Tag Archives: Standard PHP Library

SPL Countable

Introduction

Allows the object to be used in the PHP count() function. Even on PHP 5.0, it can still be used, if called as a class method.

Its purpose is best served in iterators or classes who elements are dynamic.

Interface

It only has one method that needs to be implemented, which is count().

interface Countable
{
    function count();
}

Usage Example

The example given is the not the normal practice and shouldn’t be used in real world applications.

class CountableObject implements Countable
{
    private $count;

    function __construct($count = 10)
    {
        $this->count = (int) $count;
    }

    function count()
    {
        return $this->count;
    }
}

If the user is using PHP 5.0, then they can still get the amount of elements.

$countable = new CountableObject(20);
echo $countable->count();

If the user has PHP 5.1 or above, then they can use the magic the interface provides.

$countable = new CountableObject(20);
count($countable);

Iterator Example

This is how you really should use the countable interface in real world applications.

References

Official Countable Documentation – From offical SPL documentation site.

Possibly Related Posts:


SPL Iterator Helper Functions

Introduction

These PHP 5.1 functions are to help handle Iterators.

There is no current information on the speed benchmarks of these functions compared to userland functions. These functions are C implementations, so one could assume they would be quicker.

Iterator Count

Counts the elements in any Iterator. Clones the Countable interface functionality for Iterators that don’t implement Countable.

$array = array('key1' => 'value1', 'key2' => 'value2');

echo iterator_count(new ArrayIterator($array));

Iterator To Array

Copies an Iterator to an array.

$array = array('key1' => 'value1', 'key2' => 'value2');

$newarray = iterator_to_array(new ArrayIterator($array));

Possibly Related Posts:


SPL IteratorAggregate

Introduction

Iterator Aggregation allows you to develop without rewriting a lot of the same code for classes. It is simple to implement with only one method in the interface. The method getIterator must return an Iterator object for it to work in foreach.

Interface

interface IteratorAggregate
{
   function getIterator();
}

Example

You can aggregate to PHP extensions that implement a iterator object. If you need to pass XML, you can create a new SimpleXML class giving XML iteration without having to implement it yourself.

class XmlPageViewer implements IteratorAggregate
{
    // My Methods here	 

    public function getIterator()
    {
        return new SimpleXMLElement($this->xml);
    }
}

Possibly Related Posts:


SPL Iterator

Introduction

The SPL Iterator allows for an object to be used in foreach loops.

foreach($object as $current)
{
    // Do Stuff.
}

Iterator Interface

interface Iterator
{
    function key();

    function current();

    function next();

    function valid();

    function rewind();
}

The execution path of the Iterator is as follows:

  1. Rewind() : Only called at the start of the Iteration and won’t be called until it is used in another foreach loop.
  2. Next()
  3. Valid()
  4. Current()
  5. Key() : Called Last because it is ”Optional”.

Rewind

For every foreach loop that you use the Iterator Object, rewind will be called to reset the elements. This method is called before the iteration starts. For example, it is like this.

$iterator->rewind();

while($iterator->valid())
{
    $key = $iterator->key();
    $current = $iterator->current();

    $iterator->next();
}

Except, you only have to give the variables for the key and current. Saves a lot of work in the long run.

Next

You don’t have to check whether there is another element after the current one, do the checking in the valid method. Just move to the next element.

Valid

Return true if there is a ”’current”’ element available or false when the end has been reached.

Current

Most used method and you can return any information that the user needs here. Don’t return multiple elements for the user.

Key

The key entry is optional in the foreach loop, so if you are going to use it to return data, you should specify in the manual. Most likely candidates for key are if you have multiple levels of iteration

foreach($iterator as $key => $currentObj)
{
    echo $key;
    foreach($currentObj as $key => $current)
    {

    }
}

Others are for returning the number of iterations that were preformed or what number the row is at. I used it to return the table name for one project. Carefully consideration should be taken for what is returned in the key method. Return nothing and only use current if you are unsure.

Examples

”’There is no guarantee that the code is functional.”’

Array Iterator

class MyArrayIterator implements Iterator
{
    protected $dataStore = null;

    // Array hinting was added in 5.1.x,
    // in PHP 5.0.x, is_array($data) should be used
    public function __construct(array $data)
    {
        if(is_array($data)) { // For PHP 5.0.x
            $this->dataStore = $data;
        }
    }

    public function key()
    {
        return key($this->dataStore);
    }

    public function current()
    {
        return current($this->dataStore);
    }

    public function next()
    {
        return next($this->dataStore);
    }

    public function rewind()
    {
        return reset($this->dataStore);
    }

    public function valid()
    {
        // When Next passes over the end of the array,
        // current() should return false. Needs to be tested.
        return (bool) $this->current();
    }
}

Mysql Iterator

class MysqlIterator implements Iterator
{
    protected $row = null;
    protected $query = null;

    public function __construct($query)
    {
        if(is_string($query)) {
            $this->query = mysql_query($query);
        } else if(is_resource($query)) {
            $this->query = $query;
        }
    }

    public function key() { } // Not Implemented

    public function current()
    {
        if($this->row != null)
        {
            return $this->row;
        }
    }

    public function next()
    {
        $this->row = mysql_fetch_assoc($this->query);
        return $this->row;
    }

    public function rewind()
    {
        $this->row = mysql_data_seek($this->query, 0);
        return $this->row;
    }

    public function valid()
    {
        if($this->row == false) {
            return false;
        }

        return true;
    }
}

Possibly Related Posts: