Share
Embed
SPL: The Missing Link in Development
The Standard PHP Library (SPL) is the php extension that so many developers pass on out of lack of knowledge, NO MORE! Jake Smith will introduce you to the benefits of utilizing SPL features (iterators, interfaces, exceptions and autoloader). Also, continuing from last months talk he will introduce some new PHP 5.3 SPL classes.
jakefolio
September 26, 2011
Transcript
44 slides
-
What is SPL? • A library of standard interfaces, classes,
and functions designed to solve common programming problems and allow engine overloading. Definition Source: http://elizabethmariesmith.com/ -
SPL Background • Provides Interfaces, Classes and Functions • As
of PHP 5.3 you can not turn off SPL • Poor documentation root of poor adoption. -
Before SPL Autoload set_include_path(dirname(__FILE__) . '/lib' . PATH_SEPARATOR . get_include_path());
function __autoload($class_name) { $path = dirname(__FILE__) . '/lib/' . str_replace('_', '/', strtolower ($class_name)) . '.php'; if (file_exists($path)) { require $path; } else { die('Class ' . $path . ' Not Found'); } } <?php class Form_Element_Text extends Form_Element { public function __construct($name = '', $attrs = array()) { $this->_name = $name; $this->_attrs = $attrs; } Class Name -
Autoloading w/SPL <?php /*** nullify any existing autoloads ***/ spl_autoload_register(null,
false); /*** specify extensions that may be loaded ***/ spl_autoload_extensions('.php, .class.php'); /*** class Loader ***/ function classLoader($class) { $filename = strtolower($class) . '.class.php'; $file ='classes/' . $filename; if (!file_exists($file)) { return false; } include $file; } /*** register the loader functions ***/ spl_autoload_register('classLoader'); Example Source: http://www.phpro.org/tutorials/SPL-Autoload.html -
Multiple Autoloaders <?php /*** nullify any existing autoloads ***/ spl_autoload_register(null,
false); spl_autoload_register(array('Doctrine_Core', 'autoload')); spl_autoload_register(array('Doctrine_Core', 'modelsAutoload')); -
Multiple Autoloaders <?php class Doctrine_Core { public static function autoload($className)
{ if (strpos($className, 'sfYaml') === 0) { require dirname(__FILE__) . '/Parser/sfYaml/' . $className . '.php'; return true; } if (0 !== stripos($className, 'Doctrine_') || class_exists($className, false) || interface_exists($className, false)) { return false; } $class = self::getPath() . DIRECTORY_SEPARATOR . str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php'; if (file_exists($class)) { require $class; return true; } return false; } -
iterator_to_array • Takes an iterator object, an object that implements
Traversable • All iterators implement Traversable -
spl_object_hash • MD5 hash of internal pointer • When objects
are destroyed their object hash is released • Object Hash ID can/will be reused after destruction. -
ArrayObject • Allows objects to act like arrays • Does
not allow usage of array functions on object • Built in methods: ksort, usort, asort, getArrayCopy -
SplFileInfo • Object that returns information on Files/ Folders •
isDir, isFile, isReadable, isWritable, getPerms (returns int), etc. Example Source: http://us3.php.net/manual/en/class.splfileinfo.php -
SPL Interfaces • ArrayAccess • Iterator • RecursiveIterator • Countable
• SeekableIterator • SplSubject/SplObserver -
Observer Pattern (SPL) • Great for applying hooks • Exception
Handling • User Authentication -
SplSubject <?php class ExceptionHandler implements SplSubject { private $_observers =
array(); public function attach(SplObserver $observer) { $id = spl_object_hash($observer); $this->_observers[$id] = $observer; } public function detach(SplObserver $observer) { $id = spl_object_hash($observer); unset($this->_observers[$id]); } public function notify() { foreach($this->_observers as $obs) { $obs->update($this); } } public function handle(Exception $e) { $this->exception = $e; $this->notify(); } } Example Source: http://devzone.zend.com/article/12229 -
SplObserver Class Mailer implements SplObserver { public function update(SplSubject $subject)
{ // Do something with subject object } } // Create the ExceptionHandler $handler = new ExceptionHandler(); // Attach an Exception Logger and Mailer $handler->attach(new Mailer()); // Set ExceptionHandler::handle() as the default set_exception_handler(array($handler, 'handle')); Example Source: http://devzone.zend.com/article/12229 -
ArrayAccess • OffsetExists - Values exists for key, returns boolean
• OffsetSet - Set value for key • OffsetGet - Return value for key • OffsetUnset - Remove value from array • Note that if the array is numerically indexed, a call to array_values() will be required to re-index the array if that is the behaviour required. Example Source: http://www.phpro.org/tutorials/Introduction-to-SPL-ArrayAccess.html -
ArrayAccess Example <?php class book implements ArrayAccess { public $title;
public $author; public $isbn; public function offsetExists( $offset ) { return isset( $this->$offset ); } public function offsetSet( $offset, $value) { $this->$offset = $value; } public function offsetGet( $offset ) { return $this->$offset; } public function offsetUnset( $offset ) { unset( $this->$offset ); } } Example Source: http://www.phpro.org/tutorials/Introduction-to-SPL-ArrayAccess.html -
Iterator • Provides basic iterator functionality (foreach) • Interface requires
the following methods • current(), key(), next(), rewind(), valid() -
Recursive Iterator • A foreach only goes top level, but
many times you need to dig deeper • Recursive Iterator extends Iterator and requires hasChildren() and getChildren() -
Countable • Internal Counter <?php class loopy { public function
count() { static $count = 0; return $count++; } public function access() { $this->count(); // Method logic } } -
SeekableIterator • Other iterators must start at beginning of an
array, but seekable allows you to change iteration start point. <?php class PartyMemberIterator implements SeekableIterator { public function seek($index) { $this->rewind(); $position = 0; while ($position < $index && $this->valid()) { $this->next(); $position++; } if (!$this->valid()) { throw new OutOfBoundsException('Invalid position'); } } Example Source: http://devzone.zend.com/article/2565 -
ArrayIterator • Implements: Iterator, Traversable, ArrayAccess, SeekableIterator, Countable • Used
to Iterate over ArrayObject or PHP array -
ArrayIterator <?php // Using While /*** create a new object
***/ $object = new ArrayIterator($array); /*** rewind to the beginning of the array ***/ $object->rewind(); /*** check for valid member ***/ while($object->valid()) { /*** echo the key and current value ***/ echo $object->key().' -> '.$object->current().'<br />'; /*** hop to the next array member ***/ $object->next(); } // Using Foreach $object = new ArrayIterator($array); foreach($object as $key=>$value) { echo $key.' => '.$value.'<br />'; } Example Source: http://www.phpro.org/tutorials/Introduction-to-SPL.html#6 -
LimitIterator • Used similar to Limit in SQL <?php //
Show 10 files/folders starting from the 3rd. $offset = 3; $limit = 10; $filepath = '/var/www/vhosts/mysite/images' $it = new LimitIterator(new DirectoryIterator($filepath), $offset, $limit); foreach($it as $r) { // output the key and current array value echo $it->key().' -- '.$it->current().'<br />'; } -
DirectoryIterator • If you’re accessing the filesystem this is the
iterator for you! • Returns SplFileInfo object -
DirectoryIterator <?php $hdl = opendir('./'); while ($dirEntry = readdir($hdl)) {
if (substr($dirEntry, 0, 1) != '.') { if(!is_file($dirEntry)) { continue; } $listing[] = $dirEntry; } } closedir($hdl); foreach($listing as $my_file) { echo $my_file.'<br />'; } <?php try { /*** class create new DirectoryIterator Object ***/ foreach ( new DirectoryIterator('./') as $Item ) { echo $Item.'<br />'; } } /*** if an exception is thrown, catch it here ***/ catch(Exception $e) { echo 'No files Found!<br />'; } -
RecursiveDirectory Iterator • Move out of the top level and
get all children files/folders <?php $dir = '/Users/jsmith/Sites/vhosts/test.local/wwwroot'; $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir)); // could use CHILD_FIRST if you so wish foreach ($iterator as $file) { echo $file . "<br />"; } -
GlobIterator (5.3) • Very Similar to DirectoryIterator • Only use
if you want to convert old glob code into an iterator object • returns SplFileInfo Objects -
SPL Exceptions • Logic Exception • BadFunction • BadMethodCall •
InvalidArgument • OutOfRange • RuntimeException • OutOfBounds • Range • UnexpectedValue • Underflow Example Source: http://www.php.net/manual/en/spl.exceptions.php -
SplFixedArray • Array with pre-defined dimensions • Shows great speed
for setting and retrieving • If you change Array dimensions, it will crawl. -
SplHeap • Automatically reorder after insert, based off of compare()
method • Extract is similar to array_shift() • Great memory usage! Example Source: http://www.slideshare.net/tobias382/new-spl-features-in-php-53 -
SplMaxHeap • Subclass of SplHeap • When you extract() a
value it will return in order from greatest to least <?php $heap = new SplMaxHeap(); $heap->insert('b'); $heap->insert('a'); $heap->insert('c'); echo $heap->extract()."\n"; echo $heap->extract()."\n"; echo $heap->extract()."\n"; // OUTPUT: // c // b // a Example Source: http://www.alberton.info/php_5.3_spl_data_structures.html -
SplMinHeap • Subclass of SplHeap • When you extract() a
value it will return in order from least to greatest <?php $heap = new SplMinHeap(); $heap->insert('b'); $heap->insert('a'); $heap->insert('c'); echo $heap->extract()."\n"; echo $heap->extract()."\n"; echo $heap->extract()."\n"; // OUTPUT: // a // b // c Example Source: http://www.alberton.info/php_5.3_spl_data_structures.html -
SplDoublyLinkedList • Do not know size of list/array • Can
only be read sequentially • Less processing power required, on large data sets provides better memory usage -
Useful Links • SPL in 5.3 • http://www.alberton.info/ php_5.3_spl_data_structures.html •
http://www.slideshare.net/tobias382/new-spl-features-in- php-53 • Intro to SPL • http://www.phpro.org/tutorials/Introduction-to-SPL.html • http://www.slideshare.net/DragonBe/spl-not-a-bridge-too- far -
Thanks for listening! Contact Information [t]: @jakefolio [e]: [email protected] [w]:
http://www.jakefolio.com [irc]: #dallasphp