├── .gitignore ├── examples ├── Car.php ├── fraggles.php ├── MyCar.php ├── test.php ├── southParkCharacters.php ├── states.php └── data.html ├── app ├── Iterators │ ├── Classes │ │ ├── CustomArrayIterator.php │ │ ├── CustomCachingIterator.php │ │ ├── FizzBuzzFilter.php │ │ ├── DwarfIterator.php │ │ ├── Miata.php │ │ ├── FizzBuzz.php │ │ ├── OuterIteratorDemo.php │ │ ├── PrettyBits.php │ │ ├── SeekableIterator.php │ │ └── IteratorDemo.php │ └── Command │ │ ├── BitMathCommand.php │ │ ├── RecursiveCommand.php │ │ ├── SeekCommand.php │ │ ├── FizzBuzzCommand.php │ │ ├── IteratorInterfaceCommand.php │ │ ├── OuterIteratorCommand.php │ │ ├── FizzBuzzFilteredCommand.html │ │ ├── FizzBuzzFilteredCommand.php │ │ ├── ArrayIteratorCommand.php │ │ ├── GeneratorCommand.php │ │ ├── DirectoryCommand.php │ │ └── CachingIteratorCommand.php ├── test.php └── console.sh ├── README.md ├── composer.json └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | composer.lock 2 | vendor/ -------------------------------------------------------------------------------- /examples/Car.php: -------------------------------------------------------------------------------- 1 | key() . ' - ' . $this->current(); 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /app/Iterators/Classes/CustomCachingIterator.php: -------------------------------------------------------------------------------- 1 | offsetUnset(4); 11 | 12 | return; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # iterators 2 | 3 | This is the sourcecode respository for [Iterating PHP Iterators](https://leanpub.com/iteratingphpiterators) by [Cal Evans](http://blog.calevans.com) 4 | 5 | Copyright: 2015 [E.I.C.C., Inc.](http://eicc.com) 6 | 7 | License: [MIT](http://opensource.org/licenses/MIT) 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/Iterators/Classes/FizzBuzzFilter.php: -------------------------------------------------------------------------------- 1 | rewind(); 11 | $it[3] = 'Cal'; 12 | echo "The fourth letter of the alphabet is: " . $it[3] . PHP_EOL; 13 | 14 | print_r($it); 15 | 16 | echo "\n\n"; 17 | 18 | print_r($it->getInnerIterator()); 19 | -------------------------------------------------------------------------------- /app/Iterators/Classes/DwarfIterator.php: -------------------------------------------------------------------------------- 1 | filter = $filter; 12 | return; 13 | } 14 | 15 | public function accept() 16 | { 17 | return (strpos($this->getInnerIterator()->current(), $this->filter) !== false); 18 | } 19 | 20 | } -------------------------------------------------------------------------------- /examples/fraggles.php: -------------------------------------------------------------------------------- 1 | $value) { 23 | echo $key . ":" . $value . "\n"; 24 | } 25 | echo "\nDone\n"; 26 | die(); 27 | 28 | -------------------------------------------------------------------------------- /examples/test.php: -------------------------------------------------------------------------------- 1 | 'Grumpy', 4 | 2 => 'Happy', 5 | 3 => 'Sleepy', 6 | 4 => 'Bashful', 7 | 5 => 'Sneezy', 8 | 6 => 'Dopey', 9 | 7 => 'Doc' 10 | ]; 11 | 12 | $it = new CachingIterator(new ArrayIterator($dwarves), 13 | CachingIterator::FULL_CACHE); 14 | foreach ($it as $v) { 15 | ; 16 | } 17 | 18 | $it->offsetUnset(4); 19 | $it->offsetSet('Cal', 'Kathy'); 20 | $it[5] = 'Surly'; 21 | 22 | foreach ($it as $offset => $value) { 23 | echo 'Original: ' . $offset . ' == ' . $value . "\n"; 24 | } 25 | 26 | foreach ($it->getCache() as $offset => $value) { 27 | echo 'Cache: ' . $offset . ' == ' . $value . "\n"; 28 | } 29 | 30 | -------------------------------------------------------------------------------- /app/console.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | addCommands([new Command\ArrayIteratorCommand(), 11 | new Command\CachingIteratorCommand(), 12 | new Command\FizzBuzzCommand(), 13 | new Command\FizzBuzzFilteredCommand(), 14 | new Command\IteratorInterfaceCommand(), 15 | new Command\GeneratorCommand(), 16 | new Command\OuterIteratorCommand(), 17 | new Command\DirectoryCommand(), 18 | new Command\BitMathCommand(), 19 | new Command\SeekCommand]); 20 | $app->run(); -------------------------------------------------------------------------------- /app/Iterators/Classes/Miata.php: -------------------------------------------------------------------------------- 1 | data[$key])) { 20 | $this->data[$key] = $value; 21 | } 22 | return; 23 | } 24 | 25 | public function offsetExists($key) 26 | { 27 | return isset($this->data[$key]); 28 | } 29 | 30 | public function offsetUnset($key) 31 | { 32 | unset($this->data[$key]); 33 | } 34 | 35 | public function offsetGet($key) 36 | { 37 | return isset($this->data[$key]) ? $this->data[$key] : null; 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Cal Evans 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /app/Iterators/Classes/FizzBuzz.php: -------------------------------------------------------------------------------- 1 | numbers = $numbers; 12 | return; 13 | } 14 | 15 | public function current() 16 | { 17 | $returnValue = ''; 18 | $returnValue .= ($this->numbers[$this->pointer] % 3 === 0 ? 'Fizz' : ''); 19 | $returnValue .= ($this->numbers[$this->pointer] % 5 === 0 ? 'Buzz' : ''); 20 | $returnValue = (empty($returnValue) ? $this->numbers[$this->pointer] : $returnValue); 21 | return $returnValue; 22 | } 23 | 24 | public function key() 25 | { 26 | return $this->pointer; 27 | } 28 | 29 | 30 | public function next() 31 | { 32 | $this->pointer++; 33 | return; 34 | } 35 | 36 | 37 | public function rewind() 38 | { 39 | $this->pointer = 0; 40 | return; 41 | } 42 | 43 | 44 | public function valid() 45 | { 46 | return isset($this->numbers[$this->pointer]); 47 | } 48 | 49 | } -------------------------------------------------------------------------------- /app/Iterators/Classes/OuterIteratorDemo.php: -------------------------------------------------------------------------------- 1 | numbers = $numbers; 12 | return; 13 | } 14 | 15 | public function current() 16 | { 17 | $returnValue = ''; 18 | $returnValue .= ($this->numbers[$this->pointer] % 3 === 0 ? 'Fizz' : ''); 19 | $returnValue .= ($this->numbers[$this->pointer] % 5 === 0 ? 'Buzz' : ''); 20 | $returnValue = (empty($returnValue) ? $this->numbers[$this->pointer] : $returnValue); 21 | return $returnValue; 22 | } 23 | 24 | public function key() 25 | { 26 | return $this->pointer; 27 | } 28 | 29 | 30 | public function next() 31 | { 32 | $this->pointer++; 33 | return; 34 | } 35 | 36 | 37 | public function rewind() 38 | { 39 | $this->pointer = 0; 40 | return; 41 | } 42 | 43 | 44 | public function valid() 45 | { 46 | return isset($this->numbers[$this->pointer]); 47 | } 48 | 49 | } -------------------------------------------------------------------------------- /app/Iterators/Command/BitMathCommand.php: -------------------------------------------------------------------------------- 1 | setName("bitmath") 20 | ->setDescription("Displays a 14 bit integer as individual flags") 21 | ->setDefinition($definition) 22 | ->setHelp("Quick demonstration of how bitmath works. "); 23 | } 24 | 25 | 26 | protected function execute( 27 | InputInterface $input, 28 | OutputInterface $output 29 | ) { 30 | $number = (int)$input->getOption('number'); 31 | 32 | PrettyBits::printIt($number); 33 | 34 | $output->writeln("Done"); 35 | return; 36 | } 37 | 38 | } -------------------------------------------------------------------------------- /examples/southParkCharacters.php: -------------------------------------------------------------------------------- 1 | setName("recursive") 15 | ->setDescription("Demonstrate a Recrusive Iterator") 16 | ->setHelp("Iterate over a multi-dimensional array using ther RecursiveIteratorIterator"); 17 | } 18 | 19 | 20 | protected function execute( 21 | InputInterface $input, 22 | OutputInterface $output 23 | ) { 24 | $characters = include __DIR__ . '/../../../examples/southparkCharacters.php'; 25 | 26 | $output->writeln("Source Array:"); 27 | print_r($characters); 28 | 29 | $output->writeln("Iterator Output"); 30 | $iterator = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($characters)); 31 | 32 | foreach ($iterator as $key => $value) { 33 | $output->writeln($key . " : " . $value);; 34 | } 35 | 36 | $output->writeln("Done"); 37 | return; 38 | 39 | } 40 | 41 | } 42 | 43 | -------------------------------------------------------------------------------- /app/Iterators/Command/SeekCommand.php: -------------------------------------------------------------------------------- 1 | setName("seek") 16 | ->setDescription("Demonstrate PHP's SeekIterator") 17 | ->setHelp("Runs a simple demo to show how to use PHP's SeekIterator."); 18 | } 19 | 20 | 21 | protected function execute( 22 | InputInterface $input, 23 | OutputInterface $output 24 | ) { 25 | $fraggles = include __DIR__ . '/../../../examples/fraggles.php'; 26 | 27 | $fraggleIterator = new SeekableIterator($fraggles, false); 28 | 29 | /* 30 | * This will nt produce the results you expect. 31 | */ 32 | for ($lcvA = 0; $lcvA < count($fraggleIterator); $lcvA++) { 33 | $fraggleIterator->seek($lcvA); 34 | echo $lcvA . " : " . $fraggleIterator->current() . "\n"; 35 | } 36 | 37 | $output->writeln("Done"); 38 | return; 39 | 40 | } 41 | 42 | } 43 | 44 | -------------------------------------------------------------------------------- /app/Iterators/Command/FizzBuzzCommand.php: -------------------------------------------------------------------------------- 1 | setName("fizzbuzz") 20 | ->setDescription("Outputs FizzBuzz") 21 | ->setDefinition($definition) 22 | ->setHelp("Simple demonstration of how to modify the output of an Iterator."); 23 | } 24 | 25 | 26 | protected function execute( 27 | InputInterface $input, 28 | OutputInterface $output 29 | ) { 30 | $max = max((int)$input->getOption('max'), 1); 31 | $numbers = range(1, $max); 32 | 33 | $fizzBuzz = new FizzBuzz($numbers); 34 | 35 | foreach ($fizzBuzz as $thisNumber) { 36 | $output->writeln(" " . $thisNumber); 37 | } // foreach($iteratableClass as $committer) 38 | 39 | $output->writeln("Done"); 40 | return; 41 | } 42 | 43 | } -------------------------------------------------------------------------------- /app/Iterators/Command/IteratorInterfaceCommand.php: -------------------------------------------------------------------------------- 1 | setName("iteratorInterface") 15 | ->setDescription("Shows a list of the recent committers to PHP") 16 | ->setHelp("Demonstrates building a custom Iterator using PHP's built in IteratorInterface"); 17 | } 18 | 19 | 20 | protected function execute( 21 | InputInterface $input, 22 | OutputInterface $output 23 | ) { 24 | $iteratableClass = new IteratorDemo(); 25 | 26 | if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) { 27 | $iteratableClass->setVerbose(true); 28 | } 29 | 30 | $output->writeln("Looks like we've got " . count($iteratableClass) . " recent committers."); 31 | 32 | foreach ($iteratableClass as $committer) { 33 | $output->writeln(" Commiter : " . $committer['name'] . ' from ' . $committer['location']); 34 | } // foreach($iteratableClass as $committer) 35 | 36 | $output->writeln("Done"); 37 | return; 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /app/Iterators/Command/OuterIteratorCommand.php: -------------------------------------------------------------------------------- 1 | setName("outerIterator") 18 | ->setDescription("Filters the Seven Dwarfs") 19 | ->setDefinition($definition) 20 | ->setHelp("Demonstrates how an Outer Iterator works."); 21 | } 22 | 23 | 24 | protected function execute( 25 | InputInterface $input, 26 | OutputInterface $output 27 | ) { 28 | $filter = substr((string)$input->getOption('filter'), 0, 1); 29 | $dwarves = ['Grumpy ', 'Happy ', 'Sleepy ', 'Bashful ', 'Sneezy ', 'Dopey ', 'Doc ']; 30 | $dwarfIterator = new DwarfIterator(new \ArrayIterator($dwarves), $filter); 31 | 32 | foreach ($dwarfIterator as $thisDwarf) { 33 | $output->writeln($thisDwarf); 34 | } // foreach($dwarfIterator as $thisDwarf) 35 | 36 | $output->writeln("Done"); 37 | return; 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /examples/states.php: -------------------------------------------------------------------------------- 1 | 'Alabama', 4 | 'AK' => 'Alaska', 5 | 'AZ' => 'Arizona', 6 | 'AR' => 'Arkansas', 7 | 'CA' => 'California', 8 | 'CO' => 'Colorado', 9 | 'CT' => 'Connecticut', 10 | 'DE' => 'Delaware', 11 | 'FL' => 'Florida', 12 | 'GA' => 'Georgia', 13 | 'HI' => 'Hawaii', 14 | 'ID' => 'Idaho', 15 | 'IL' => 'Illinois', 16 | 'IN' => 'Indiana', 17 | 'IA' => 'Iowa', 18 | 'KS' => 'Kansas', 19 | 'KY' => 'Kentucky', 20 | 'LA' => 'Louisiana', 21 | 'ME' => 'Maine', 22 | 'MD' => 'Maryland', 23 | 'MA' => 'Massachusetts', 24 | 'MI' => 'Michigan', 25 | 'MN' => 'Minnesota', 26 | 'MS' => 'Mississippi', 27 | 'MO' => 'Missouri', 28 | 'MT' => 'Montana', 29 | 'NE' => 'Nebraska', 30 | 'NV' => 'Nevada', 31 | 'NH' => 'New Hampshire', 32 | 'NJ' => 'New Jersey', 33 | 'NM' => 'New Mexico', 34 | 'NY' => 'New York', 35 | 'NC' => 'North Carolina', 36 | 'ND' => 'North Dakota', 37 | 'OH' => 'Ohio', 38 | 'OK' => 'Oklahoma', 39 | 'OR' => 'Oregon', 40 | 'PA' => 'Pennsylvania', 41 | 'RI' => 'Rhode Island', 42 | 'SC' => 'South Carolina', 43 | 'SD' => 'South Dakota', 44 | 'TN' => 'Tennessee', 45 | 'TX' => 'Texas', 46 | 'UT' => 'Utah', 47 | 'VT' => 'Vermont', 48 | 'VA' => 'Virginia', 49 | 'WA' => 'Washington', 50 | 'WV' => 'West Virginia', 51 | 'WI' => 'Wisconsin', 52 | 'WY' => 'Wyoming' 53 | ]; 54 | -------------------------------------------------------------------------------- /app/Iterators/Command/FizzBuzzFilteredCommand.html: -------------------------------------------------------------------------------- 1 | setName("fizzbuzzfiltered") 20 | ->setDescription("Filters input before outputting FizzBuzz") 21 | ->setDefinition($definition) 22 | ->setHelp("Simple demonstration of how to modify the input and output of an Iterator."); 23 | } 24 | 25 | 26 | protected function execute(InputInterface $input, 27 | OutputInterface $output) 28 | { 29 | $max = (int)$input->getOption('max'); 30 | $numbers = range(1, $max); 31 | 32 | $fizzBuzzFiltered = new \Iterators\Classes\FizzBuzzFilter($numbers); 33 | 34 | foreach($numbers as $thisNumber) { 35 | $fizzBuzzFiltered[]=$thisNumber; 36 | } 37 | 38 | $fizzBuzz = new \Iterators\Classes\FizzBuzz($fizzBuzzFiltered); 39 | 40 | foreach($fizzBuzz as $thisNumber) { 41 | $output->writeln(" ".$thisNumber); 42 | } // foreach($iteratableClass as $committer) 43 | 44 | $output->writeln("Done"); 45 | return; 46 | } 47 | 48 | } -------------------------------------------------------------------------------- /app/Iterators/Command/FizzBuzzFilteredCommand.php: -------------------------------------------------------------------------------- 1 | setName("fizzbuzzfiltered") 21 | ->setDescription("Filters input before outputting FizzBuzz") 22 | ->setDefinition($definition) 23 | ->setHelp("Simple demonstration of how to modify the input and output of an Iterator."); 24 | } 25 | 26 | 27 | protected function execute( 28 | InputInterface $input, 29 | OutputInterface $output 30 | ) { 31 | $max = max((int)$input->getOption('max'), 1); 32 | $numbers = range(1, $max); 33 | 34 | $fizzBuzzFiltered = new FizzBuzzFilter(); 35 | 36 | foreach ($numbers as $thisNumber) { 37 | $fizzBuzzFiltered[] = $thisNumber; 38 | } 39 | 40 | $fizzBuzz = new FizzBuzz($fizzBuzzFiltered); 41 | 42 | foreach ($fizzBuzz as $thisNumber) { 43 | $output->writeln(" " . $thisNumber); 44 | } // foreach($iteratableClass as $committer) 45 | 46 | $output->writeln("Done"); 47 | return; 48 | } 49 | 50 | } -------------------------------------------------------------------------------- /app/Iterators/Command/ArrayIteratorCommand.php: -------------------------------------------------------------------------------- 1 | setName("arrayIterator") 15 | ->setDescription("Does something clever.") 16 | ->setHelp("Demonstrates the use of PHP's built-in ArrayIterator"); 17 | } 18 | 19 | 20 | protected function execute( 21 | InputInterface $input, 22 | OutputInterface $output 23 | ) { 24 | $fraggles = include __DIR__ . '/../../../examples/fraggles.php'; 25 | $arrayIterator = new \ArrayIterator($fraggles); 26 | 27 | // Print the array 28 | $output->writeln("The array in natural order"); 29 | foreach ($arrayIterator as $thisFraggle) { 30 | $output->writeln(" " . $thisFraggle); 31 | } 32 | 33 | // print the array sorted 34 | $output->writeln("The array in alphabetical order"); 35 | $arrayIterator->asort(); 36 | foreach ($arrayIterator as $thisFraggle) { 37 | $output->writeln(" " . $thisFraggle); 38 | } 39 | 40 | 41 | // print the array sorted 42 | $output->writeln("Emprorer First order"); 43 | $arrayIterator->uasort([$this, 'emperorFirst']); 44 | 45 | foreach ($arrayIterator as $thisFraggle) { 46 | $output->writeln(" " . $thisFraggle); 47 | } 48 | 49 | 50 | $output->writeln("Done"); 51 | return; 52 | } 53 | 54 | public function emperorFirst($a) 55 | { 56 | return (substr($a, 0, 3) == "Emp" ? 0 : 1); 57 | } 58 | } -------------------------------------------------------------------------------- /app/Iterators/Classes/SeekableIterator.php: -------------------------------------------------------------------------------- 1 | setVerbose($verbose); 14 | $this->data = $data; 15 | } 16 | 17 | 18 | public function count() 19 | { 20 | if ($this->verbose) { 21 | echo "-- Count\n"; 22 | } 23 | return count($this->data); 24 | } 25 | 26 | 27 | public function key() 28 | { 29 | if ($this->verbose) { 30 | echo "-- Key\n"; 31 | } 32 | return $this->pointer; 33 | } 34 | 35 | 36 | public function next() 37 | { 38 | if ($this->verbose) { 39 | echo "-- Next\n"; 40 | } 41 | 42 | $this->pointer++; 43 | 44 | return; 45 | } 46 | 47 | 48 | public function rewind() 49 | { 50 | if ($this->verbose) { 51 | echo "-- Rewind\n"; 52 | } 53 | $this->pointer = 0; 54 | 55 | return; 56 | } 57 | 58 | 59 | public function valid() 60 | { 61 | if ($this->verbose) { 62 | echo "-- Valid\n"; 63 | } 64 | 65 | return isset($this->data[$this->pointer]); 66 | } 67 | 68 | 69 | public function current() 70 | { 71 | if ($this->verbose) { 72 | echo "-- Current\n"; 73 | } 74 | return $this->data[$this->pointer]; 75 | } 76 | 77 | 78 | public function seek($position) 79 | { 80 | 81 | $position = rand(0, count($this->data) - 1); 82 | 83 | if (!isset($this->data[$position])) { 84 | throw new \OutOfBoundsException("invalid seek position ($position)"); 85 | } 86 | 87 | $this->pointer = $position; 88 | 89 | return; 90 | } 91 | 92 | /* 93 | * Not part of the Seekable interface 94 | */ 95 | public function setVerbose($newValue = false) 96 | { 97 | $this->verbose = (bool)$newValue; 98 | return; 99 | } 100 | 101 | } -------------------------------------------------------------------------------- /app/Iterators/Command/GeneratorCommand.php: -------------------------------------------------------------------------------- 1 | setName("generator") 16 | ->setDescription("Use PHP's Generator to output recent contributors to the core.") 17 | ->setHelp("Demonstrates how a Generator works."); 18 | } 19 | 20 | 21 | protected function execute( 22 | InputInterface $input, 23 | OutputInterface $output 24 | ) { 25 | $client = new Client(); 26 | $commits = $client->get('https://api.github.com/repos/php/php-src/commits')->json(); 27 | $commitGenerator = $this->gatherCommits($commits, $output->getVerbosity()); 28 | 29 | /* 30 | * If the verbose flag is passed, prove that generators are an object. 31 | */ 32 | if ($output->getVerbosity() === OutputInterface::VERBOSITY_DEBUG) { 33 | print_r($commitGenerator); 34 | print_r(class_implements($commitGenerator)); 35 | $output->writeln("Done"); 36 | return; 37 | } 38 | 39 | foreach ($commitGenerator as $thisCommit) { 40 | echo $thisCommit['committer']['name'] . " : " . $thisCommit['committer']['location'] . "\n"; 41 | } 42 | 43 | $output->writeln("Done"); 44 | return; 45 | } 46 | 47 | 48 | protected function gatherCommits($gatheredComits, $verbosity) 49 | { 50 | $committers = []; 51 | 52 | foreach ($gatheredComits as $thisCommit) { 53 | 54 | if (!isset($committers[$thisCommit['author']['id']])) { 55 | $client = new Client(); 56 | $committers[$thisCommit['author']['id']] = $client->get('https://api.github.com/user/' . $thisCommit['author']['id'])->json(); 57 | } 58 | 59 | $payload = ['commit' => $thisCommit, 'committer' => $committers[$thisCommit['author']['id']]]; 60 | 61 | if ($verbosity === OutputInterface::VERBOSITY_VERBOSE) { 62 | echo "Pre Yeild\n"; 63 | } 64 | 65 | yield $payload; 66 | 67 | if ($verbosity === OutputInterface::VERBOSITY_VERBOSE) { 68 | echo "Post Yeild\n"; 69 | } 70 | 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /app/Iterators/Command/DirectoryCommand.php: -------------------------------------------------------------------------------- 1 | setName("directory") 21 | ->setDescription("Demonstrate PHP's DirectoryIterator") 22 | ->setDefinition($definition) 23 | ->setHelp("Recurse a directory and print out all the files in it and all subdirectories."); 24 | 25 | } 26 | 27 | 28 | protected function execute( 29 | InputInterface $input, 30 | OutputInterface $output 31 | ) { 32 | 33 | $startingPoint = $input->getOption('directory'); 34 | $method = (int)$input->getOption('method'); 35 | 36 | $output->writeln("Iterating over " . $startingPoint); 37 | 38 | switch ($method) { 39 | 40 | case 1: 41 | $this->method1($startingPoint); 42 | break; 43 | 44 | case 2: 45 | $this->method2($startingPoint); 46 | 47 | } 48 | 49 | $output->writeln("\nDone"); 50 | return; 51 | 52 | } 53 | 54 | protected function method1($dir, $padLength = 0) 55 | { 56 | $thisDir = new \DirectoryIterator($dir); 57 | 58 | foreach ($thisDir as $value) { 59 | if ($thisDir->isDot()) { 60 | // Skip the dot directories 61 | continue; 62 | } else { 63 | if ($thisDir->isDir()) { 64 | 65 | if ($thisDir->isReadable()) { 66 | // if this is a new directory AND we have permission to read it, recurse into it. 67 | echo str_repeat(' ', $padLength * 2) . $value . "\\\n"; 68 | $this->method1($dir . '/' . $value, $padLength + 1); 69 | } 70 | 71 | } else { 72 | // output the file 73 | echo str_repeat(' ', $padLength * 2) . $value . "\n"; 74 | } 75 | } 76 | } 77 | return; 78 | } 79 | 80 | 81 | protected function method2($dir, $padLength = 0) 82 | { 83 | 84 | try { 85 | $thisDir = new \FilesystemIterator($dir); 86 | } catch (\UnexpectedValueException $e) { 87 | return; 88 | } 89 | 90 | foreach ($thisDir as $value) { 91 | 92 | if ($value->isDir()) { 93 | echo str_repeat(' ', $padLength * 2) . $value . "\\\n"; 94 | $this->method2($value->getPathname(), $padLength + 1); 95 | } 96 | 97 | echo str_repeat(' ', $padLength * 2) . $value->getPathname() . "\n"; 98 | } 99 | 100 | return; 101 | } 102 | 103 | 104 | } 105 | -------------------------------------------------------------------------------- /app/Iterators/Classes/IteratorDemo.php: -------------------------------------------------------------------------------- 1 | populate(); 16 | $this->rewind(); 17 | return; 18 | } 19 | 20 | 21 | public function count() 22 | { 23 | if ($this->verbose) { 24 | echo "-- Count\n"; 25 | } 26 | return count($this->committers); 27 | } 28 | 29 | 30 | public function key() 31 | { 32 | if ($this->verbose) { 33 | echo "-- Key\n"; 34 | } 35 | return $this->pointer; 36 | } 37 | 38 | 39 | public function next() 40 | { 41 | if ($this->verbose) { 42 | echo "-- Next\n"; 43 | } 44 | $this->pointer++; 45 | if ($this->valid()) { 46 | $this->committers[$this->pointer]['location'] = $this->fetchLocation($this->pointer); 47 | } 48 | 49 | return; 50 | } 51 | 52 | 53 | public function rewind() 54 | { 55 | if ($this->verbose) { 56 | echo "-- Rewind\n"; 57 | } 58 | $this->pointer = 0; 59 | 60 | if (count($this->committers) > 0) { 61 | $this->committers[$this->pointer]['location'] = $this->fetchLocation($this->pointer); 62 | } 63 | 64 | return; 65 | } 66 | 67 | 68 | public function valid() 69 | { 70 | if ($this->verbose) { 71 | echo "-- Valid\n"; 72 | } 73 | 74 | return isset($this->committers[$this->pointer]); 75 | } 76 | 77 | 78 | public function current() 79 | { 80 | if ($this->verbose) { 81 | echo "-- Current\n"; 82 | } 83 | return $this->committers[$this->pointer]; 84 | } 85 | 86 | 87 | /* 88 | * These are not part of the IteratorInterface. 89 | */ 90 | protected function checkCommiters($email) 91 | { 92 | if ($this->verbose) { 93 | echo "-- Check Committers\n"; 94 | } 95 | $returnValue = false; 96 | foreach ($this->committers as $commiter) { 97 | if ($commiter['email'] === $email) { 98 | $returnValue = true; 99 | break; 100 | } 101 | } 102 | 103 | return $returnValue; 104 | 105 | } 106 | 107 | 108 | protected function populate() 109 | { 110 | if ($this->verbose) { 111 | echo "-- Populate\n"; 112 | } 113 | 114 | $client = new Client(); 115 | $response = $client->get('https://api.github.com/repos/php/php-src/commits'); 116 | $commits = $response->json(); 117 | 118 | foreach ($commits as $thisCommit) { 119 | if (!$this->checkCommiters($thisCommit['commit']['author']['email'])) { 120 | $user = [ 121 | 'email' => $thisCommit['commit']['author']['email'], 122 | 'name' => $thisCommit['commit']['author']['name'] 123 | ]; 124 | 125 | if (is_array($thisCommit['author'])) { 126 | $user['id'] = $thisCommit['author']['id']; 127 | } 128 | 129 | $this->committers[] = $user; 130 | } 131 | } 132 | return; 133 | } 134 | 135 | 136 | protected function fetchLocation($pointer) 137 | { 138 | if ($this->verbose) { 139 | echo "-- Fetch Location\n"; 140 | } 141 | if (empty($this->committers[$pointer]['id'])) { 142 | return 'Unknown'; 143 | } 144 | 145 | if (!isset($this->committers[$pointer]['location'])) { 146 | $client = new Client(); 147 | $response = $client->get('https://api.github.com/user/' . $this->committers[$pointer]['id']); 148 | $githubUser = $response->json(); 149 | $returnValue = $githubUser['location']; 150 | } else { 151 | $returnValue = $this->committers[$pointer]['location']; 152 | } 153 | return $returnValue; 154 | } 155 | 156 | 157 | public function setVerbose($newValue = false) 158 | { 159 | $this->verbose = (bool)$newValue; 160 | return; 161 | } 162 | 163 | } -------------------------------------------------------------------------------- /app/Iterators/Command/CachingIteratorCommand.php: -------------------------------------------------------------------------------- 1 | setName("cachingIterator") 17 | ->setDescription("Output the seven dwarfs in CSV format.") 18 | ->setHelp("Demonstrates how a Caching Iterator works."); 19 | } 20 | 21 | 22 | protected function execute( 23 | InputInterface $input, 24 | OutputInterface $output 25 | ) { 26 | $dwarves = [ 27 | 1 => 'Grumpy', 28 | 2 => 'Happy', 29 | 3 => 'Sleepy', 30 | 4 => 'Bashful', 31 | 5 => 'Sneezy', 32 | 6 => 'Dopey', 33 | 7 => 'Doc' 34 | ]; 35 | $output->writeln('Look ahead exampe. Build a CSV the hard way.'); 36 | 37 | $dwarfIterator = new \ArrayIterator($dwarves); 38 | $cachingDwarfIterator = new \CachingIterator($dwarfIterator); 39 | $dwarfListOutput = ''; 40 | 41 | foreach ($cachingDwarfIterator as $thisDwarf) { 42 | $dwarfListOutput .= $thisDwarf; 43 | 44 | if ($cachingDwarfIterator->hasNext()) { 45 | $dwarfListOutput .= ','; 46 | } 47 | 48 | } // foreach($dwarfIterator as $thisDwarf) 49 | 50 | $output->writeln($dwarfListOutput); 51 | $output->writeln(' '); 52 | 53 | $dwarfIterator = null; 54 | $cachingDwarfIterator = null; 55 | 56 | 57 | $output->writeln('Set the TOSTRING_USE_KEY flag'); 58 | $dwarfIterator = new \ArrayIterator($dwarves); 59 | $cachingDwarfIterator = new \CachingIterator($dwarfIterator, \CachingIterator::TOSTRING_USE_KEY); 60 | 61 | foreach ($cachingDwarfIterator as $key => $thisDwarf) { 62 | var_dump((string)$cachingDwarfIterator); 63 | echo "\n"; 64 | } // foreach($dwarfIterator as $thisDwarf) 65 | 66 | $dwarfIterator = null; 67 | $cachingDwarfIterator = null; 68 | 69 | $output->writeln(' '); 70 | $output->writeln('Setting the TOSTRING_USE_CURRENT flag'); 71 | 72 | $dwarfIterator = new \ArrayIterator($dwarves); 73 | $cachingDwarfIterator = new \CachingIterator($dwarfIterator, \CachingIterator::TOSTRING_USE_CURRENT); 74 | 75 | foreach ($cachingDwarfIterator as $key => $thisDwarf) { 76 | var_dump((string)$cachingDwarfIterator); 77 | echo "\n"; 78 | } // foreach($dwarfIterator as $thisDwarf) 79 | 80 | 81 | $output->writeln(' '); 82 | $output->writeln('Setting the TOSTRING_USE_INNER flag'); 83 | 84 | $dwarfIterator = new CustomArrayIterator($dwarves); 85 | $cachingDwarfIterator = new \CachingIterator($dwarfIterator, \CachingIterator::TOSTRING_USE_INNER); 86 | 87 | foreach ($cachingDwarfIterator as $key => $thisDwarf) { 88 | var_dump((string)$cachingDwarfIterator); 89 | echo "\n"; 90 | } // foreach($dwarfIterator as $thisDwarf) 91 | 92 | 93 | $output->writeln(' '); 94 | $output->writeln('Setting the FULL_CACHE flag'); 95 | $dwarfIterator = new \ArrayIterator($dwarves); 96 | $cachingDwarfIterator = new CustomCachingIterator($dwarfIterator, \CachingIterator::FULL_CACHE); 97 | 98 | // Load the cache; 99 | foreach ($cachingDwarfIterator as $thisDwarf) { 100 | }; 101 | 102 | $cachingDwarfIterator->removeBashful(); 103 | 104 | $output->writeln(' '); 105 | $output->writeln(' Cached'); 106 | 107 | foreach ($cachingDwarfIterator->getCache() as $key => $thisDwarf) { 108 | $output->writeln($key . " : " . $thisDwarf); 109 | } // foreach($dwarfIterator as $thisDwarf) 110 | 111 | $output->writeln(' '); 112 | $output->writeln(' This is the original iterator'); 113 | foreach ($cachingDwarfIterator as $key => $thisDwarf) { 114 | $output->writeln($key . " - " . $thisDwarf); 115 | } // foreach($dwarfIterator as $thisDwarf) 116 | 117 | 118 | $output->writeln(' '); 119 | $output->writeln(" Now that we've modified an element, \n let's modify an element"); 120 | 121 | $dwarfIterator = new \ArrayIterator($dwarves); 122 | $cachingDwarfIterator = new \CachingIterator($dwarfIterator, \CachingIterator::FULL_CACHE); 123 | // Load the cache; 124 | foreach ($cachingDwarfIterator as $thisDwarf) { 125 | }; 126 | 127 | $cachingDwarfIterator[5] = 'Surley'; 128 | 129 | $output->writeln(' '); 130 | $output->writeln(' Now let\'s out the inner cache'); 131 | foreach ($cachingDwarfIterator->getCache() as $key => $thisDwarf) { 132 | $output->writeln($key . " : " . $thisDwarf); 133 | } // foreach($dwarfIterator as $thisDwarf) 134 | 135 | 136 | $output->writeln("Done"); 137 | return; 138 | } 139 | 140 | } 141 | -------------------------------------------------------------------------------- /examples/data.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Fraggle Rock Characters - Naming Schemes 5 | 6 | 7 | 9 | 10 | 11 | 13 | 14 | 16 | 18 | 19 | 21 | 26 | 27 | 28 | 74 | 171 | 174 | 178 | 179 |
180 |
181 | 182 |
183 | 184 | 185 | 186 | 187 |

Fraggle Rock Characters

188 | 189 | 190 |
191 | 192 |
From Naming Schemes
193 | 194 | 195 |
196 | 197 | 198 |
199 | Jump to: navigation, search 200 |
201 | 202 | 203 |
204 | 205 | 206 | 221 | 222 |
207 |

Contents

208 | 220 |
223 |

[edit] Fraggles

227 |
    228 |
  • Boober 229 |
  • 230 |
  • Gobo 231 |
  • 232 |
  • Mokey 233 |
  • 234 |
  • Red 235 |
  • 236 |
  • Wembley 237 |
  • 238 |
239 |

[edit] Doozers 242 |

243 |
    244 |
  • Architect 245 |
  • 246 |
  • Crosscut 247 |
  • 248 |
  • Crusty 249 |
  • 250 |
  • Cotterpin (Architects apprentice) 251 |
  • 252 |
  • Flange (Cotterpin's father) 253 |
  • 254 |
  • Flex 255 |
  • 256 |
  • Hammerhead 257 |
  • 258 |
  • Modem (Wrench's mother) 259 |
  • 260 |
  • Wrench 261 |
  • 262 |
263 |

[edit] Gorgs

266 |
    267 |
  • Emperor of the Universe 268 |
  • 269 |
  • Empress of the Universe 270 |
  • 271 |
  • Gunge 272 |
  • 273 |
  • Junior 274 |
  • 275 |
  • Marjory 276 |
  • 277 |
  • Philo 278 |
  • 279 |
280 |

[edit] Outer Space 283 |

284 |
    285 |
  • Doc 286 |
  • 287 |
  • Sprocket 288 |
  • 289 |
290 |

[edit] External Links 293 |

294 | 299 | 300 | 309 | 310 | 311 |
312 | 313 | 314 | 317 | 318 | 319 | 320 | 321 |
322 | 323 | 324 |
325 | 326 |
327 | 328 | 329 |
330 | 331 | 332 |
333 |
Personal tools
334 | 339 |
340 | 341 | 342 |
343 | 344 | 345 |
346 |
Namespaces
347 | 355 |
356 | 357 | 358 | 359 | 360 |
361 |

362 |

363 |
Variants
364 | 365 | 369 |
370 | 371 | 372 |
373 |
374 | 375 | 376 |
377 |
Views
378 | 387 |
388 | 389 | 390 | 391 | 392 |
393 |
Actions
394 | 395 | 399 |
400 | 401 | 402 | 403 | 404 | 416 | 417 | 418 |
419 |
420 | 421 | 422 |
423 | 424 | 426 | 427 | 428 | 429 |
430 |
Navigation
431 | 432 |
433 | 443 |
444 |
445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 |
454 |
Toolbox
455 | 456 |
457 | 471 |
472 |
473 | 474 | 475 | 476 | 477 | 478 | 479 |
480 | 481 | 482 | 503 | 504 | 507 | 508 | 511 | 512 | 516 | 521 | 522 | 523 | 524 | 525 | --------------------------------------------------------------------------------