Home arrow PHP arrow Page 4 - Implementing the Countable SPL Interface

The full source code for the MySQLi_ResultWrapper class - PHP

In this third part of a seven-part series on the Iterator, Countable and ArrayAccess SPL interfaces, I give the MySQLi_ResultWrapper class developed in the previous part the capability of counting the number of rows contained in a given result set. I'll do that by implementing the "count()” method declared by the Countable interface. Doing this will make it possible to use an instance of the class to traverse data sets and count records as if they were plain PHP arrays, which is quite appealing to client code that works with the class’s API.

TABLE OF CONTENTS:
  1. Implementing the Countable SPL Interface
  2. Review: implementing the Iterator interface
  3. Counting rows in result sets with the Countable SPL interface
  4. The full source code for the MySQLi_ResultWrapper class
By: Alejandro Gervasio
Rating: starstarstarstarstar / 2
March 30, 2010

print this article
SEARCH DEV SHED

TOOLS YOU CAN USE

advertisement

Undeniably, the best way to understand how the prior “MySQLi_ResultWrapper” class can be an implementer of both the Iterator and Countable PHP 5 interfaces is by examining its full source code. Thus, below you'll find the complete definition of this class, including the “count()” method that you saw in the previous segment. Here it is:

class MySQLi_ResultWrapper extends MySQLi_Result implements Iterator, Countable

{

    private $_pointer = 0;

   

   // fetch row as an object

    public function fetchObject()

    {

        if (!$row = $this->fetch_object())

        {

            return NULL;

        }

        return $row;

    }

   

    // fetch row as an associative array

    public function fetchAssocArray()

    {

        if (!$row = $this->fetch_assoc())

        {

            return NULL;

        }

        return $row;

    }

   

    // fetch row as an enumerated array

    public function fetchNumArray()

    {

        if (!$row = $this->fetch_row())

        {

            return NULL;

        }

        return $row;

    }

   

    // fetch all rows

    public function fetchAll($type = MYSQLI_ASSOC)

    {

        if ($type !== MYSQLI_ASSOC AND $type !== MYSQLI_NUM AND $type !== MYSQLI_BOTH)

        {

            $type = MYSQLI_ASSOC;

        }

        if (!$rows = $this->fetch_all($type))

        {

            return NULL;

        }

        return $rows;  

    }

   

    // get definition information on fields

    public function fetchFieldsInfo()

    {

        if (!$fieldsInfo = $this->fetch_fields())

        {

            throw new Exception('No information available for table fields.');

        }

        return $fieldsInfo;

    }

   

    // get definition information on next field

    public function fetchFieldInfo()

    {

        if (!$fieldInfo = $this->fetch_field())

        {

            throw new Exception('No information available for current table field.');   

        }

        return $fieldInfo;

    }

   

    // move pointer in result set to specified offset

    public function movePointer($offset)

    {

        $offset = abs((int)$offset);

        $limit = $this->num_rows - 1;

        if ($limit <= 0 OR $offset > $limit)

        {

            return NULL;

        }

        unset($limit);

        return $this->data_seek($offset);

    }

   

    // count rows in result set (implementation required by 'count()' method in Countable interface)

    public function count()

    {

        return $this->num_rows;

    }

      

    // reset result set pointer (implementation required by 'rewind()' method in Iterator interface)

    public function rewind()

    {

        $this->_pointer = 0;

        $this->movePointer($this->_pointer);

        return $this; 

    }

   

    // get current row set in result set (implementation required by 'current()' method in Iterator interface)

    public function current()

    {

        if (!$this->valid())

        {

            throw new Exception('Unable to retrieve current row.');

        }

        $this->movePointer($this->_pointer);

        return $this->fetchObject();

    }

   

    // get current result set pointer (implementation required by 'key()' method in Iterator interface)

    public function key()

    {

        return $this->_pointer;

    }

   

    // move forward result set pointer (implementation required by 'next()' method in Iterator interface)

    public function next()

    {

        ++$this->_pointer;

        $this->movePointer($this->_pointer);

        return $this;

    }

   

    // determine if result set pointer is valid or not (implementation required by 'valid()' method in Iterator interface)

    public function valid()

    {

        return $this->_pointer < $this->num_rows;

    }

} 

As you can see from the code above, the “MySQLi_ResultWrapper” class has successfully implemented the Iterator and Countable SPL interfaces. While this process seems to be everything but interesting, the truth is that now client code using an instance of this class will be able to traverse and count rows in MySQL data sets by using a “foreach” iterator and the “count()” method respectively.

We’re not done with this sample class, though. It would be good to give it the ability to retrieve a particular row in a result set by specifying its offset. In reality, this can be accomplished by implementing another interface packaged with the Standard PHP Library called ArrayAccess. The details of this process will be covered in the next tutorial.   

Final thoughts

That’s all for now. In this third part of the series I gave the previous “MySQLi_ResultWrapper” class the capability to count the number of rows contained in a given result set by implementing the “count()” method declared by the Countable interface. In doing so, it’s now possible to use an instance of the class to traverse data sets and count records as if they were plain PHP arrays, which is quite appealing to client code that works with the class’ API.

In addition, it’d be desirable to provide the class with the ability to access a particular row in a result set by specifying only its offset. Fortunately, this can be achieved with minor hassles by making the class an implementer of the ArrayAccess SPL interface. As I mentioned before, this topic will be covered in depth in the next article of the series, so don’t miss it!    



 
 
>>> More PHP Articles          >>> More By Alejandro Gervasio
 

blog comments powered by Disqus
escort Bursa Bursa escort Antalya eskort
   

PHP ARTICLES

- Hackers Compromise PHP Sites to Launch Attac...
- Red Hat, Zend Form OpenShift PaaS Alliance
- PHP IDE News
- BCD, Zend Extend PHP Partnership
- PHP FAQ Highlight
- PHP Creator Didn't Set Out to Create a Langu...
- PHP Trends Revealed in Zend Study
- PHP: Best Methods for Running Scheduled Jobs
- PHP Array Functions: array_change_key_case
- PHP array_combine Function
- PHP array_chunk Function
- PHP Closures as View Helpers: Lazy-Loading F...
- Using PHP Closures as View Helpers
- PHP File and Operating System Program Execut...
- PHP: Effects of Wrapping Code in Class Const...

Developer Shed Affiliates

 


Dev Shed Tutorial Topics: