Save 37% off PRO during our Black Friday Sale! »

Iterators in PHP

E4df4a30f000a225df7114e4940944e7?s=47 jakefolio
February 08, 2014

Iterators in PHP

PHP iterators have been around since PHP 5, but are heavily under utilized. With all the built-in iterators there is no reason you shouldn't be leveraging it's power and flexibility. In this session you will learn about all the built-in PHP iterators and be guided on how to extend and/or create your own iterators.

E4df4a30f000a225df7114e4940944e7?s=128

jakefolio

February 08, 2014
Tweet

Transcript

  1. Iterators IN PHP NOW WITH GENERATORS

  2. http://bitly.com/wNwg6N

  3. An iterator is an object that enables a programmer to

    traverse a container. Various types of iterators are often provided via a container's interface. Source: http://en.wikipedia.org/wiki/Iterator
  4. PHP also have a lot of awesome features; at least

    two of them are in my opinion largely underused: Iterators and Streams. “ ” Fabien Potencier (Lead Developer of Symfony Project) Source: http://fabien.potencier.org/article/44/php-iterators-and-streams-are-awesome
  5. One Iterator Two Iterator Three Iterator floor();

  6. Where are Iterators Used?

  7. Iterators in Source https://github.com/php/php-src/tree/master/ext/spl

  8. Everyone Loves Iterators

  9. Everyone Loves Iterators Have you used SimpleXML?

  10. Everyone Loves Iterators Have you used SimpleXML? Have you used

    pdo?
  11. class IterableFilterIterator extends FilterIterator { public function accept() { return

    in_array("Iterator", class_implements($this->current())); } } $classes = new IterableFilterIterator(new ArrayIterator(get_declared_classes())); foreach ($classes as $name) { echo $name . "\n"; } Classes that implement Iterator
  12. class IterableFilterIterator extends FilterIterator { public function accept() { return

    in_array("Iterator", class_implements($this->current())); } } $classes = new IterableFilterIterator(new ArrayIterator(get_declared_classes())); foreach ($classes as $name) { echo $name . "\n"; } Classes that implement Iterator Generator RecursiveIteratorIterator IteratorIterator FilterIterator RecursiveFilterIterator CallbackFilterIterator RecursiveCallbackFilterIterator ParentIterator LimitIterator CachingIterator RecursiveCachingIterator NoRewindIterator AppendIterator InfiniteIterator RegexIterator RecursiveRegexIterator EmptyIterator RecursiveTreeIterator ArrayIterator RecursiveArrayIterator DirectoryIterator FilesystemIterator RecursiveDirectoryIterator GlobIterator SplFileObject SplTempFileObject SplDoublyLinkedList SplQueue SplStack SplHeap SplMinHeap SplMaxHeap SplPriorityQueue SplFixedArray SplObjectStorage MultipleIterator IntlIterator IntlPartsIterator Phar PharData SimpleXMLIterator MongoCursor
  13. Defining an Iterator

  14. Iterator Interfaces

  15. Iterator Interfaces • Traversable • Iterator • RecursiveIterator • Countable

    • SeekableIterator Source: http://www.php.net/manual/en/spl.iterators.php
  16. Interface - Iterator Source: http://us.php.net/manual/en/class.iterator.php Iterator extends Traversable { /*

    Methods */ abstract public mixed current ( void ) abstract public scalar key ( void ) abstract public void next ( void ) abstract public void rewind ( void ) abstract public boolean valid ( void ) }
  17. Interface - RecursiveIterator Source: http://www.php.net/manual/en/spl.iterators.php RecursiveIterator extends Iterator { /*

    Methods */ public RecursiveIterator getChildren ( void ) public bool hasChildren ( void ) /* Inherited methods */ abstract public mixed Iterator::current ( void ) abstract public scalar Iterator::key ( void ) abstract public void Iterator::next ( void ) abstract public void Iterator::rewind ( void ) abstract public boolean Iterator::valid ( void ) }
  18. Interface - Countable Source: http://www.php.net/manual/en/spl.iterators.php Countable { /* Methods */

    abstract public int count ( void ) }
  19. Interface - Seekable Source: http://www.php.net/manual/en/spl.iterators.php SeekableIterator extends Iterator { /*

    Methods */ abstract public void seek ( int $position ) /* Inherited methods */ abstract public mixed Iterator::current ( void ) abstract public scalar Iterator::key ( void ) abstract public void Iterator::next ( void ) abstract public void Iterator::rewind ( void ) abstract public boolean Iterator::valid ( void ) }
  20. Iterator Basics

  21. Iterator Aggregate Iterator Aggregate is used when you need to

    offload iteration, and its methods, to another iterator public function getIterator() { ... }
  22. Iterator Aggregate Iterator Aggregate Iterator

  23. Outer Iterator Outer Iterators act as a wrapper layer. Outer

    iterator is iterated and then internally iterates over inner iterator. * * * ITERATOR!
  24. Outer Iterator Outer Iterator Inner Iterator

  25. Outer Iterator Outer Iterator Inner Iterator

  26. Recursive Iterator Recursive Iterators prepare an iterator to be recursively

    iterated. * Requires RecursiveIteratorIterator to properly recursively Iterate. *
  27. Recursive Iterator Recursive Iterator Get Children

  28. Iterator Notes If you use foreach it will auto rewind.

    Using for or while will require you to rewind iterator.
  29. Recursive Iterators

  30. $data = [ 'title' => 'how to work with iterators',

    'posts' => [ [ 'title' => 'introduction to iterators', 'email' => 'JohnDoe@example.com', ], [ 'title' => 'extending iterators', 'email' => 'JaneDoe@example.com', ], ], ]; foreach (new RecursiveArrayIterator($data) as $field => $val) { echo "{$field}:{$val}\n"; } Sub Title Recursive*Iterator Recursively Iterate Array
  31. $data = [ 'title' => 'how to work with iterators',

    'posts' => [ [ 'title' => 'introduction to iterators', 'email' => 'JohnDoe@example.com', ], [ 'title' => 'extending iterators', 'email' => 'JaneDoe@example.com', ], ], ]; foreach (new RecursiveArrayIterator($data) as $field => $val) { echo "{$field}:{$val}\n"; } Sub Title Recursive*Iterator Recursively Iterate Array title: how to work with iterators posts: Array
  32. $data = [ 'title' => 'how to work with iterators',

    'posts' => [ [ 'title' => 'introduction to iterators', 'email' => 'JohnDoe@example.com', ], [ 'title' => 'extending iterators', 'email' => 'JaneDoe@example.com', ], ], ]; foreach (new RecursiveArrayIterator($data) as $field => $val) { echo "{$field}:{$val}\n"; } Sub Title Recursive*Iterator Recursively Iterate Array title: how to work with iterators posts: Array
  33. None
  34. RecursiveIteratorIterator implements OuterIterator , Traversable , Iterator { /* Constants

    */ const integer LEAVES_ONLY = 0 ; const integer SELF_FIRST = 1 ; const integer CHILD_FIRST = 2 ; const integer CATCH_GET_CHILD = 16 ; }
  35. $data = [ 'title' => 'how to work with iterators',

    'posts' => [ [ 'title' => 'introduction to iterators', 'email' => 'JohnDoe@example.com', ], [ 'title' => 'extending iterators', 'email' => 'JaneDoe@example.com', ], ], ]; $it = new RecursiveIteratorIterator( new RecursiveArrayIterator($data) ); foreach($it as $field => $val) { echo "{$field}:{$val}\n"; } Sub Title Recursive*Iterator Recursively Iterate Array
  36. $data = [ 'title' => 'how to work with iterators',

    'posts' => [ [ 'title' => 'introduction to iterators', 'email' => 'JohnDoe@example.com', ], [ 'title' => 'extending iterators', 'email' => 'JaneDoe@example.com', ], ], ]; $it = new RecursiveIteratorIterator( new RecursiveArrayIterator($data) ); foreach($it as $field => $val) { echo "{$field}:{$val}\n"; } Sub Title Recursive*Iterator Recursively Iterate Array title: how to work with iterators title: introduction to iterators email: JohnDoe@example.com title: extending iterators email: JaneDoe@example.com
  37. $it = new RecursiveArrayIterator([ 'Home', 'About' => ['Careers', 'Contact'], 'Location',

    'FAQ', ]); Sub Title RecursiveNavigationIterator Hooks Output multi-dimensional array as UL/LI
  38. class RecursiveNavigationIterator extends RecursiveIteratorIterator { public $openTag = "<ul>"; public

    $closeTag = "</ul>"; public function beginIteration() { echo $this->openTag . PHP_EOL; } public function endIteration() { echo $this->closeTag . PHP_EOL; } public function beginChildren() { echo $this->openTag . PHP_EOL; } public function endChildren() { echo $this->closeTag . PHP_EOL; } } Sub Title RecursiveNavigationIterator Hooks Output multi-dimensional array as UL/LI
  39. $it = new RecursiveArrayIterator([ 'Home', 'About' => ['Careers', 'Contact'], 'Location',

    'FAQ', ]); $navIt = new RecursiveNavigationIterator($it, RecursiveIteratorIterator::SELF_FIRST); foreach ($navIt as $navItem) { echo "<li>{$navItem}</li>" . PHP_EOL; } Sub Title RecursiveNavigationIterator Hooks Output multi-dimensional array as UL/LI
  40. $it = new RecursiveArrayIterator([ 'Home', 'About' => ['Careers', 'Contact'], 'Location',

    'FAQ', ]); $navIt = new RecursiveNavigationIterator($it, RecursiveIteratorIterator::SELF_FIRST); foreach ($navIt as $navItem) { echo "<li>{$navItem}</li>" . PHP_EOL; } Sub Title RecursiveNavigationIterator Hooks Output multi-dimensional array as UL/LI <ul> <li>Home</li> <li>About</li> <ul> <li>Careers</li> <li>Contact</li> </ul> <li>Location</li> <li>FAQ</li> </ul>
  41. Problem: Source: http://www.php.net/manual/en/spl.iterators.php I have a cache folder, but it

    goes many folders deep.
  42. $it = new RecursiveIteratorIterator( new RecursiveDirectoryIterator('cache', FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST ); function

    clearCache(Iterator $it) { // Check if directory if ($it->current()->isDir()) { rmdir($it->key()); return true; } return unlink($it->key()); } iterator_apply($it, 'clearCache', [$it]); Sub Title iterator_apply Clear all files/folders in cache folder
  43. Directory Iterator

  44. $it = new DirectoryIterator('vendor'); foreach ($it as $file) { echo

    $file->getFilename() . PHP_EOL; } Sub Title DirectoryIterator Source: Output directory content for Composer vendors http://us.php.net/manual/en/class.directoryiterator.php SplFileInfo
  45. $it = new DirectoryIterator('vendor'); foreach ($it as $file) { echo

    $file->getFilename() . PHP_EOL; } Sub Title DirectoryIterator Source: Output directory content for Composer vendors http://us.php.net/manual/en/class.directoryiterator.php SplFileInfo . .. aura autoload.php bin composer monolog psr robmorgan slim slimcontroller symfony vlucas
  46. Directory Iterator Note If you attempt to access a file

    that you do not have permission to. You will receive a UnexpectedValueException.
  47. Filesystem Iterator

  48. FilesystemIterator extends DirectoryIterator implements SeekableIterator , Traversable , Iterator {

    /* Constants */ const integer CURRENT_AS_PATHNAME = 32 ; const integer CURRENT_AS_FILEINFO = 0 ; const integer CURRENT_AS_SELF = 16 ; const integer CURRENT_MODE_MASK = 240 ; const integer KEY_AS_PATHNAME = 0 ; const integer KEY_AS_FILENAME = 256 ; const integer FOLLOW_SYMLINKS = 512 ; const integer KEY_MODE_MASK = 3840 ; const integer NEW_CURRENT_AND_KEY = 256 ; const integer SKIP_DOTS = 4096 ; const integer UNIX_PATHS = 8192 ; // Default Flags FilesystemIterator::KEY_AS_PATHNAME FilesystemIterator::CURRENT_AS_FILEINFO FilesystemIterator::SKIP_DOTS Sub Title FileSystemIterator (PHP 5.3.x) FileSystemIterator Constants/Flags
  49. Glob Iterator

  50. $it = new GlobIterator('vendor/*/*.php'); foreach ($it as $path => $file)

    { echo $path . " - " . $file->getFilename() . PHP_EOL; } Sub Title GlobIterator Source: Output directory content for Composer vendors http://us.php.net/manual/en/class.globiterator.php
  51. $it = new GlobIterator('vendor/*/*.php'); foreach ($it as $path => $file)

    { echo $path . " - " . $file->getFilename() . PHP_EOL; } Sub Title GlobIterator Source: Output directory content for Composer vendors http://us.php.net/manual/en/class.globiterator.php vendor/composer/ClassLoader.php - ClassLoader.php vendor/composer/autoload_classmap.php - autoload_classmap.php vendor/composer/autoload_namespaces.php - autoload_namespaces.php vendor/composer/autoload_psr4.php - autoload_psr4.php vendor/composer/autoload_real.php - autoload_real.php
  52. $it = new RecursiveDirectoryIterator('vendor'); foreach (new RecursiveTreeIterator($it) as $file) {

    echo $file . PHP_EOL; } Sub Title RecursiveTreeIterator Source: Output ASCII view of Directory Structure http://us.php.net/manual/en/class.recursivetreeiterator.php
  53. $it = new RecursiveDirectoryIterator('vendor'); foreach (new RecursiveTreeIterator($it) as $file) {

    echo $file . PHP_EOL; } Sub Title RecursiveTreeIterator Source: Output ASCII view of Directory Structure http://us.php.net/manual/en/class.recursivetreeiterator.php \-vendor/vlucas |-vendor/vlucas/. |-vendor/vlucas/.. \-vendor/vlucas/phpdotenv |-vendor/vlucas/phpdotenv/. |-vendor/vlucas/phpdotenv/.. |-vendor/vlucas/phpdotenv/.git | |-vendor/vlucas/phpdotenv/.git/. | |-vendor/vlucas/phpdotenv/.git/.. | |-vendor/vlucas/phpdotenv/.git/FETCH_HEAD | |-vendor/vlucas/phpdotenv/.git/HEAD | |-vendor/vlucas/phpdotenv/.git/ORIG_HEAD | |-vendor/vlucas/phpdotenv/.git/branches | | |-vendor/vlucas/phpdotenv/.git/branches/. | | \-vendor/vlucas/phpdotenv/.git/branches/.. | |-vendor/vlucas/phpdotenv/.git/config | |-vendor/vlucas/phpdotenv/.git/description
  54. Filter Iterator

  55. Source: http://www.php.net/manual/en/spl.iterators.php Need to view all files in a directory,

    but it keeps returning Version Control folders (.svn and .git). Problem:
  56. class NoVCSIterator extends FilterIterator { public function accept() { $vcsFolders

    = array(".git", ".svn"); $file = $this->current(); if ($file->isDir() && (in_array($vcsFolders, $file->getFilename())) { return false; } return true; } } Sub Title FilterIterator Do not show Version Control folders
  57. Source: http://www.php.net/manual/en/spl.iterators.php I need to see all images that are

    over 5MB that have been uploaded. Problem:
  58. class LargeFileFilterIterator extends FilterIterator { public function accept() { $file

    = $this->current(); if ($file->getSize() > $this->fileSizeMin) { return true; } return false; } } class ImageFilterIterator extends FilterIterator { public function accept() { $file = $this->current(); if (in_array($file->getExtension(), $this->imageWhiteList)) { return true; } return false; } } Sub Title FilterIterator Only show images greater than 5MB
  59. $dir = new FileSystemIterator(UPLOADS_PATH); $filterIt = new LargeFileFilterIterator( new ImageFilterIterator($dir,

    ['jpg']) ); foreach($filterIt as $file) { echo $file->getFileName() . PHP_EOL; } Sub Title FilterIterator Only show images greater than 5MB
  60. $dir = new FileSystemIterator(UPLOADS_PATH); $filterIt = new LargeFileFilterIterator( new ImageFilterIterator($dir,

    ['jpg']) ); echo count($filterIt); // 1 echo iterator_count($filterIt); // 2 foreach($filterIt as $file) { echo $file->getFileName() . PHP_EOL; } Sub Title iterator_count Countable with Filters
  61. Regex Iterator

  62. /* Constants */ const integer RegexIterator->MATCH = 0 ; const

    integer GET_MATCH = 1 ; const integer ALL_MATCHES = 2 ; const integer SPLIT = 3 ; const integer REPLACE = 4 ; const integer USE_KEY = 1 ; $it = new RecursiveDirectoryIterator( 'vendor', RecursiveDirectoryIterator::SKIP_DOTS ); $regexIt = new RecursiveRegexIterator( $it, '/^.*\.(php|env|json|yml)$/', RegexIterator::ALL_MATCHES ); foreach (new RecursiveIteratorIterator($regexIt) as $path => $file) { echo $path . PHP_EOL; } Sub Title RegexIterator Source: Match specific file types with RecursiveDirectoryIterator http://us3.php.net/manual/en/class.regexiterator.php
  63. /* Constants */ const integer RegexIterator->MATCH = 0 ; const

    integer GET_MATCH = 1 ; const integer ALL_MATCHES = 2 ; const integer SPLIT = 3 ; const integer REPLACE = 4 ; const integer USE_KEY = 1 ; $it = new RecursiveDirectoryIterator( 'vendor', RecursiveDirectoryIterator::SKIP_DOTS ); $regexIt = new RecursiveRegexIterator( $it, '/^.*\.(php|env|json|yml)$/', RegexIterator::ALL_MATCHES ); foreach (new RecursiveIteratorIterator($regexIt) as $path => $file) { echo $path . PHP_EOL; } Sub Title RegexIterator Source: Match specific file types with RecursiveDirectoryIterator http://us3.php.net/manual/en/class.regexiterator.php vendor/autoload.php vendor/composer/ClassLoader.php vendor/composer/autoload_classmap.php vendor/composer/autoload_namespaces.php vendor/composer/autoload_psr4.php vendor/composer/autoload_real.php vendor/composer/installed.json
  64. Parent Iterator

  65. Source: http://www.php.net/manual/en/spl.iterators.php Parent Iterator is a FilterIterator that only accepts

    elements that have children. Hence the name ParentIterator Parent Iterator
  66. Limit Iterator

  67. Source: http://www.php.net/manual/en/spl.iterators.php Currently have a CSV with a lot of

    lines, but I need to paginate with 3 results per page. Problem:
  68. $usersCSV = <<<CSV "jsmith", "Jake", "Smith", "jake.smith92@gmail.com" "saustin", "Steve", "Austin",

    "moneyman@gmail.com" "srogers", "Steven", "Rogers", "thecapt@gmail.com" "ballen", "Barry", "Allen", "ballen@flash.net" "bbanner", "Bruce", "Banner", "smashallthethings@gmail.com" CSV; $csv = new SplTempFileObject(); $csv->fwrite($usersCSV); $csv->setFlags(SplFileObject::READ_CSV); $it = new LimitIterator($csv, 0, 3); foreach ($it as list($username, $firstName, $lastName, $email)) { echo "{$firstName} {$lastName}" . PHP_EOL; } Sub Title LimitIterator Limit CSV output to first 3
  69. $usersCSV = <<<CSV "jsmith", "Jake", "Smith", "jake.smith92@gmail.com" "saustin", "Steve", "Austin",

    "moneyman@gmail.com" "srogers", "Steven", "Rogers", "thecapt@gmail.com" "ballen", "Barry", "Allen", "ballen@flash.net" "bbanner", "Bruce", "Banner", "smashallthethings@gmail.com" CSV; $csv = new SplTempFileObject(); $csv->fwrite($usersCSV); $csv->setFlags(SplFileObject::READ_CSV); $it = new LimitIterator($csv, 0, 3); foreach ($it as list($username, $firstName, $lastName, $email)) { echo "{$firstName} {$lastName}" . PHP_EOL; } Sub Title LimitIterator Limit CSV output to first 3 Jake Smith Steve Austin Steven Rogers
  70. $usersCSV = <<<CSV "jsmith", "Jake", "Smith", "jake.smith92@gmail.com" "saustin", "Steve", "Austin",

    "moneyman@gmail.com" "srogers", "Steven", "Rogers", "thecapt@gmail.com" "ballen", "Barry", "Allen", "ballen@flash.net" "bbanner", "Bruce", "Banner", "smashallthethings@gmail.com" CSV; $csv = new SplTempFileObject(); $csv->fwrite($usersCSV); $csv->setFlags(SplFileObject::READ_CSV); $it = new LimitIterator($csv, 0, 3); try { $it->seek(20); } catch (OutOfBoundsException $e) { echo "Error: " . $e->getMessage() . PHP_EOL; } Sub Title LimitIterator Throw Exception if seeking beyond total number of elements
  71. $usersCSV = <<<CSV "jsmith", "Jake", "Smith", "jake.smith92@gmail.com" "saustin", "Steve", "Austin",

    "moneyman@gmail.com" "srogers", "Steven", "Rogers", "thecapt@gmail.com" "ballen", "Barry", "Allen", "ballen@flash.net" "bbanner", "Bruce", "Banner", "smashallthethings@gmail.com" CSV; $csv = new SplTempFileObject(); $csv->fwrite($usersCSV); $csv->setFlags(SplFileObject::READ_CSV); $it = new LimitIterator($csv, 0, 3); try { $it->seek(20); } catch (OutOfBoundsException $e) { echo "Error: " . $e->getMessage() . PHP_EOL; } Sub Title LimitIterator Throw Exception if seeking beyond total number of elements Error: Cannot seek to 20 which is behind offset 0 plus count 3
  72. Callback Filter Iterator

  73. Source: http://www.php.net/manual/en/spl.iterators.php I need to find all files that contain

    the word “recursive”, but don’t want to create a new class to extend FilterIterator. Problem:
  74. $dirIt = new GlobIterator('*.php'); $recursiveFiles = new CallbackFilterIterator( $dirIt, function($current,

    $key, $it) { return preg_match('/recursive/i', $current); } ); foreach($recursiveFiles as $name) { echo $name . PHP_EOL; } Sub Title CallbackFilterIterator CallbackFilterIterator requires PHP 5.4
  75. $dirIt = new GlobIterator('*.php'); $recursiveFiles = new CallbackFilterIterator( $dirIt, function($current,

    $key, $it) { return preg_match('/recursive/i', $current); } ); foreach($recursiveFiles as $name) { echo $name . PHP_EOL; } Sub Title CallbackFilterIterator CallbackFilterIterator requires PHP 5.4 /recursive_cache.php /recursive_it.php
  76. Caching Iterator

  77. Source: http://www.php.net/manual/en/spl.iterators.php I need to know what value of the

    next element will be. Think prev/ next navigation. Problem:
  78. $articles = new ArrayIterator([ 'NetTuts.com: Integrating Zendesk With WordPress', 'Laravel

    News: The Artisan Files Alex Dover', 'That Podcast: Episode 10 The one with the "best practices"', 'Community News: Packagist Latest Releases for 11.14.2014', ]); $it = new CachingIterator($articles); $it->rewind(); foreach ($it as $article) { echo "{$article}"; if ($it->hasNext()) { echo " --- {$it->getInnerIterator()->current()}"; } echo PHP_EOL; } Sub Title CachingIterator CachingIterator? Look Ahead Iterator! Source: http://stackoverflow.com/questions/2458099/peek-ahead-when-iterating-an-array-in-php-5-2
  79. $articles = new ArrayIterator([ 'NetTuts.com: Integrating Zendesk With WordPress', 'Laravel

    News: The Artisan Files Alex Dover', 'That Podcast: Episode 10 The one with the "best practices"', 'Community News: Packagist Latest Releases for 11.14.2014', ]); $it = new CachingIterator($articles); $it->rewind(); foreach ($it as $article) { echo "{$article}"; if ($it->hasNext()) { echo " --- {$it->getInnerIterator()->current()}"; } echo PHP_EOL; } Sub Title CachingIterator CachingIterator? Look Ahead Iterator! Source: http://stackoverflow.com/questions/2458099/peek-ahead-when-iterating-an-array-in-php-5-2 NetTuts.com: Integrating Zendesk With WordPress --- Laravel News: The Artisan Files Alex Dover Laravel News: The Artisan Files Alex Dover --- That Podcast: Episode 10 The one with the "best practices" That Podcast: Episode 10 The one with the "best practices" --- Community News: Packagist Latest Releases for 11.14.2014 Community News: Packagist Latest Releases for 11.14.2014
  80. Generators

  81. function getLines($file) { $f = fopen($file, 'r'); if (!$f) throw

    new Exception(); while ($line = fgets($f)) { yield $line; } fclose($f); } Sub Title Generator We Have a Generator http://blog.ircmaxell.com/2012/07/what-generators-can-do-for-you.html It’s really that easy!
  82. NOW IN PHP

  83. function easyAsAbc() { yield 1; yield 2; yield 3; }

    foreach (easyAsAbc() as $num) { echo $num . PHP_EOL; } Sub Title Quick Tips with Yield http://us3.php.net/manual/en/language.generators.syntax.php
  84. function easyAsAbc() { yield 1; yield 2; yield 3; }

    foreach (easyAsAbc() as $num) { echo $num . PHP_EOL; } Sub Title Quick Tips with Yield http://us3.php.net/manual/en/language.generators.syntax.php 1 2 3
  85. function easyAsAbc() { yield 1; return; yield 2; yield 3;

    } foreach (easyAsAbc() as $num) { echo $num . PHP_EOL; } Sub Title Quick Tips with Yield http://us3.php.net/manual/en/language.generators.syntax.php End an iteration
  86. function easyAsAbc() { yield 1; return; yield 2; yield 3;

    } foreach (easyAsAbc() as $num) { echo $num . PHP_EOL; } Sub Title Quick Tips with Yield http://us3.php.net/manual/en/language.generators.syntax.php End an iteration 1
  87. function easyAsAbc() { yield 1; return true; yield 2; yield

    3; } foreach (easyAsAbc() as $num) { echo $num . PHP_EOL; } Sub Title Quick Tips with Yield http://us3.php.net/manual/en/language.generators.syntax.php Returning a value will cause a PHP Fatal Returning ANY VALUE will cause a PHP Fatal
  88. function easyAsAbc() { yield 1; return true; yield 2; yield

    3; } foreach (easyAsAbc() as $num) { echo $num . PHP_EOL; } Sub Title Quick Tips with Yield http://us3.php.net/manual/en/language.generators.syntax.php Returning a value will cause a PHP Fatal Returning ANY VALUE will cause a PHP Fatal PHP Fatal error: Generators cannot return values using "return"
  89. function userAttributes() { yield 'id' => 1; yield 'username' =>

    'jsmith'; yield 'email' => 'jake.smith92@gmail.com'; } foreach (userAttributes() as $key => $val) { echo $key . ':' . $val . PHP_EOL; } Sub Title Quick Tips with Yield http://us3.php.net/manual/en/language.generators.syntax.php Key and Value yield
  90. function userAttributes() { yield 'id' => 1; yield 'username' =>

    'jsmith'; yield 'email' => 'jake.smith92@gmail.com'; } foreach (userAttributes() as $key => $val) { echo $key . ':' . $val . PHP_EOL; } Sub Title Quick Tips with Yield http://us3.php.net/manual/en/language.generators.syntax.php Key and Value yield id:1 username:jsmith email:jake.smith92@gmail.com
  91. function counter($start) { for ($i = $start; $i >= $start;

    $i++) { $command = (yield $i); if ($command == "stop") { return; } } } $counter = counter(1); foreach ($counter as $num) { if ($num >= 20) { $counter->send('stop'); } echo $num . PHP_EOL; } Receive data Quick Tips with Yield
  92. function counter($start) { for ($i = $start; $i >= $start;

    $i++) { $command = (yield $i); if ($command == "stop") { return; } } } $counter = counter(1); foreach ($counter as $num) { if ($num >= 20) { $counter->send('stop'); } echo $num . PHP_EOL; } Receive data Quick Tips with Yield
  93. function counter($start) { for ($i = $start; $i >= $start;

    $i++) { $command = (yield $i); if ($command == "stop") { return; } } } $counter = counter(1); foreach ($counter as $num) { if ($num >= 20) { $counter->send('stop'); } echo $num . PHP_EOL; } Receive data Quick Tips with Yield Receiving values via send method
  94. function counter($start) { for ($i = $start; $i >= $start;

    $i++) { $command = (yield $i); if ($command == "stop") { return; } } } $counter = counter(1); foreach ($counter as $num) { if ($num >= 20) { $counter->send('stop'); } echo $num . PHP_EOL; } Receive data Quick Tips with Yield Receiving values via send method 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
  95. Other Iterators

  96. Other Iterators •EmptyIterator •If you try to access current() it

    will throw an Exception •InfiniteIterator •Continuously runs (auto rewinds)
  97. Iterator Functions

  98. Iterator Functions • iterator_to_array • If Iterator is Recursive, it

    will flatten array • iterator_apply • similar to array_walk • iterator_count • used when iterator doesn’t implement countable
  99. Questions? Concerns? Complaints?

  100. https://joind.in/12807

  101. jakefolio http://jakefolio.com me@jakefolio.com Jake Smith Thanks for Listening!