Your SlideShare is downloading. ×

Iteratory

1,805

Published on

Presentation for first meetphp convention

Presentation for first meetphp convention

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,805
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
26
Comments
0
Likes
2
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Iteratory
  • 2. Iteracja po tablicach$array = range(1, 5); // generuje tablicę z wartościami od 1 do 5foreach ($array as $key => $value) { echo $key. => .$value.PHP_EOL;}/* wynik0 => 11 => 22 => 33 => 44 => 5*/
  • 3. Iteracja po tablicach – wewnętrzny kursor$array = range(1, 5);current($array); // 1next($array); // 2current($array); // 2next($array);each($array); // array(2, 3)end($array); // 5current($array); // 5while (list($key, $value) = each($array)) { echo $key . => .$value.PHP_EOL;}// 4 => 5
  • 4. Iteracja po obiekcie$object = new stdClass;$object->key = value;$object->key_2 = value_2;foreach ($object as $key=>$value) { echo $key. => .$value.PHP_EOL;}// key => value// key_2 => value_2
  • 5. Iteracja po obiekcie – tylko właściwości publiczneclass foo { public $key = value; protected $key_2 = value_2; private $key_3 = value_3; static public $staticKey = value; static protected $staticKey_2 = value_2; static private $staticKey_3 = value_3;}$object = new foo;foreach ($object as $key=>$value) { echo $key. => .$value.PHP_EOL;}// key => value
  • 6. Zachowanie iteracji wg obiektuclass MyIterator implements Iterator {private $_tab = array();public function __construct(array $tab){ $this->_tab = $tab;}public function current() { $object = new MyIterator(range(1,3)); return current($this->_tab)._MyIteration; foreach ($object as $key=>$value) {} echo $key. => .$value.PHP_EOL;public function next() { } next($this->_tab); // rewind} // check_validpublic function key() { // 0 => 1_MyIteration return key($this->_tab); // check_valid} // 1 => 2_MyIterationpublic function valid() { // check_valid echo check_valid . PHP_EOL; // 2 => 3_MyIteration return key($this->_tab) !== null; // check_valid}public function rewind() { echo rewind . PHP_EOL; reset($this->_tab);}}
  • 7. Iterator, IteratorAggregate oraz Traversableinterface Iterator implements Traversable { // definicja interfejsu}interface IteratorAggregate implements Traversable { // definicja interfejsu}• Grupuje dwa rodzaje iteratorów w jedno• Nie może być implementowany bez Iteratora lub IteratorAggregate
  • 8. Traversable jako typowany argumentfunction foo(Traversable $object) {}class Foo implements IteratorAggregate { public function getIterator() { return new EmptyIterator(); }}foo(new ArrayIterator()); // przykładowa implementacja Iteratorfoo(new Foo()); // implementacja IteratorAggregate
  • 9. Kiedy używać interfejsu Iterator?● Uzyskanie całkowitej kontroli nad zwracanymi wartościami● Definiowanie własnych ścieżek poruszania po danych● Generowanie danych
  • 10. Kiedy używać interfejsu Iterator?class PaginationIterator implements Iterator {// definicja prywatnych właściwościpublic function __construct($entriesLength, $entriesPerPage = 20, $activePage = 1) { $this->_entriesLength = (int)$entriesLength; $this->_entriesPerPage = (int)$entriesPerPage; $this->_activePage = (int)$activePage; $this->_maxPages = (int)ceil($this->_entriesLength / $this->_entriesPerPage);}public function current() { $object = new stdClass(); $key = $this->_iterationIndex; $object->page = $key + 1; $object->isActive = $key === ($this->_activePage - 1); return $object;}public function next() { $this->_iterationIndex++; }public function key() { return $this->_iterationIndex; }public function valid() { return $this->_iterationIndex < $this->_maxPages; }public function rewind() { $this->_iterationIndex = 0; }}
  • 11. Kiedy używać interfejsu Iterator?$iterator = new PaginationIterator(100, 30, 1);foreach ($iterator as $page) { echo Page: .$page->page; echo isActive: .var_export($page->isActive, true).PHP_EOL;}// Page: 1 isActive: true// Page: 2 isActive: false// Page: 3 isActive: false// Page: 4 isActive: false
  • 12. Kiedy używać interfejsu IteratorAggregate?● Szybkie zwrócenie danych do iteracji● Idealne we wszelkiego rodzaju klasach agregujących listy wartości● Brak konieczności obróbki danych
  • 13. Kiedy używać interfejsu IteratorAggregate?class Form implements IteratorAggregate { private $_elements = array(); public function addElement(FormElement $element) { $this->_elements[] = $element; } public function getIterator() { return new ArrayIterator($this->_elements); }}class FormElement { public function __construct($type, $name) { $this->type = $type; $this->name = $name; }}
  • 14. Kiedy używać interfejsu IteratorAggregate?$form = new Form();$form->addElement(new FormElement(text, name));$form->addElement(new FormElement(test, surname));foreach ($form as $element) { echo Type: .$element->type; echo Name: .$element->name.PHP_EOL;}// Type: text Name: name// Type: test Name: surname
  • 15. SPL – Dodatkowe interfejsy iteratorów SeekableIterator$iterator = new ArrayIterator(range(1, 5));$seekAlready = false;foreach ($iterator as $key => $value) { echo $key. => .$value.PHP_EOL; if (!$seekAlready && $key === 3) { $iterator->seek(1); $seekAlready = true; echo seek.PHP_EOL; }}// 0 => 1// 1 => 2// 2 => 3// 3 => 4// seek// 2 => 3// 3 => 4// 4 => 5
  • 16. SPL – Dodatkowe interfejsy iteratorów OuterIterator$iterator = new AppendIterator();$iterator->append(new ArrayIterator(range(1, 2)));$iterator->append(new ArrayIterator(range(3, 6)));foreach ($iterator as $key => $value) { echo $key. => .$value. : ; echo $iterator->getInnerIterator()->count().PHP_EOL;}// 0 => 1 : 2// 1 => 2 : 2// 0 => 3 : 4// 1 => 4 : 4// 2 => 5 : 4// 3 => 6 : 4
  • 17. SPL – Dodatkowe interfejsy iteratorów RecursiveIterator$array = array( 1, 2, array(3, 4, 5));$iterator = new RecursiveArrayIterator($array);foreach ($iterator as $key=>$value) { if ($iterator->hasChildren()) { echo children.PHP_EOL; foreach ($iterator->getChildren() as $key => $value) { echo $key. => .$value.PHP_EOL; } } else { echo no children.PHP_EOL; }}// no children// no children// children// 0 => 3// 1 => 4// 2 => 5
  • 18. SPL – ArrayIterator● Wszystkie możliwości sortowania (natsort, usort, ksort)● Dostęp do wartości za pomocą []● Zliczanie ilości elementów● Dodawanie kolejnych elementów● Serializacja, deserializacja
  • 19. SPL – RecursiveIteratorIterator● Iteruje rekursywnie po RecursiveIterator● Niezwykle potężne narzędzie do obsługi struktur drzewiastych oraz wszelkich zagnieżdżeń● 3 tryby iteracji ● LEAVES_ONLY ● SELF_FIRST ● CHILD_FIRST
  • 20. SPL – RecursiveIteratorIterator$array = array( 1, 2, array(3, 4, array( 5, array(6, 7) , 8) , 9));// domyślnie RecursiveIteratorIterator::LEAVES_ONLY$iterator = new RecursiveArrayIterator($array);$iterator = new RecursiveIteratorIterator($iterator);foreach ($iterator as $key => $value) { echo $key. => .$value. : ; echo $iterator->getDepth().PHP_EOL;}// 0 => 1 : 0// 1 => 2 : 0// 0 => 3 : 1// 1 => 4 : 1// 0 => 5 : 2// 0 => 6 : 3// 1 => 7 : 3// 2 => 8 : 2// 3 => 9 : 1
  • 21. SPL – RecursiveIteratorIterator// LEAVES_ONLY // SELF_FIRST // CHILD_FIRST// 0 => 1 : 0 // 0 => 1 : 0 // 0 => 1 : 0// 1 => 2 : 0 // 1 => 2 : 0 // 1 => 2 : 0// 0 => 3 : 1 // 2 => Array : 0 // 0 => 3 : 1// 1 => 4 : 1 // 0 => 3 : 1 // 1 => 4 : 1// 0 => 5 : 2 // 1 => 4 : 1 // 0 => 5 : 2// 0 => 6 : 3 // 2 => Array : 1 // 0 => 6 : 3// 1 => 7 : 3 // 0 => 5 : 2 // 1 => 7 : 3// 2 => 8 : 2 // 1 => Array : 2 // 1 => Array : 2// 3 => 9 : 1 // 0 => 6 : 3 // 2 => 8 : 2 // 1 => 7 : 3 // 2 => Array : 1 // 2 => 8 : 2 // 3 => 9 : 1 // 3 => 9 : 1 // 2 => Array : 0
  • 22. SPL – CallbackFilterIterator – od PHP 5.4class CallbackFilterIterator extends FilterIterator { private $_callback; public function __construct(Iterator $iterator, Closure $callback) { parent::__construct($iterator); $this->_callback = $callback; } public function accept() { return call_user_func( $this->_callback, $this->current(), $this->key(), $this->getInnerIterator()); }}
  • 23. SPL – CallbackFilterIteratorclass Form implements IteratorAggregate { public function getElementsByType($type) { return new CallbackFilterIterator( $this->getIterator(), function($element) use ($type) { return $type === $element->type; }); }}$form = new Form();$form->addElement(new FormElement(text, name));$form->addElement(new FormElement(number, age));$form->addElement(new FormELement(range, weight));foreach ($form->getElementsByType(text) as $element) { echo Type: .$element->type; echo Name: .$element->name.PHP_EOL;}// Type: text Name: name
  • 24. SPL - AppendIterator$form = new Form();$form->addElement(new FormElement(text, name));$form->addElement(new FormElement(number, age));$form->addElement(new FormELement(range, weight));$iterator = new AppendIterator();$iterator->append($form->getElementsByType(text));$iterator->append($form->getElementsByType(range));foreach ($iterator as $element) {echo Type: .$element->type;echo Name: .$element->name.PHP_EOL;}// Type: text Name: name// Type: range Name: weight
  • 25. SPL - DirectoryIterator● Rozszerza SplFileInfo – cała masa dobrodziejstw$iterator = new DirectoryIterator(some_dir);foreach ($iterator as $file) { echo $file->getPathName().PHP_EOL;}// some_dir.// some_dir..// some_dirtest_file.txt// some_dirtest_file_2.txt
  • 26. SPL - RegexIterator$array = array( Jabłko, Banan, Ananas, Wiśnia, Arbuz);$iterator = new ArrayIterator($array);$iterator = new RegexIterator($iterator, /nas?/i);foreach ($iterator as $string) { echo $string.PHP_EOL;}// Banan// Ananas ● Jest w stanie wykonywać replace, split
  • 27. Wespół w zespół – przeszukiwanie katalogów$iterator = new RecursiveDirectoryIterator(PHPUnit/Extensions);$iterator = new RecursiveIteratorIterator($iterator);$iterator = new RegexIterator($iterator, /_coverage/i);foreach ($iterator as $file) { echo $file->getPathName();}// PHPUnit/Extensions/SeleniumTestCase/phpunit_coverage.php
  • 28. SPL – InfiniteIterator – Tasksclass TaskDownloader extends ArrayIterator { public function __construct() { // lock constructor } public function rewind() { $iteration = 0; do { $tasks = $this->fetch(); if ($iteration > 0) { usleep(1000); } $iteration++; } while ($tasks === array()); parent::__construct($tasks); } public function fetch() { // fetch tasks from tasks repository }}$iterator = new InfiniteIterator(new TaskDownloader());foreach ($iterator as $task) { echo $task;}
  • 29. Iteratory oszczędzają pamięć● Nie potrzebują wszystkich danych od samego początku● Są w stanie generować, pobierać dane
  • 30. Pobieranie dużej ilości rekordówclass PDODataPartition extends Iterator { public function rewind() { $this->_loadPartition(0); $this->_position = 0; } public function valid() { if (isset($this->_data[$this->_position])) { return true; } if ($this->_position < $this->_partitionSize) { return false; } if ($this->_loadPartition(++$this->_partitionNum)) { $this->_position = 0; return true; } return false; } protected function _loadPartition($numOfPartition) { $this->_partitionNum = (int)$numOfPartition; $query = $this->_getPartitionQuery(); $stmt = $this->_pdo->query($query); if ($stmt) { $this->_data = $stmt->fetchAll(); } return (bool)$this->_data; } protected function _getPartitionQuery() { $offset = $this->_partitionNum * $this->_partitionSize; $limit = $this->_partitionSize; return $this->_query. LIMIT .$limit. OFFSET .$offset; }}
  • 31. Pobieranie dużej ilości rekordów$records = $pdo->query(SELECT * FROM tabela)->fetchAll();foreach ($records as $record) {}// vs$iterator = new PDODataPartition($pdo, SELECT * FROM tabela, 1000);foreach ($iterator as $record) {} PDO PDODataPartition Pamięć 562 552 25 896 Czas 0,231 s 0,930 s Więcej: http://bit.ly/uGQ0Vl
  • 32. Iterator w php 5.4 - Traittrait IteratorTrait { protected $_data = array(); public function next() { next($this->_data); } public function current() { return current($this->_data); } public function valid() { return key($this->_data) !== null; } public function key() { return key($this->_data); } public function rewind() { reset($this->_data); }}class SomeOtherClass { }class TestIterator extends SomeOtherClass implements Iterator { use IteratorTrait; public function __construct(array $data) { $this->_data = &$data; }}$o = new TestIterator(range(1, 5));foreach ($o as $key => $value) { echo $key. => .$value.PHP_EOL;}
  • 33. KontaktŁukasz KużyńskiTwitter: @wookiebplwww: http://wookieb.plFB: http://www.facebook.com/wookieb

×