Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Iterators in PHP

24,405 views

Published on

How to use and write our own Iterators in PHP

Published in: Business, Technology
  • Great demonstration about the need to innovate company models; how you can represent them succinctly; along with the intent to make advancement initiatives actionable. Superb use of images and obvious to see illustrative samples.
    Sharika
    http://financeadded.com http://traveltreble.com
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

Iterators in PHP

  1. 1. Iterators in PHP 5 <ul><ul><li>Dr Tarique Sani </li></ul></ul><ul><ul><li>CTO, SANIsoft </li></ul></ul><ul><ul><li>Nagpur, India </li></ul></ul>
  2. 2. Who am I? <ul><li>A PHP programmer since 5+ years </li></ul><ul><li>Author of PHP projects like Coppermine, PHPlib and WAPpop </li></ul><ul><li>CTO, of my own software development company working exclusively with PHP </li></ul><ul><li>... </li></ul>
  3. 3. Who are you? <ul><li>Who has been working with PHP </li></ul><ul><li>Who is familiar with some OOP concepts </li></ul><ul><li>Who wants to learn more about new features offered by PHP 5 – specially Iterators </li></ul>
  4. 4. Introduction to Iterators <ul><li>PHP projects perpetually re-inventing the wheel </li></ul><ul><li>Standardising some of the wheels – good idea </li></ul><ul><ul><li>Reusable code </li></ul></ul><ul><ul><li>Same map for developers </li></ul></ul><ul><li>SPL (Standard PHP Library) by Marcus Boerger </li></ul><ul><ul><li>&quot;is a collection of interfaces” </li></ul></ul><ul><ul><li>part of the core distribution of PHP5 </li></ul></ul><ul><ul><li>On by default </li></ul></ul><ul><li>SPL for now has interfaces for Iterators </li></ul>
  5. 5. So what is an Iterator? <ul><li>A design pattern </li></ul><ul><li>Intent of an iterator </li></ul><ul><ul><li>&quot;provide an object which traverses some aggregate structure, abstracting away assumptions about the implementation of that structure.&quot; </li></ul></ul>!! ???
  6. 6. Some common PHP code Loop through a MySQL query // Fetch the &quot;aggregate structure&quot; $result = mysql_query(&quot; SELECT user,pass FROM auth&quot; ); // Iterate over the structure while ( $row = mysql_fetch_array($result) ) { // do stuff with the row here }
  7. 7. Some common PHP code To read the contents of a array: // Fetch the &quot;aggregate structure&quot; $array = ; //Whatever it takes foreach ($array as $key => $value) { // iterate through array elements }
  8. 8. Some common PHP code To read the contents of a file // Fetch the &quot;aggregate structure&quot; $fp = fopen(&quot;/home/tarique/log.txt&quot;, &quot;r&quot;); // Iterate over the structure while (!feof($fp)) { $line = fgets($fp); // do stuff with the line here }
  9. 9. Some common PHP code To read the contents of a directory: // Fetch the &quot;aggregate structure&quot; $dir = opendir('/home/tarique/files'); // Iterate over the structure while ( $file = readdir($dir) ) { print &quot;$file &quot;; }
  10. 10. Bugs!!! <ul><li>File named '0' in the directory </li></ul><ul><li>Solution - </li></ul>while (false != = ($file = readdir($dir))) { print &quot;$file &quot;; } <ul><li>Cumbersome.... </li></ul><ul><li>Is there an easier solution? </li></ul>
  11. 11. Yes! DirectoryIterator <ul><li>Same result is achieved by </li></ul>foreach (new DirectoryIterator($path) as $file) { print &quot;$file &quot;; } <ul><li>Shorter code </li></ul><ul><li>Cleaner code </li></ul><ul><li>Safer code (can't forget === ) </li></ul>
  12. 12. More features of SPL / Iterators <ul><li>Both standalone iterators and iterators meant to be chained </li></ul><ul><ul><li>using the 'FilterIterator' in conjunction with a 'DirectoryIterator' </li></ul></ul><ul><ul><li>'LimitIterator' allows you to 'page' through an iterator's results </li></ul></ul><ul><li>You can create your own Iterators in PHP </li></ul><ul><ul><li>For looping through IMAP results, Thumbnails in a gallery, SQL result sets </li></ul></ul>
  13. 13. More of DirectoryIterator <ul><li>Still not good </li></ul><ul><li>returning . and .. </li></ul><ul><li>returning directories </li></ul><ul><li>Solution </li></ul><ul><ul><li>isDir( ) </li></ul></ul>$dir = new DirectoryIterator( '/www/www.example.com/'); foreach ($dir as $file) { print &quot;$file &quot;; } . .. email.html images includes index.html search.html
  14. 14. More of DirectoryIterator <ul><li>Still not good </li></ul><ul><li>returning . and .. </li></ul><ul><li>returning directories </li></ul><ul><li>Solution </li></ul><ul><ul><li>isDir( ) </li></ul></ul>$dir = new DirectoryIterator( '/www/www.example.com/'); foreach ($dir as $file) { if (! $file->isDir( )) { print &quot;$file &quot;; } } email.html index.html search.html
  15. 15. DirectoryIterator Methods <ul><li>getPath( ) </li></ul><ul><ul><li>Returns the opened path (e.g., /home/tarique/public_html) </li></ul></ul><ul><li>getFilename( ) </li></ul><ul><ul><li>Returns the current filename (e.g., index.html) </li></ul></ul><ul><li>getPathname( ) </li></ul><ul><ul><li>Returns the current path and file </li></ul></ul><ul><li>isDir( ) </li></ul><ul><ul><li>Determines whether the current file is a directory </li></ul></ul><ul><li>isDot( ) </li></ul><ul><ul><li>Determines whether the current file is a dot file </li></ul></ul>
  16. 16. Cut the classroom crap!! Show us something useful!!
  17. 17. Time for me to....
  18. 18. Create your own Iterator <ul><li>Overview of the Iterator 'Interface' and methods </li></ul><ul><li>See how PHP 5 handles multiple queries </li></ul><ul><li>Create a custom Iterator to handle multiple queries </li></ul>
  19. 19. Implementing the Iterator Interface <ul><li>The Iterator interface is a set of 5 methods </li></ul><ul><ul><li>rewind( ) - Resets iterator list to its start </li></ul></ul><ul><ul><li>valid( ) - Says if there are additional items left in the list </li></ul></ul><ul><ul><li>next( ) - Moves iterator to the next item in the list </li></ul></ul><ul><ul><li>key( ) - Returns the key of the current item </li></ul></ul><ul><ul><li>current( ) - Returns the current item </li></ul></ul>
  20. 20. So you can change this... <ul><li>Involves four functions and a do/while loop </li></ul>if (mysqli_multi_query($db, $query)) { do { if ($result = mysqli_store_result($db)) { while ($row = mysqli_fetch_row($result)) { print &quot;$row[0] &quot;; } mysqli_free_result($result); } } while (mysqli_next_result($db)); }
  21. 21. to this..... <ul><li>much simpler and cleaner </li></ul>foreach (new MySQLiQueryIterator($db, $query) as $result) { if ($result) { while ($row = mysqli_fetch_row($result)) { print &quot;$row[0] &quot;; } } }
  22. 22. MySQL multi-query iterator <ul><li>Set some of the needed variables </li></ul><ul><li>Constructor assigns the $link and $query to class variables </li></ul>class MySQLiQueryIterator implements Iterator { protected $link; protected $query; protected $key; protected $valid; protected $result; //Constructor public function __construct($link, $query) { $this->link = $link; $this->query = $query; }
  23. 23. multi-query iterator – rewind( ) <ul><li>Sets the key to 0 </li></ul><ul><li>Executes the query and store the result else make valid false </li></ul>public function rewind( ) { $this->key = 0; if (mysqli_multi_query($this->link, $this->query)) { $this->result = mysqli_store_result($this->link); $this->valid = true; } else { $this->result = false; $this->valid = false; } }
  24. 24. multi-query iterator – valid( ) <ul><li>Returns the result from mysqli_more_results( ) </li></ul><ul><li>Catch the current result to be returned not the next </li></ul>public function valid( ) { // mysqli_more_results( ) is one ahead of Iterator valid( ) $valid = $this->valid; $this->valid = mysqli_more_results($this->link); return $valid; }
  25. 25. multi-query iterator – key( ) public function key( ) { return $this->key; }
  26. 26. multi-query iterator – current( ) public function current( ) { return $this->result; }
  27. 27. multi-query iterator - next() <ul><li>Frees result, increments key </li></ul><ul><li>Fetches an additional row using mysqli_store_result( ) </li></ul>public function next( ) { if ($this->result) { mysqli_free_result($this->result); } $this->key++; if (mysqli_next_result($this->link)) { $this->result = mysqli_store_result($this->link); } else { $this->result = false; } }
  28. 28. multi-query iterator - Usage <ul><li>Worth the trouble </li></ul><ul><li>Use in code simplified </li></ul>$db = mysqli_connect('db.example.org'); $query = >>>_SQL_ DROP TABLE IF EXISTS users; CREATE TABLE users(username VARCHAR(50) UNIQUE, password VARCHAR(50)); INSERT INTO users VALUES('tarique', '123456'); INSERT INTO users VALUES('aasim', 'abcdef'); SELECT username FROM users; _SQL_;
  29. 29. multi-query iterator - Usage foreach (new MySQLiQueryIterator($db, $query) as $result) { if ($result) { while ($row = mysqli_fetch_row($result)) { print &quot;$row[0] &quot;; } } } tarique aasim
  30. 30. Is that it?
  31. 31. Chaining Iterators <ul><li>FilterIterator </li></ul><ul><ul><li>abstract class </li></ul></ul><ul><ul><li>You must define accept( ) method </li></ul></ul><ul><li>LimitIterator </li></ul><ul><ul><li>behaves just like the SQL LIMIT </li></ul></ul>
  32. 32. FilterIterator - Example <ul><li>Takes 2 arguments in constructor – an Iterator and regex </li></ul><ul><li>accept( ) returns true if the regex matches </li></ul>class RegexFilter extends FilterIterator { protected $regex; public function _ _construct(Iterator $it, $regex) { parent::_ _construct($it); $this->regex = $regex; } public function accept( ) { return preg_match($this->regex, $this->current( )); } }
  33. 33. FilterIterator - Example <ul><li>Takes 2 arguments in constructor – an Iterator and regex </li></ul><ul><li>accept( ) returns true if the regex matches </li></ul>$dir = new DirectoryIterator('/www/www.example.com/') { $filtered_dir = new RegexFilter($dir, '/html$/i'); foreach ($filtered_dir as $file); print &quot;$file &quot;; } thumb.html index.html display.html
  34. 34. LimitIterator - Example <ul><li>Can be directly instantiated </li></ul><ul><li>Takes an Iterator, start position and number of items to return </li></ul>foreach(new LimitIterator( new DirectoryIterator('/www/www.example.com/'), 2, 2) as $file) { print &quot;$file &quot;; } index.html images
  35. 35. Combined - Example <ul><li>return the first file with html extension </li></ul>foreach(new LimitIterator(new RegexFilter( new DirectoryIterator('/www/www.example.com/'), '/html$/i'), 0, 1) as $file) { print &quot;$file &quot;; } index.html
  36. 36. Is that it...
  37. 37. SimpleXML Iterator <ul><li>Takes and XML string and makes it an iterable object </li></ul><ul><li>Combine it with a LimitIterator and you can page the XML results </li></ul>$ab = file_get_contents('address-book.xml'); $page = 0; $limit = 10; foreach (new LimitIterator(new SimpleXMLIterator($ab), $page * $limit, $limit) as $person) { print &quot;$person->firstname $person->lastname: $person->email &quot;; }
  38. 38. RecursiveIterator Interface <ul><li>RecursiveIterator interface extends the existing Iterator interface </li></ul><ul><li>Two additional methods: </li></ul><ul><ul><li>hasChildren( ) </li></ul></ul><ul><ul><li>getChildren( ) These methods are used to navigate through sublists. </li></ul></ul>
  39. 39. RecursiveDirectoryIterator <ul><li>RecursiveIteratorIterator. This class is an Iterator for classes that implement the RecursiveIterator interface </li></ul>$dir = new RecursiveIteratorIterator( new RecursiveDirectoryIterator('/www/www.example.com'), true); foreach ($dir as $file) { print $file->getPathname( ) . &quot; &quot;; } /www/www.example.com/email.html /www/www.example.com/images /www/www.example.com/images/logo.gif
  40. 40. Is that it!!! @#$W**
  41. 41. Yes and No <ul><li>Lots of other iterators built in </li></ul><ul><li>http://in.php.net/spl </li></ul><ul><li>Sources in the ext/spl/examples </li></ul>

×