PHP5: SPL

Posted on March 16, 2011

The Standard PHP Library is “a collection of interfaces and classes that are meant to solve standard problems”. It’s technically an extension, but it’s included by default and can’t be disabled, so it’s basically part of PHP5.

Data Structures

The SPL provides some standard data structures, implemented as object-oriented classes. They all work as you’d expect.

There’s a generic doubly-linked list with stack (LIFO) and queue (FIFO) variations. There’s a generic heap (tree), and max-heap and min-heap variations. There is also a priority queue, implemented as a heap.

There is an array implementation called SplFixedArray. Unlike PHP’s built-in arrays, they have a fixed size and are indexed by integer, so they are like arrays in C and other languages. This lets the implementation be faster and have a smaller memory footprint.

Finally, there is SplObjectStorage, which lets you map objects to data. It sort of extends PHP’s built-in integer/string=>value mapping by allowing you to map objects. You can also ignore the mapping part and just store the objects as a set. A spl_object_hash() function is available if you want to build your own map objects.

Iterators

PHP5 gives us more flexibility over iterating over objects. By default, you can iterate over an object’s visible properties in a foreach, while, etc.

PHP adds an interface called Iterator that can be implemented and extended by an object. There is also an IteratorAggregate interface that you can use so you don’t have to implement all the required Iterator methods yourself. There’s a bunch of existing iterators — many of them are used in various extensions, but you can use them too.

Here’s an example using the DirectoryIterator to print out all the files in a directory:

$iterator = new DirectoryIterator(dirname(__FILE__));
while($iterator->valid())
{
  echo $iterator->getFilename() . "n";
  $iterator->next();
}

PHP also adds some functions for working with iterators:

Interfaces

I wrote about how interfaces work in the PHP5 OOP article. As with the iterators, PHP5 includes a set of interfaces that you can use and extend:

  • Iterator and IteratorAggregate were mentioned in the previous section
  • Countable — allows an object to be counted using the count() function
  • RecursiveIterator — object for iterating recursively
  • OuterIterator — iterator containing another iterator; for example, FilterIterator wraps the object you want to iterate over inside a filtering iterator
  • SeekableIterator — iterator with support for moving the iterator’s internal pointer to a specified position
  • SplObserver and SplSubject — used for implementing the object design pattern
  • ArrayAccess — allows an object to be accessed like an array (i.e., using the “[]” operator)
  • ArrayObject — uses ArrayAccess and other interfaces to add more array functionality to objects. It includes methods for counting, sorting, and serialization.
  • Serializable — lets you customize the serialization of an object. Using this interface stops the object from using __sleep() and wakeup().

This article has good info and examples about some of these. These interfaces and iterators give us a powerful ability to extend objects.

Exceptions

I wrote about how exceptions work in a previous article. PHP defines a bunch of exceptions for its own purposes, but they cover most situations and can be used by anyone.

The hierarchy isn’t documented well, but you can see it in this comment and in charts elsewhere. Basically there are 2 main kinds of exceptions: runtime errors and program logic errors. These are pretty broad errors, so there are further types that you can throw:

  • BadFunctionCallException or BadMethodCallException — if a callback refers to an undefined function or if some arguments are missing
  • InvalidArgumentException — if an argument does not match with the expected value
  • LengthException — if a length is invalid
  • OutOfBoundsException — if a value is not a valid key (runtime)
  • OutOfRangeException — when an illegal index was requested (compile time)
  • OverflowException — when you add an element into a full container
  • UnderflowException — when you try to remove an element of an empty container
  • RangeException – range errors during program execution (runtime). Normally this means there was an arithmetic error other than under/overflow.
  • DomainException — if a value does not adhere to a defined valid data domain (compile time)
  • UnexpectedValueException — if a value does not match with a set of values. Typically this happens when a function calls another function and expects the return value to be of a certain type or value not including arithmetic or buffer related errors.

File Handling

PHP5 has some classes for working with files.

The SplFileInfo class is basically a collection of methods to get filesystem-level info about a file. Here’s an example:

$info = new SplFileInfo('example.php');
if ($info->isFile())
{
  echo $info->getRealPath();
}

The SplFileObject class is for working with files. It is basically an object-oriented interface of the existing procedural functions for reading from and writing to files. It extends the SplFileInfo class, so all of those methods are available too. (SplFileInfo also has an openFile() method for converting an SplFileInfo object into a SplFileObject object.)

There is also a SplTempFileObject class that extends SplFileObject for when you need a temporary file.

Miscellaneous Functions

Finally, the PHP SPL adds some additional functions for getting class information:

  • class_implements() — returns an array of the interfaces that a class or object (and its parents) implement
  • class_parents() — returns an array of the parent classes for a class or object
  • spl_classes() — returns an array of all SPL classes

Leave a Reply

  1.  

    |