1--TEST-- 2SPL: SplObjectStorage 3--FILE-- 4<?php 5 6class MyObjectStorage extends SplObjectStorage 7{ 8 function rewind(): void 9 { 10 echo __METHOD__ . "()\n"; 11 parent::rewind(); 12 } 13 14 function valid(): bool 15 { 16 echo __METHOD__ . "(" . (parent::valid() ? 1 : 0) . ")\n"; 17 return parent::valid(); 18 } 19 20 function key(): int 21 { 22 echo __METHOD__ . "(" . parent::key() . ")\n"; 23 return parent::key(); 24 } 25 26 function current(): object 27 { 28 echo __METHOD__ . "(" . parent::current()->getName() . ")\n"; 29 return parent::current(); 30 } 31 32 function next(): void 33 { 34 echo __METHOD__ . "()\n"; 35 parent::next(); 36 } 37} 38 39class ObserverImpl implements SplObserver 40{ 41 protected $name = ''; 42 43 function __construct($name = 'obj') 44 { 45 $this->name = '$' . $name; 46 } 47 48 function update(SplSubject $subject): void 49 { 50 echo $this->name . '->' . __METHOD__ . '(' . $subject->getName() . ");\n"; 51 } 52 53 function getName() 54 { 55 return $this->name; 56 } 57} 58 59class SubjectImpl implements SplSubject 60{ 61 protected $name = ''; 62 protected $observers; 63 64 function __construct($name = 'sub') 65 { 66 $this->observers = new MyObjectStorage; 67 $this->name = '$' . $name; 68 } 69 70 function attach(SplObserver $observer): void 71 { 72 echo $this->name . '->' . __METHOD__ . '(' . $observer->getName() . ");\n"; 73 $this->observers->attach($observer); 74 } 75 76 function detach(SplObserver $observer): void 77 { 78 echo $this->name . '->' . __METHOD__ . '(' . $observer->getName() . ");\n"; 79 $this->observers->detach($observer); 80 } 81 82 function count(): int 83 { 84 return $this->observers->count(); 85 } 86 87 function notify(): void 88 { 89 echo $this->name . '->' . __METHOD__ . "();\n"; 90 foreach($this->observers as $key => $observer) 91 { 92 $observer->update($this); 93 } 94 } 95 96 function getName() 97 { 98 return $this->name; 99 } 100 101 function contains($obj) 102 { 103 return $this->observers->contains($obj); 104 } 105} 106 107$sub = new SubjectImpl; 108 109$ob1 = new ObserverImpl("ob1"); 110$ob2 = new ObserverImpl("ob2"); 111$ob3 = new ObserverImpl("ob3"); 112 113var_dump($sub->contains($ob1)); 114$sub->attach($ob1); 115var_dump($sub->contains($ob1)); 116$sub->attach($ob1); 117$sub->attach($ob2); 118$sub->attach($ob3); 119var_dump($sub->count()); 120 121$sub->notify(); 122 123$sub->detach($ob3); 124var_dump($sub->count()); 125 126$sub->notify(); 127 128$sub->detach($ob2); 129$sub->detach($ob1); 130var_dump($sub->count()); 131 132$sub->notify(); 133 134$sub->attach($ob3); 135var_dump($sub->count()); 136 137$sub->notify(); 138 139?> 140--EXPECT-- 141bool(false) 142$sub->SubjectImpl::attach($ob1); 143bool(true) 144$sub->SubjectImpl::attach($ob1); 145$sub->SubjectImpl::attach($ob2); 146$sub->SubjectImpl::attach($ob3); 147int(3) 148$sub->SubjectImpl::notify(); 149MyObjectStorage::rewind() 150MyObjectStorage::valid(1) 151MyObjectStorage::current($ob1) 152MyObjectStorage::key(0) 153$ob1->ObserverImpl::update($sub); 154MyObjectStorage::next() 155MyObjectStorage::valid(1) 156MyObjectStorage::current($ob2) 157MyObjectStorage::key(1) 158$ob2->ObserverImpl::update($sub); 159MyObjectStorage::next() 160MyObjectStorage::valid(1) 161MyObjectStorage::current($ob3) 162MyObjectStorage::key(2) 163$ob3->ObserverImpl::update($sub); 164MyObjectStorage::next() 165MyObjectStorage::valid(0) 166$sub->SubjectImpl::detach($ob3); 167int(2) 168$sub->SubjectImpl::notify(); 169MyObjectStorage::rewind() 170MyObjectStorage::valid(1) 171MyObjectStorage::current($ob1) 172MyObjectStorage::key(0) 173$ob1->ObserverImpl::update($sub); 174MyObjectStorage::next() 175MyObjectStorage::valid(1) 176MyObjectStorage::current($ob2) 177MyObjectStorage::key(1) 178$ob2->ObserverImpl::update($sub); 179MyObjectStorage::next() 180MyObjectStorage::valid(0) 181$sub->SubjectImpl::detach($ob2); 182$sub->SubjectImpl::detach($ob1); 183int(0) 184$sub->SubjectImpl::notify(); 185MyObjectStorage::rewind() 186MyObjectStorage::valid(0) 187$sub->SubjectImpl::attach($ob3); 188int(1) 189$sub->SubjectImpl::notify(); 190MyObjectStorage::rewind() 191MyObjectStorage::valid(1) 192MyObjectStorage::current($ob3) 193MyObjectStorage::key(0) 194$ob3->ObserverImpl::update($sub); 195MyObjectStorage::next() 196MyObjectStorage::valid(0) 197