A Collection class is an OOP replacement for the traditional array data structure. As the name suggests, a collection can be seen as a container and can be described as a class designed for holding data of a specific type or any type.
Collections can be seen as more specialized arrays, so, practically, a Collection class should be able to make some simple array manipulation tasks such as sorting, counting arrays, adding or removing items, getting an element by its index and so on, as you will see in the Collection class from next section of this article.
This article will show you how to create a Collection class using different types of methods used to manipulate arrays and we will apply the Reflection mechanism over this class.
Creating the Collection class
As I mention above, a collection class needs to reveal methods that allow us to add, get, sort and remove items, list the size of the collection, check if a given object exists in the collection, checking if the collection is empty or not, setting an element by its key, etc.
To create a Collection class we need to implement two interfaces: ArrayAccess and Iterator interfaces, described next:
The ArrayAccess interface provide accessing objects as arrays for the purposes of setting, unsetting and retrieving data from it. To implement ArrayAccess you need to implement four methods:
• ArrayAccess::offsetExists — Whether an offset exists
• ArrayAccess::offsetGet — Offset to retrieve
• ArrayAccess::offsetSet — Assign a value to the specified offset
• ArrayAccess::offsetUnset — Unset an offset
The Iterator interface is an interface for external iterators or objects that can be iterated themselves internally.
To implement Iterator you need to implement five methods:
• Iterator::current — Return the current element
• Iterator::key — Return the key of the current element
• Iterator::next — Move forward to next element
• Iterator::rewind — Rewind the Iterator to the first element
• Iterator::valid — Checks if current position is valid
Below is the Collection class that contains all the practical methods in order to work with arrays:
<?php
class Collection implements Iterator, ArrayAccess {
//The number of elements from the Collection
public $length=0;
//The array
//public $array = array('12','5','60', '98', '8');
//Adding an object into a collection
function add($arg1,$arg2=false) {
if(!$arg2) {
$this->array_elements[] = $arg1;
} else {
if (!array_key_exists($arg1,$this->array_elements)) {
$this->array_elements[$arg1] = $arg2;
}
}
$this->count();
return $this ;
}
//Setting a value for a specified key of the array_elements
function set($key,$item) {
if(isset($key)) {
$this->array_elements[$key] = $item;
} else {
$this->array_elements[] = $item ;
}
$this->count();
return $this->get($key);
}
//Sorting the array by values
function asort($flags=null) {
asort($this->array_elements,$flags);
return $this;
}
//Sorting the array by keys
function ksort($flags=null) {
ksort($this->array_elements,$flags);
return $this;
}
//Sorting the array naturally
function sort($flags=null) {
sort($this->array_elements,$flags);
return $this ;
}
//Getting the length of the array
function count() {
$this->lenght = count($this->array_elements);
return $this->lenght ;
}
//Removing a specified kye
function remove($key) {
if (array_key_exists($key,$this->array_elements)) {
unset($this->array_elements[$key]);
$this->count();
return $this;
}
}
//Moving the cursor a step forward
function next() {
return next($this->array_elements) ;
}
//Cheking if the next element is valid
function hasNext() {
$this->next() ;
$v = $this->valid() ;
$this->back() ;
return $v ;
}
//Moves the cursor a step back
function back() {
return prev($this->array_elements);
}
//Moves the cursor at start
function rewind() {
return reset($this->array_elements);
}
//Moves the cursor at the end
function forward() {
return end($this->array_elements);
}
//Getting the key from the pointed cursor
function current() {
return current($this->array_elements);
}
//Getting the current cursor of the key
function currentKey() {
return key($this->array_elements) ;
}
//Getting the cursor of the key
function key() {
return $this->currentKey();
}
//Checking if the cursor is at a valid item
function valid() {
if(!is_null($this->key())) {
return true;
} else {
return false ;
}
}
//Returning object for given posistion
function get($key) {
return $this->array_elements[$key];
}
//Checking if an offset exists using Array Access interface
function offsetExists($offset) {
return $this->exists($offset);
}
//Getting an element using Array Access interface
function offsetGet($offset) {
return $this->get($offset);
}
//Setting an element using Array Access interface
function offsetSet($offset,$value) {
return $this->set($offset, $value);
}
//Removing element using Array Access interface
function offsetUnset($offset) {
return $this->remove($offset);
}
//Checking if the collection is empty or not
function isEmpty() {
if($this->count() < 1)
return true ;
else
return false;
}
//Checking if a given object exists in collection
function contains($obj) {
foreach($this->array_elements as $element) {
if($element === $obj) {
$this->rewind();
return true ;
}
}
$this->rewind();
return false ;
}
//Returning the first index of given object
function indexOf($obj) {
foreach($this->array_elements as $k=>$element) {
if($element === $obj) {
$this->rewind();
return $k ;
}
}
$this->rewind();
return null ;
}
//Cutting the array to given size
function trimToSize($size) {
$t = array_chunk($this->array_elements,$size,true);
$this->array_elements = $t[0];
$this->count();
return $this ;
}
}
?>
Testing the Collection class from above, using some of the most important methods in working with:
1. Adding a new entry into the collection:
$collection = new Collection($array);
$a=$collection->add('34');
print "<pre>";
print_r($a);
print "</pre>";
The output will be:
Collection Object
(
[lenght] => 6
[array_elements:Collection:private] => Array
(
[0] => 12
[1] => 5
[2] => 60
[3] => 98
[4] => 8
[5] => 34
)
)
2. Checking if the collection is empty:
$collection = new Collection($array);
if($collection->isEmpty()){
echo 'The collection is empty ';}
else
{echo 'The collection is not empty ';}
The output will be:
The collection is not empty
3. Setting a value for the collection (in this case [2]=>1000)
$collection = new Collection($array);
$s=$collection->set('2','1000');
print "<pre>";
print_r($collection);
print "</pre>";
The output will be:
Collection Object
(
[lenght] => 6
[array_elements:Collection:private] => Array
(
[0] => 12
[1] => 5
[2] => 1000
[3] => 98
[4] => 8
[5] => 34
)
)
4. Trimming the collection to a specified length (in our case 2):
$collection = new Collection($array);
$trimToSize=$collection->trimToSize(2);
print "<pre>";
print_r($trimToSize);
print "</pre>";
The output is:
Collection Object
(
[lenght] => 2
[array_elements:Collection:private] => Array
(
[0] => 12
[1] => 5
)
)
5. Sorting the collection
$collection = new Collection($array);
//This function sorts an array. Elements will be arranged from lowest to highest when this function has completed.
$sortingCollection=$collection->sort();
//Sorts an array by key, maintaining key to data correlations
$sortingCollection=$collection->ksort();
//Sort an array and maintain index association
$sortingCollection=$collection->asort();
print "<pre>";
print_r($sortingCollection);
print "</pre>";
The output of this different collection sorting is:
sort()
----------------
Collection Object
(
[lenght] => 5
[array_elements:Collection:private] => Array
(
[0] => 5
[1] => 8
[2] => 12
[3] => 60
[4] => 98
)
)
ksort()
----------------
Collection Object
(
[lenght] => 5
[array_elements:Collection:private] => Array
(
[0] => 12
[1] => 5
[2] => 60
[3] => 98
[4] => 8
)
)
asort()
----------------
Collection Object
(
[lenght] => 5
[array_elements:Collection:private] => Array
(
[1] => 5
[4] => 8
[0] => 12
[2] => 60
[3] => 98
)
)
Applying the Reflection Mechanism Over the Collection Class
The next listing uses the Reflection mechanism to reveal all the methods of our Collection class using the ReflectionClass class. This class reports information about a class, such as interfaces, methods, constructor, properties, constants and so on. Learn more about the ReflectionClass methods.
In the listing below we will only use the getMethods() method:
<?php
include ('Collection.php');
$reflection = new ReflectionClass("Collection");
$methods = $reflection->getMethods();
echo "The following methods are available:".'<br/>';
print "<pre>";
print_r($methods);
print "</pre>";
?>
The following methods are available:
Array
(
[0] => ReflectionMethod Object
(
[name] => add
[class] => Collection
)
[1] => ReflectionMethod Object
(
[name] => set
[class] => Collection
)
[2] => ReflectionMethod Object
(
[name] => asort
[class] => Collection
)
[3] => ReflectionMethod Object
(
[name] => ksort
[class] => Collection
)
[4] => ReflectionMethod Object
(
[name] => sort
[class] => Collection
)
[5] => ReflectionMethod Object
(
[name] => count
[class] => Collection
)
[6] => ReflectionMethod Object
(
[name] => remove
[class] => Collection
)
[7] => ReflectionMethod Object
(
[name] => next
[class] => Collection
)
[8] => ReflectionMethod Object
(
[name] => hasNext
[class] => Collection
)
[9] => ReflectionMethod Object
(
[name] => back
[class] => Collection
)
[10] => ReflectionMethod Object
(
[name] => rewind
[class] => Collection
)
[11] => ReflectionMethod Object
(
[name] => forward
[class] => Collection
)
[12] => ReflectionMethod Object
(
[name] => current
[class] => Collection
)
[13] => ReflectionMethod Object
(
[name] => currentKey
[class] => Collection
)
[14] => ReflectionMethod Object
(
[name] => key
[class] => Collection
)
[15] => ReflectionMethod Object
(
[name] => valid
[class] => Collection
)
[16] => ReflectionMethod Object
(
[name] => get
[class] => Collection
)
[17] => ReflectionMethod Object
(
[name] => offsetExists
[class] => Collection
)
[18] => ReflectionMethod Object
(
[name] => offsetGet
[class] => Collection
)
[19] => ReflectionMethod Object
(
[name] => offsetSet
[class] => Collection
)
[20] => ReflectionMethod Object
(
[name] => offsetUnset
[class] => Collection
)
[21] => ReflectionMethod Object
(
[name] => isEmpty
[class] => Collection
)
[22] => ReflectionMethod Object
(
[name] => contains
[class] => Collection
)
[23] => ReflectionMethod Object
(
[name] => indexOf
[class] => Collection
)
[24] => ReflectionMethod Object
(
[name] => trimToSize
[class] => Collection
)
[25] => ReflectionMethod Object
(
[name] => getIterator
[class] => Collection
)
)
Conclusion
During this article you have seen how to create the Collection class (which implements the ArrayAccess and Iterator interfaces) that allow us to make use of the most handy methods, such as adding, removing and resizing of the collection.