圌ããã€ã³ã¿ãã¥ãŒã§é£ãã質åãããã®ã奜ããªã®ã¯ç§å¯ã§ã¯ãããŸããã åžžã«é©åã§ãããšã¯éãããçŸå®ãšåžžã«é¢é£ããŠãããšã¯éããŸããããäºå®ã¯æ®ã£ãŠããŸãã ãã¡ããã質åã¯è°è«ã®äœå°ããããæã«ã¯äžèŠãããšéŠ¬é¹¿ããŠããããã«èŠãã質åã¯ãå®éã«ããªããæžããŠããèšèªãã©ãã ãç¥ã£ãŠãããããã§ãã¯ããããšãç®çãšããŠããŸãã
ãããŠããã¡ãããé¢æ¥ã§ã®è³ªåãã©ããªã«å¥åŠã§äžæ£ç¢ºã§ãã£ãŠããããªãã¯ããã°ã©ãã³ã°ã®ããã«æ¯æãããèšèªãç¥ã£ãŠãçµå±æºåããå¿
èŠããããŸãã
äžé£ã®èšäºã®ç¬¬3éšã¯ãçŸä»£ã®PHPã§æãèšå€§ãªæŠå¿µã®1ã€ã§ããå埩ãå埩åãå埩å¯èœãšã³ãã£ãã£ã«åœãŠãããŠããŸãã PHPã®éçºè
ã®å°äœã«å¯Ÿããã€ã³ã¿ãã¥ãŒã®ããã®èªå·±æºåã«é©ããããã®åé¡ã«é¢ããç¹å®ã®æäœéã®ç¥èã1ã€ã®ããã¹ãã§åæžããããšããŸããã
åã®2ã€ã®éšåïŒ
PHPã®é
å
æåããå§ããŸãããã
PHPã«ã¯é
åããããŸãã PHPã®é
åã¯é£æ³çã§ããã€ãŸãããã¢ïŒããŒãå€ïŒãæ ŒçŽããŸããããŒã¯intãŸãã¯stringã§ããå¿
èŠããããå€ã¯ã©ã®ã¿ã€ãã§ãããŸããŸããã
äŸïŒ
$arr = ['foo' => 'bar', 'baz' => 42, 'arr' => [1, 2, 3]];
ããŒãšå€ã¯ãèšå·ã=>ãã§åºåãããŠããŸãã ããŒã¯ãã€ã³ããã¯ã¹ããšåŒã°ããããšããããŸãããPHPã§ã¯ãããã¯åçã®çšèªã§ãã
PHPã®é
åã§ã¯ãããªãå®å
šãªäžé£ã®æäœãå®çŸ©ãããŠããŸãã
é
åãæäœããããã®å€ãã®é¢æ°ããããŸã-
æ°åãæ°çŸïŒ
ãã ããããããPHPã®é
åã®æãéèŠãªããããã£ã¯ãé
åã®ãã¹ãŠã®èŠçŽ ãé çªã«åŠçãããã¹ãŠã®ããŒãšå€ã®ãã¢ãé çªã«ååŸããæ©èœã§ãã
é
åã®å埩
é
åããã©ããŒã¹ããããã»ã¹ã¯ãå埩ãïŒãŸãã¯ãç¡å¹åãïŒãšåŒã°ãïŒãšããã§ãåã¹ããããåã
ã®ããŒãšå€ã®ãã¢ãååŸããããšããå埩ãã§ãïŒããããã£ãŠé
åèªäœã¯å埩å¯èœã§ãïŒãå埩ãïŒæ¬è³ªã
å埩ããã»ã¹ã®æãåçŽãªäŸã¯ããã¡ãããforeachã¹ããŒãã¡ã³ãã«ãã£ãŠå®è£
ããããžã§ã€ã³ãã«ãŒãã§ãã
foreach ($arr as $key=>$val) { echo $key . '=>' . $val; echo "\n"; }
ã«ãŒãããããŒã®ããŒãšå€ãåºåãåãã=>ãèšå·ã«æ³šæããŠãã ããã
ããããPHPã¯ã©ã®ããã«ç解ããŸãã-ã«ãŒãã®ç¹å®ã®ã¹ãããã§é
åã®ã©ã®èŠçŽ ãåããïŒ æ¬¡ã«åãã®ã¯ã©ãã§ããïŒ ãããŠãã€åæ¢ããã®ãïŒ
ãã®è³ªåã«çããã«ã¯ãåé
åã«ååšãããããããå
éšãã€ã³ã¿ãŒãã®ååšã«æ³šæããå¿
èŠããããŸãã ãã®äžå¯èŠã®ãã€ã³ã¿ã¯ãçŸåšã®ãèŠçŽ ãæããããã«1ã¹ããã移åã§ããŸã-次ã®èŠçŽ ã«ç§»åããããæåã®èŠçŽ ã«å床ãªã»ããããŸãã
PHPã®å
éšãã€ã³ã¿ãŒãçŽæ¥æäœããã«ã¯ãäŸã䜿çšããŠæãç°¡åã«åŠç¿ã§ããé¢æ°ããããŸãã
$arr = [1, 2, 3];
äžããããã³ãŒãäŸãå®éã«ä»¥åã«äœ¿çšãããforeachã«ãŒããšåçã§ãããforeachãresetïŒïŒãkeyïŒïŒãcurrentïŒïŒãnextïŒïŒé¢æ°ã®æ§æã·ã¥ã¬ãŒã®ãããªãã®ã§ããããšã¯ç°¡åã«ããããŸãïŒãããŠendïŒïŒããã³prevïŒ ïŒ-éé ã§æ€çŽ¢ãæŽçããŸãïŒã
ãã®ã¹ããŒãã¡ã³ãã¯ãPHP 7ããåã¯çå®ã§ããããçŸåšã¯ããã§ã¯ãããŸãã-foreachã«ãŒãã¯ãresetïŒïŒãnextïŒïŒãããã³ãã®ä»ã®å埩é¢æ°ãšåãå
éšãã€ã³ã¿ãŒã䜿çšããŠåæ¢ãããããäœçœ®ã®å€æŽãåæ¢ããŸããã
å°èš
ãããã£ãŠãPHPã®é
åã®ç¹°ãè¿ããã©ã®ããã«æ©èœããããèŠçŽããã«ã¯ïŒ
- åé
åã«ã¯ãå
éšãã€ã³ã¿ãŒãé¢é£ä»ããããŠããŸãã
- é
åã®å
é ïŒãŸãã¯æ«å°ŸïŒã«ãªã»ããã§ããŸã
- 次ã®ïŒåã®ïŒèŠçŽ ã«ç§»åã§ããŸãã
- æåŸã«å°éãããã©ããã確èªã§ããŸã-ãã€ã³ã¿ãŒãé
åããåºãŠããŸããïŒ
- ãããŠãçŸåšã®èŠçŽ ã®ããŒãšå€ãååŸã§ããŸãïŒãã€ã³ã¿ãæãïŒ
ãã®ãããªããã€ã¹ã䜿çšãããšãã«ãŒãå
ã§é
åïŒèŠçŽ ãåæïŒã®ç¹°ãè¿ããæŽçã§ããŸãã ãã ããforeachã«ãŒãã¯äŒŒãŠããŸãããresetïŒïŒãkeyïŒïŒãcurrentïŒïŒãªã©ã®é¢æ°ãšåãå
éšãã€ã³ã¿ãŒã§ã¯æ©èœãããç¬èªã®ããŒã«ã«ã«ãŒãã§æ©èœããããšãç解ããããšãéèŠã§ãããµã€ã¯ã«ã®ããã«ã
ãªããžã§ã¯ããå埩åŠçãã
é
åã®ãããªãªããžã§ã¯ãã¯ãå埩å¯èœãªãšã³ãã£ãã£ã§ãã ãªããžã§ã¯ãã¯ããã®ã³ã³ããã¹ãã§è¡šç€ºãããããããã£ã«ãã£ãŠã¯ããŒã«ãããããããã£åã¯ããŒãšããŠæ©èœããŸãã
class Foo { public $first = 1; public $second = 2; protected $third = 3; public function iterate() { foreach ($this as $key => $value) { echo $key . '=>' . $value; echo "\n"; } } } $foo = new Foo; foreach ($foo as $key => $value) { echo $key . '=>' . $value; echo "\n"; } $foo->iterate();
ãã ãããã®ãããªå埩ã¯ããã®ç®ã«èŠããç¹æ§ã«åŸã£ãŠãå€ãã®å Žåå®å
šã«åœ¹ã«ç«ããªãã æãäžè¬çãªäŸã¯ãå
éšã®å®å
šãªã¹ãã¢ã«å€ã®ã»ãããæ ŒçŽãããªããžã§ã¯ãã§ãã ããšãã°ã次ã®ããã«ïŒ
class Storage { protected $storage = []; public function set($key, $val) { $this->storage[$key] = $val; } public function get($key) { return $this->storage[$key]; } }
ãããªãã¯ããããã£ãæããªããã®ãããªãªããžã§ã¯ãã®å埩ãæŽçããæ¹æ³ã¯ïŒ ãããŠãããçš®ã®ã«ã¹ã¿ã éæšæºã¢ã«ãŽãªãºã ã䜿çšããŠäžè¬çã«å埩ãæŽçããæ¹æ³ã¯ïŒ
ã€ãã¬ãŒã¿ã€ã³ã¿ãŒãã§ã€ã¹
ç¬èªã®å埩ã¢ã«ãŽãªãºã ãå®è£
ããããã«ãPHPïŒãŸãã¯SPLïŒã¯ã5ã€ã®ã¡ãœããã§æ§æãããç¹å¥ãªIteratorã€ã³ã¿ãŒãã§ãŒã¹ãæäŸããŸãã
ã¯ã©ã¹ã¯ãããã®ã¡ãœãããå®è£
ããå¿
èŠããããå®è£
ãããã¢ã«ãŽãªãºã ã«åŸã£ãŠforeachã«ãŒãã䜿çšããŠãã®ã¯ã©ã¹ã®ãªããžã§ã¯ããå埩ããæ©äŒãåŸãããŸãã
ããã§ã€ãã¬ãŒã¿ã€ã³ã¿ãŒãã§ã€ã¹ã¡ãœããã®èª¬æã§èšåãããŠããNB "ãã€ã³ã¿"ã¯ãå®éã«ååšããé
åã®å
éšãã€ã³ã¿ãšã¯å¯Ÿç
§çã«ãçŽç²ãªæœè±¡åã§ãã ãã®æœè±¡åã®å®è£
æ¹æ³ã¯ãŠãŒã¶ãŒã«ãã£ãŠç°ãªããŸããçµæã®ã¿ãéèŠã§ããããšãã°ãrewindïŒïŒããã³currentïŒïŒã¡ãœããã®é£ç¶åŒã³åºãã¯ãæåã®èŠçŽ ã®å€ãè¿ãå¿
èŠããããŸãã
Iteratorã€ã³ã¿ãŒãã§ãŒã¹ãå®è£
ããæãç°¡åãªäŸ class Example implements Iterator { protected $storage = []; public function set($key, $val) { $this->storage[$key] = $val; } public function get($key) { return $this->storage[$key]; } public function current() { return current($this->storage); } public function key() { return key($this->storage); } public function next(): void { next($this->storage); } public function rewind(): void { reset($this->storage); } public function valid(): bool { return null !== key($this->storage); } } $test = new Example; $test->set('foo', 'bar'); $test->set('baz', 42); foreach ($test as $key => $val) { echo $key . '=>' . $val; echo "\n"; }
Traversableããã³IteratorAggregate
å³å¯ã«èšãã°ãTraversableã€ã³ã¿ãŒãã§ã€ã¹ã䜿çšãããšãforeachã䜿çšããŠå埩åŠçãè¡ãããšãã§ããIteratorããã®åŸç¶ã§ãã Traversableã®æ©èœã¯ãçŽæ¥å®è£
ã§ããªãïŒäžçš®ã®ãæœè±¡ã€ã³ã¿ãŒãã§ãŒã¹ãïŒãããã¢ããªã±ãŒã·ã§ã³ã§Iteratorã€ã³ã¿ãŒãã§ãŒã¹ãŸãã¯ãã®ãåŒãIteratorAggregateã䜿çšããå¿
èŠããããŸãã 圌ã«ã€ããŠè©±ããŸãããã
SPLã«ã¯ãã€ãã¬ãŒã¿ãŒãªããžã§ã¯ãã§ä»ã®ãšã³ãã£ãã£ïŒé
åãªã©ïŒãã©ããã§ããããã€ãã®çµã¿èŸŒã¿ã€ãã¬ãŒã¿ãŒã¯ã©ã¹ãå«ãŸããŠããŸãã
$iterator = new ArrayIterator([1, 2, 3]); foreach ($iterator as $key => $val) {
ãã®ãããªæ¢è£œã®ã€ãã¬ãŒã¿ã©ãããŒã®ãªã¹ãã¯éåžžã«å€§ãããDirectoryIteratorïŒæå®ããããã£ã¬ã¯ããªå
ã®ãã¡ã€ã«ã®ãªã¹ããå埩åŠçïŒãRecursiveArrayIteratorïŒãã¹ããããé
åã®ååž°çãã©ããŒã¹ïŒãFilterIteratorïŒäžèŠãªå€ã®æåŠã«ãããã©ããŒã¹ïŒãããã³ãã®ä»ã®å€æ°ã®æçšãªã¯ã©ã¹ãå«ãŸã
ãŸã ã
æ¢è£œã®ã€ãã¬ãŒã¿ãŒãšIteratorAggregateã€ã³ã¿ãŒãã§ãŒã¹ã䜿çšãããšãç¬èªã®ã€ãã¬ãŒã¿ãŒã¯ã©ã¹ã®äœæã倧å¹
ã«ç°¡çŽ åã§ããŸãã ãããã£ãŠãäžèšã®ãã¿ãã¬ã®äžã«ããéåžžã«é·ãã¯ã©ã¹ã¯ã次ã®ãããªãã®ã«æžããããšãã§ããŸãã
class Example implements IteratorAggregate { protected $storage = []; public function set($key, $val) { $this->storage[$key] = $val; } public function get($key) { return $this->storage[$key]; } public function getIterator(): Traversable { return new ArrayIterator($this->storage); } }
-çµæã¯ãIteratorã€ã³ã¿ãŒãã§ãŒã¹ã®å®è£
ãšåãã«ãªããŸãã
ãžã§ãã¬ãŒã¿ãŒã¯ã©ãã§ããïŒ
ãã¡ããã§ãã foreachã§ãããã䜿çšããŸãïŒ
class Generator implements Iterator
ãã ãããžã§ãã¬ãŒã¿ãŒã¯å¥ã®èšäºã®ãããã¯ã§ãã ãããŸã§ã®éããžã§ãã¬ãŒã¿ãŒã®ã¡ã«ããºã ã«éæ³ã¯äœããªããšèšãã ãã§ååã§ããåãIteratorã€ã³ã¿ãŒãã§ãŒã¹ãå埩ã«äœ¿çšãããŸãã 1ã€ã®ãbutããé€ããŠãå埩ãæ¢ã«éå§ãããŠããå Žåããžã§ãã¬ãŒã¿ãŒããæåã«å·»ãæ»ããããšã¯ã§ããŸãããrewindïŒïŒã¡ãœãããåŒã³åºããšäŸå€ãã¹ããŒãããŸãã
å埩å¯èœã¿ã€ã
PHP 7.1ããåã«ã¯ãå¥åŠãªç¶æ³ããããŸããã äžæ¹ã«ã¯ãIteratorãŸãã¯IteratorAggregateãä»ããŠTraversableãå®è£
ããå埩å¯èœãªãªããžã§ã¯ãããããŸããã åãã¡ã«ããºã ã䜿çšããã®ãšåãåŽã«ãžã§ãã¬ãŒã¿ãŒããããŸããã ãŸããå察åŽã«ã¯é
åãããããªããžã§ã¯ãã®å¯èŠããããã£ã«å¯Ÿããããã€ãã£ããå埩ããããŸãã å®éãåãåäœããããå
±éç¹ã®ãªã2çš®é¡ã®å埩å¯èœãªãšã³ãã£ãã£ããããŸããã
7.1ã§ã¯ãæçµçã«ãã®äžæŽåã解æ¶ãããå¥ã®ãç䌌åãïŒãŸãã¯ãããã«ã¹ã¿ã åïŒããå埩å¯èœãã«ãªããŸããã
PHPã§typeæŒç®åã衚瀺ãããã®ããã€ãåŸ
ã€ãšãiterableã®å®çŸ©ã¯æ¬¡ã®ããã«èšè¿°ã§ããŸãã
type iterable = array | Traversable;
ãã®åã¯ãé
åãšãã¹ãŠã®Traversableåå«ãçµã¿åãããforeachã䜿çšããŠå埩ã§ããå€ã®åã瀺ããŸãã
function doSomething(iterable $it) { foreach ($it as $key=>$val) {
ãããŠãããã¯äœã§ããïŒ
ãã®ã¿ã€ããã£ãŒãã¯æ¬¡ã®ãšããã§ãã
iterable ---> array --> Traversable ---> Iterator --> IteratorAggregate --> Generator
衚瀺å¯èœãªããããã£ã«å¿ããŠãã€ãã£ããªå埩ãèš±å¯ãããªããžã§ã¯ãïŒããªããžã§ã¯ãã ããã¿ã€ãïŒã¯ãå埩å¯èœãªã¿ã€ãã«ãŸã å«ãŸããŠããªãããšã«æ³šæããŠãã ããã ãããããã®ãããªãªããžã§ã¯ããå埩åŠçããããšã®å®çšçãªäŸ¡å€ã¯ããã»ã©å€§ãããªããããåæºããçç±ã¯ãããŸãã...
ä»ã«èªããã®ã¯äœã§ããïŒ
ã€ã³ã¿ãã¥ãŒãšè·å Žã§ã®æåïŒ