src/SplHeapStasis.php source

1 <?php
2
3 declare(strict_types=1);
4
5 namespace Serializor;
6
7 use SplHeap;
8 use SplMaxHeap;
9 use SplMinHeap;
10
11 /**
12 * Stasis for SplHeap subclasses (SplMaxHeap, SplMinHeap).
13 * PHP <8.5 doesn't have __serialize() for these classes.
14 */
15 final class SplHeapStasis extends Stasis
16 {
17 /**
18 * The heap class name.
19 * @var class-string<SplHeap>
20 */
21 private string $c;
22
23 /**
24 * The heap items (extracted via iteration).
25 * @var array<int, mixed>
26 */
27 public array $items = [];
28
29 /**
30 * @param class-string<SplHeap> $className
31 */
32 public function __construct(string $className)
33 {
34 $this->c = $className;
35 }
36
37 public function __serialize(): array
38 {
39 return [$this->c, $this->items];
40 }
41
42 public function __unserialize(array $data): void
43 {
44 [$this->c, $this->items] = $data;
45 }
46
47 public function getClassName(): string
48 {
49 return $this->c;
50 }
51
52 /**
53 * Get reference to items for Codec child transformation.
54 */
55 public function &getItems(): array
56 {
57 return $this->items;
58 }
59
60 public static function fromHeap(SplHeap $heap): SplHeapStasis
61 {
62 $className = \get_class($heap);
63 $frozen = new SplHeapStasis($className);
64
65 // Clone to avoid destructive iteration on original
66 $copy = clone $heap;
67 foreach ($copy as $item) {
68 $frozen->items[] = $item;
69 }
70
71 return $frozen;
72 }
73
74 public function &getInstance(): mixed
75 {
76 if ($this->hasInstance()) {
77 return $this->getCachedInstance();
78 }
79
80 $rc = new \ReflectionClass($this->c);
81 /** @var SplHeap $heap */
82 $heap = $rc->newInstance();
83
84 // Re-insert all items
85 foreach ($this->items as $item) {
86 $heap->insert($item);
87 }
88
89 $this->setInstance($heap);
90 return $heap;
91 }
92 }
93