spl to the rescue - tek 09
DESCRIPTION
Given at tek 2009 this is the first version of my SPL to the Rescue talkTRANSCRIPT
Standard Tools for Everyday Programming
Community Heckling On twitter #tek09 (or #phptek) and #spldg
DG’s for drinking game (you’ll see why later)
IRC is open, I can see backlog – constructive criticism is good
Comment on http://joind.in/talk/view/186
No comments on hair, clothes, or my fat belly –constructive criticism is welcome ;)
I have a ProblemRecursively iterate through
directories
Find all .jpg files
Check last modified dates
Moved the ones older than two years to new location
How should I do this? Some nasty recursive use of scandir() to get my lists
Or PHP’s dir() function and looping
array_map() with a convoluted callback
I think I’m going to need a lot of code….
SPL to the Rescue! RecursiveDirectoryIterator
RecursiveIteratorIterator
FilterIterator
SplFileInfo
What fun tools we have!
And not the kind you kick out of IRC
What is SPL?tandard HP ibrary
A library of standard interfaces, classes, and functions designed to
solve common programming problems and allow engine
overloading.
That’s nice… in English please.What is SPL?1. Engine overloading hooks via interfaces
ArrayAccess, Countable, SeekableIterator
2. Classes that utilize the interfaces do cool things ArrayObject, RecursiveIterator, DirectoryIterator
3. Standard Class Implementations Exceptions, SplObserver and SplStorage
4. Functions to help with autoloading and objects spl_autoload_register(), spl_classes(), iterator_apply()
But… it’s an extension right? SPL is an extension
SPL is a core extension
SPL cannot be built shared
SPL should not be turned off
SPL is present in PHP since 5.0 (almost 5 years ago)
As of 5.3, SPL cannot be turned off without altering source
If you don’t have SPL, whoever built your PHP is an idiot
(or an evil genius – it’s HARD).
Helper functions from SPL to you
Autoload Magic spl_autoload() – default autoload implementation
spl_autoload_register() – add an autoload to the stack
spl_autoload_unregister() – remove an autoloader
spl_autoload_functions() – what’s on the stack
spl_autoload_extensions() – ext for spl_autoload()
spl_autoload_call() – load something through the stack
Isn’t __autoload good enough? Combining different libraries with different naming
conventions
Dealing with different types of files (templates, classes) in different locations
Changing autoload in use during runtime
Object Helper Functions class_implements()
class_parents()
spl_object_hash()
Why are these not in core?
I DON’T KNOW - GO ASK YOUR DAD!
Nothing but Templates
Exception Classes
LogicException
BadFunctionCallException
BadMethodCall
DomainExceptionInvalidArgumentE
xceptionLengthException
OutofRangeException
Exception Classes
RuntimeException
OutofBoundsException
OverflowException
RangeExceptionUnderflowExcepti
onUnexpectedValueE
xception
So what does SPL offer? A standard set of Exceptions that all inherit from
PHP’s Exception base class
A standard way to set up exceptions by what kind they are
Do I recommend it? Depends on how exceptions are used in your application.
Foreach is your bestest friend! Foreach an object today!
The iterator drinking game! Every time someone says the word iterator tonight,
take a drink
Start a conversation with me, and you’ll be gone in about five minutes
It’s the SPL drinking game (tonight at cocktail hour)
Iterators What the heck is an iterator? A design pattern that is a generic solution to the
problem of iterating over data in a consistent manner.
Access the elements of an aggregate object sequentially without exposing its underlying representation.
Why do I care? Ever need to go over a list of items returned from a
database (well, duh)
Or need to go over a list of items returned from a webservice?
Ever used foreach?
Foreach it baby! Foreach is your friend
iterators give your code consistent usage
and you can add more functionality
What else can you do with iterators?
Extend Iterators to do what you need
Chain Iterators: iteratoriteratoriteratoriterator
(that’s 5 shots)….
Meet the Iterator Interface
So how is it different?Array $ar= array(); Iterator $it = new Iterator;
can be rewound
reset($ar)
is valid unless the key is NULL
!is_null(key($ar))
Has a current value
current($ar)
Has keys
key($ar)
can move forward
next($ar)
Might be rewindable
$it->rewind()
should know if there is a value
$it->valid()
Might have a current value or key
$it->key()
$it->current()
Can move forward
$it->next()
An Iterator for every occasion RecursiveIterator
RecursiveIteratorIterator
OuterIterator
IteratorIterator
FilterIterator
RecursiveFilterIterator
ParentIterator
SeekableIterator
LimitIterator
GlobIterator
• CachingIterator
• RecursiveCachingIterator
• NoRewindIterator
• AppendIterator
• RecursiveIteratorIterator
• InfiniteIterator
• RegexIterator
• RecursiveRegexIterator
• EmptyIterator
• RecursiveTreeIterator
• ArrayIterator
See, the drinking game will be lots of fun….
Innie or an Outie? OuterIterator (interface)
Extends Iterator
Puts a wrapper around an iteratorinside
Has one additional method –getInnerIterator() that should be implemented
Loopety Loop RecursiveIterator
(interface)
Has two additional methods to implement
getChildren should return the sub-iteratorfor the current element – and it must return an object that implements recursiveIterator
hasChildren
Jumping ahead? SeekableIterator
(interface)
Additional method –seek(string $position)
Lets you jump to a specific spot to start iterating
Now on to classes Classes implement interfaces plus provide additional
functionality
Interfaces need you to fill in all the the required methods
You can implement multiple interfaces
You can’t extend multiple classes
Choose Wisely
FilterIterator Abstract Class
Has one method that must be implemented – accept –which should return true or false
File filtering example at the beginning used this
Highly useful for many types of iteration
FilterIterator OuterIterator Iterator Traversable
IteratorIterator Regular Class
Iterates an iterator – No I am not kidding
IteratorIterator OuterIterator Iterator Traversable
ArrayIterator Regular Class
Iterates an array – OR the public properties of an object! (neat trick – dirty trick)
ArrayIterator SeekableIterator Iterator TraversableArrayAccess and Countable too!
RecursiveIteratorIterator Regular Class
Like IteratorIterator only recursive to boot – still not kidding - but I don’t say it as cool as Marcus
RecursiveIteratorIterator OuterIterator Iterator Traversable
ParentIterator Regular Class
Filter out stuff without children
ParentIterator OuterIterator Iterator Traversable
LimitIterator Regular Class
Like mysql’s limit – pick your range and offset and foreach away!
LimitIterator OuterIterator Iterator Traversable
CachingIterator Regular Class
Manages another iterator by checking whether it has more elements each time using a hasNext() method
CachingIterator OuterIterator Iterator Traversable
RecursiveCachingIterator Regular Class
Just like caching iterator only – believe it or not –recursive!
RecursiveCachingIterator CachingIterator OuterIterator Iterator Traversable
DirectoryIterator Regular Class
Makes going through directories a snap
isDot, isFile – I love you
DirectoryIteratorSplFileInfo(extends)
Iterator Traversable
RecursiveDirectoryIterator Regular Class
Like, do it again… and again… and again… and…
DirectoryIterator(extends)
RecursiveIterator Iterator Traversable
Iterator Helper Functions iterator_apply() – like array_walk for your iterator
implementing objects
iterator_count() – count the items in your iterator (not quite the same as implementing countable::count)
iterator_to_array() – copy all the stuff from your iterator into a regular PHP array
Even Superman
doesn’t work alone
Is it an array? An object? Why… it’s both!
ArrayAccess Interface
ArrayObject A class, NOT an interface
It’s like arrayaccess on RedBull
The manual LIES – for a full list of everything you can do with arrayobject, see http://www.php.net/~helly/php/ext/spl/
Highlights exchangeArray
getArrayCopy (get your internally stored array)
Sorting methods ksort et al
Countable Interface you can
implement with any class (not iteratorspecific, but used a lot for it)
Implement the count method and you can use the count() PHP function on any object
SplObjectStorage This does not do what you think it does
Use objects as array keys, uniquely, with no collision issues (you might get them from spl_object_hash)
Remember you need the object to get the data back out, unless you’re simply iterating over the contents
Regular class, no need to extend and fill in methods
http://www.colder.ch/news/01-08-2009/34/splobjectstorage-for-a-fa.html
SPLFixedArray A fixed length, int key only array
Why? It’s FAST (very fast) because it stores data differently “under the hood” in C
Regular class, don’t need to extend and fill in any methods
5.3+
SplObserver and SplSubject Abstract classes for anything using an observer pattern
http://www.a-scripts.com/object-oriented-php/2009/02/21/the-observer-pattern/ - great common sense tutorial
If you do event/observers in your code, extending these two makes good sense
SplFileInfo fancy class for a file
all the file system functions in compact object form
getMTime == filemtime
openFile == fopen
Beyond arrays to the wild wild west
New and Shiny
SplDoublyLinkedList
SplStack SplQueue
More Data Structures
SplHeap
SplMaxHeap SplMinHeap
SplPriorityQueue
The Documentation Problem
http://elizabethmariesmith.com/2009/02/setting-up-phd-on-windows/ - you can write docbook on any platform!
Efnet - #php.doc channel
http://doc.php.net
[email protected] – mailing list
See me and start helping today!
Resources http://php.net/spl - spl docs
http://php.net/~helly/php/ext/spl - Doxygen docs
http://blueparabola.com/blog/spl-deserves-some-reiteration - some stuff about new data structures