2. Whoami
http://elizabethmariesmith.com
Work at http://omniti.com
PHP-GTK
PECL cairo
WinGui
Bad bad bad things to PHP (on windows)
Twitter @auroraeosrose
IRC auroraeosrose
3. Community Heckling
On twitter #zendcon
IRC is open, I can see backlog – constructive criticism
is good
Comment on http://joind.in/talk/view/934
No comments on hair, clothes, or my fat belly –
constructive criticism is welcome ;)
5. I have a Problem
Recursively iterate through
directories
Find all .jpg files
Check last modified dates
Move the ones older than two years
to new location
6. 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
Glob + foreach madness
I think I’m going to need a lot of code….
7.
8. SPL to the Rescue!
RecursiveDirectoryIterator
RecursiveIteratorIterator
FilterIterator
SplFileInfo
What fun tools we have!
11. What is SPL?
tandard HP ibrary
A library of standard interfaces,
classes, and functions designed to
solve common programming
problems and allow engine
overloading.
12. Zod says – kneel before me!
No… wait
Explain in English Now!
Because no one understood a
word of that…
13. What is SPL?
1. Engine overloading hooks via interfaces
Countable, SeekableIterator, RecursiveIterator
2. Classes that utilize the interfaces
ArrayObject, MultipleIterator, DirectoryIterator
3. Standard Class Implementations
Exceptions, SplStorage
4. Functions to help with autoloading and objects
spl_autoload_register(), spl_classes(), iterator_apply()
14. 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).
15. Stuff that’s NOT in SPL
Engine Defined interfaces you should know about!
ArrayAccess
Serializable
Iterator
IteratorAggregate
Traversable
17. Built in Autoloader
spl_autoload() – default autoload implementation
spl_autoload_extensions() – ext for spl_autoload()
18. Autoload Stack
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_call() – load something through the
stack
19. 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
20. Object Helper Functions
class_implements()
class_parents()
spl_object_hash()
Why are these not in core?
Zod does not know… Zod demands you kneel!
24. 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 kind
Do I recommend it? Depends on your application.
26. 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.
27. 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? (or its slower, lesser cousin for?)
28. Foreach it baby!
Foreach is your friend
iterators give your code consistent usage
and you can add more functionality
29. You can also…
Extend Iterators to do what you need
Chain Iterators: iteratoriteratoriteratoriterator
31. So how is it different?
Array $ar= array(); Iterator $it = new Iterator;
can be rewound Might be rewindable
reset($ar) $it->rewind()
is valid unless the key is NULL should know if there is a value
!is_null(key($ar)) $it->valid()
Has a current value Might have a current value or
current($ar) key
Has keys $it->key()
key($ar) $it->current()
can move forward Can move forward
next($ar) $it->next()
34. Innie or an Outie?
OuterIterator (interface)
Extends Iterator
Puts a wrapper around an iterator
inside
Has one additional method –
getInnerIterator() that should be
implemented
35. Loopety Loop
RecursiveIterator
(interface)
Has two additional
methods to implement
getChildren should
return the sub-iterator
for the current element
– and it must return an
object that implements
recursiveIterator
hasChildren
36. Jumping ahead?
SeekableIterator
(interface)
Additional method –
seek(string $position)
Lets you jump to a
specific spot to start
iterating
37. 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
38. 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
39. IteratorIterator
Regular Class
Stick in something that implements traversable
Voila – instant iterator
IteratorIterator OuterIterator Iterator Traversable
40. ArrayIterator
Regular Class
Iterates an array – OR the public properties of an
object! (neat trick – dirty trick)
ArrayAccess and
ArrayIterator SeekableIterator Iterator Traversable
Countable too!
43. LimitIterator
Regular Class
Like mysql’s limit – pick your range and offset and
foreach away!
LimitIterator OuterIterator Iterator Traversable
44. CachingIterator
Regular Class
Manages another iterator by checking whether it has
more elements each time using a hasNext() method
CachingIterator OuterIterator Iterator Traversable
45. RecursiveCachingIterator
Regular Class
Just like caching iterator only – believe it or not –
recursive!
RecursiveCachingIterator CachingIterator OuterIterator Iterator Traversable
46. DirectoryIterator
Regular Class
Makes going through directories a snap
isDot, isFile – I love you
SplFileInfo
DirectoryIterator Iterator Traversable
(extends)
48. RegexIterator
Regular Class
Filter an iterator by a regex
Pick how you want it to match
FilterIterator IteratorIterator
Iterator Traversable
(extends) (extends)
49. Iterator Helper Functions
iterator_apply() – like array_walk
iterator_count() – count the items
iterator_to_array() – run the iterator, put results in
array
52. ArrayObject
A class, NOT an interface
It’s like arrayaccess on RedBull
Highlights
exchangeArray
getArrayCopy (get your internally stored data)
Sorting methods
ksort et al
53. Countable
Interface you can
implement with any
class (not iterator
specific, but used a lot
for it)
Implement the count
method and you can use
the count() PHP
function on any object
54. 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
55. 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
56. SplFileInfo
fancy class for a file
all the file system functions in compact object form
getMTime == filemtime
openFile == fopen
59. Arrays and Objects
General purpose containers
Have same C structure (HashTable)
holding the data underneath
C has other ways of holding data that can
be faster when scaled
60. Lies, damn Lies, and statistics
Great set of benchmarks by Matthew Turland
http://www.slideshare.net/tobias382/new-spl-
features-in-php-53
Generally, not useful for small amounts of data, highly
useful for large (think thousands) of pieces of data
61. SPLFixedArray
A fixed length, int key only array
Why? It’s faster because it stores data differently
“under the hood” in C
Regular class, don’t need to extend and fill in any
methods
64. Implementations
Stack does LIFO
Queue does FIFO
See improvements when constantly updating the stack
Less improvement seen with a straight stick everything
in and remove everything at once
67. Implementations
MinHeap - key 1 < or = key 2
MaxHeap – key 1 > or = key 2
PriorityQueue – constantly sorting by priority as new
things are put in
68. 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
phpdoc@lists.php.net – mailing list
See me and start helping today!
69. Resources
http://php.net/spl - spl docs
http://php.net/~helly/php/ext/spl - Doxygen docs
http://www.alberton.info/articles/filter/tag/SPL -
some great datastorage related tutorials
http://www.phpro.org/tutorials/Introduction-to-
SPL.html - more great SPL tutorials
auroraeosrose@php.net
Hinweis der Redaktion
Spl is the coolest extension that nobody uses.This talk isn’t heavy on code but is heavy on ideas and “how to, when to, quit reinventing the wheel”Also heavy on “for little things, use the little solutions”This is NOT a tutorial talk (although I think spl needs one) with reams of code to see “how things work” – this is not a “how” talk as much as a “what” and “when”Marcus Borger the man of the hour for SPL – borrows heavily from java concepts Don’t forget the warning about use 5.2.1+ a lot of the cool and nifty stuff here is only available in newer versions35 seconds
Brief who am I, why am I doing this talk, how to get ahold of meAnd a “what is auroraeosrose” quick talk
So let’s learn about splWarning about this talk – I’m going to make you participate, and there will be very little code shownAt the end I’ll give some links to some fabulous SPL tutorials you should ALL GO DOThis really should be a tutorial because there is SOOO MUCH in spl
Let’s set the scene – I have a bunch of old stuff that needs to be taken out and archived from a random annoying structure.I have pretty firm criteria on what I need to do, just need a fast way to do it1 min
Let the crowd give ideas in addition to this – (no spl stuff)
Ceiling cat is angry (thanks to Chris for the lovely pic) 10 seconds or so, with kitty noises
But we already have the tools for all of this?Explain the tools, explain what they do
Code to actually do it
Should hit the 5 minute mark hereWhy don’ t you use spl is the question of the dayAnd “who uses spl” – 10 seconds or so
Definition of Standard (Merriam Webster) - 4: something set up and established by authority as a rule for the measure of quantity, weight, extent, value, or qualityLibrary: a: a place in which literary, musical, artistic, or reference materials (as books, manuscripts, recordings, or films) are kept for use but not for sale b: a collection of such materials2 a: a collection resembling or suggesting a library <a library of computer programs> <wine library>In other words… a collection
More joke joke time
SPL is – cool engine hooksClass that use the hooksStandard classesHelper functions
I can’t depend on an extension that might not be presentUm… if spl is not present – urdoin it rong
Traversable is an odd duck – it does… um… nothingHowever, if you’re writing extensions, you can use it to signify your data can be foreached but NOT implementIteratorNote: serializable classes no longer support sleep and wakeup, instead they have serialize and unserialize – very powerful thatArray access and iterator/iterator aggregate we’ll talk about later
Hit 8 minute mark here – Start with some helper functions before I get to the fun iterator stuff
Spl_autoload is a default autoloader implementationYou tell it what extensions to look for by using spl_autoload_extensionsIf you use .class.php or .inc or whatever you can add them to the extensions that are looked forJust like with include_path, performance is affected by the first thing in the extensions list (if you have all .class.php files, use that)If you use namespaces, it’ll map them too
Talk a little bit about they accept standard PHP callbacks for autoloaders - $this ‘method’ syntax works fine – spl_autoload_call will “force load” a classThis behaves more like a QUEUE than a STACK, since the registry is accessed in FIFO order. The autoloaders are attempted in the order they are defined.The docs suckAutoload is [mixed autoload_function = "spl_autoload" [, throw = true [, prepend]]] – prepend is new for 5.3Do throw tells how error handling is done for the autoload adding – if it’s true, exceptions will be thrown if badcallables are passed in, otherwise you just get false as a return valuePrepend does exactly what it saysIf you pass in an already existing item it doesn’t error, instead it returns true
Isn’t autoload evil? Eh, who cares, highlyhighly usefulShort discussion on autoload itselfNote that you need to register any __autoload if using spl_autoload_register
Spl_object_hash is new and improved now as well in 5.3 – you’ll no longer get collisions and the key is truly unique (but it’s still slow)
Exceptions are exceptions2.Never use exceptions for control flow3.Never ever use exceptions for parameter passing10 minute mark
Anything that could have been detected at compile time, during application design, or by careful code reviewPerfect for libraries to tell your consumer “you’re being stupid”
Anything that is unexpected during runtimeBase Exception for all database extensions
Something like ZF or Pear/PEAR2 that is package and package dependant exception based, no… PHP has generally not gone this (the JAVA route) with Exceptions
12 minute mark
Iterators make codeReadable Easy to understand Testable Easy to refactorAsk audience questions about why they think an iterator is useful – and when they might want to use one15 minute mark
Iterators make codeReadable Easy to understand Testable Easy to refactorAsk audience questions about why they think an iterator is useful – and when they might want to use one15 minute mark
Talk a little bit about foreach and how simple it can make complicated data access, filtering, and recursive iteration
Talk a little bit about foreach and how simple it can make complicated data access, filtering, and recursive iteration
Implementing the iterator interface, and how it’s not in SPL but in PHP proper – it’s an engine level hookHow is this called when foreach is used?RewindValidCurrent or keynext(make them all repeat until it’s memorized – they’ll thank me for it later)Brief note on traversable – you can’t implement it in userland it and only marcus knows why it exists
Brief note on array vs. iterator and how they differ
Quick not on how may iterator choices there are before we look at some individiual ones
20 minute mark
Wrapping up iterators (chaining iterators basically) is what a lot of the iterator classes use
the sub iterator for the current element Note:The returned object must implement RecursiveIterator.
24 minutes to here – about the halfway point for the talk
Warning – this might have unintended consequencesHere’s a hint – pdostatement implements traversable
this Iterator can manage both native PHP arrays and the public properties of an object
this helps you do cool stuff like "flatten" a hierarchical data structure so that you can loop through it with a single foreach statement, while still preserving knowledge of the hierarchy. This class could be very useful for rendering tree menus, for example.
when using a ResursiveIterator, the ParentIterator allows you to filter out elements that do not have children. If, for example, you have a CMS in which documents can be placed anywhere under a tree of categories, the ParentIterator would allow you to recurse the tree but display only the "category nodes", omitting the documents that appear under each category.
this class allows you to specify a range of elements to Iterator over, starting with a key offset and specifying a number of elements to access from that point. The concept is the same as the LIMIT clause in MySQL.
this manages another Iterator (which you pass to its constructor). It allows you to check whether the inner Iterator has more elements, using the hasNext() method, before actually advancing with the next() method. Personally, I'm not 100% sure about the name; perhaps LookAheadIterator would be more accurate?
this is largely the same as the CachingIterator, but allows iteration over hierarchical data structures.the name; perhaps LookAheadIterator would be more accurate?
to iterate over a directory in a file system, this Iterator provides a bunch of useful methods like isFile() and isDot() that save a lot of hassle.
this class allows iteration over a directory structure so that you can descend into subdirectories.
This is an AWESOME iterator – stick a directory or glob iterator in here and have a great time
A few useful tools to make life with iterators more funfor your iterator implementing objectsIterator count is not the same as countable in your iterator (not quite the same as implementing countable::count)copy all the stuff from your iterator into a regular PHP array
12 minute mark
Array object is a really easy way to do an arrayaccess – just override what you need to change (like for a readonly array or other fun)There are also flags you can pass to the constructor to make var_dump work differently, or to have $iterm[‘foo’] and $item->foo
How would this be useful?Notice this is NOT the same as a function you’ll see later
Poor choice for any kind of registry or $object to scalar key mappingsThere are some cool new features in 5.3 with arrayaccess magicIt’s more of a “map” or “set” – the name is not quite rightYou can use it as a map (objects as array keys) or as a set (unique set of objects)
Talk a bit about event listening, observers
This is just an easy way to deal with file stuff – for all of you whining about not having a file object in PHP – yes we do!
Data structures are new in 5.3 and compliments of Etienne Kneuss who did most of the work
Why are data structures useful? They scale fantasticallyMatt did a great great set of benchmarks on this
Estimates are 30% faster than a regular array – but remember using the size changing methods can eat a lot of time. Really only useful if you’re NOT going to be changing the size of the array a lotRemember you aren’t going to see big returns over a regular array until you’re hitting the 10,000 item mark
Quick C discussion on stacks Put it on top, take off the top (or put it on bottom, take it off the top)Double linked list points forward to the next spot and backwards to the previous spot
This is not going to be a computer science lesson – basically these use different “stuff” underneath to store your data (instead of a hashtable) what does this mean for you? Your stacks and queues might be faster – then again, they might not. The neat thing is being able to change your iteration direction (FIFO or LIFO) when using them, and the queue can optionally delete items as it iterates them – makes common tasks much fasterNote: you CAN change the direction of iteration for doublylinkedlists – you can NOT change the direction for splstack and queue
Doubly linked lists, stack and queue have a stack as the underlying storage structureLast in first out and first in first out – difference between array_pop and array_unshiftPush and pop (or enqueue, dequeue for the splqueue)Because of the algorithms used underneath – if you need FIFO for anything over 10,000 items or so, queue is going to show BIG improvements in speedStack? Not quite so much, stack works best when used in a manner that’s constantly being updated, otherwise you won’t see that much improvement in speed – although remember that you can have it delete items as well, which DOES make it fasterNote you can’t change queue’s direction either, but can also change it to keep or remove on iteration
specialized tree-based data structure that satisfies the heap property: if B is a child node of A, then key(A) ≥ key(B). This implies that an element with the greatest key is always in the root node, and so such a heap is sometimes called a max-heap. (Alternatively, if the comparison is reversed, the smallest element is always in the root node, which results in a min-heap.)
Priority queue uses a heap internally, but does not actually extend splheapBlame the developers – I doThis kind of stuff is most useful if you’re iterating and changing the data inside at the same timeSending lots of emailsEvent messagingSms – queuing up web service requests
You don’t see great returns on these until you hit the 1,000 or so mark… then it’s phenomenal
PHP documentation is entirely community drivenWe need volunteers – anyone can do PhD and docbook!Docs are MUCH MUCH better than they were – several new volunteers have made a BIG difference!You can be the new doc superstar ;)