• Like
  • Save
Iterators in PHP
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

Iterators in PHP

  • 21,265 views
Published

How to use and write our own Iterators in PHP

How to use and write our own Iterators in PHP

Published in Business , Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
  • 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
    Are you sure you want to
    Your message goes here
No Downloads

Views

Total Views
21,265
On SlideShare
0
From Embeds
0
Number of Embeds
5

Actions

Shares
Downloads
0
Comments
1
Likes
19

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