src/SplPriorityQueueStasis.php source

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