PHP ships with a number of predefined classes and interfaces, two of the common out of them are ArrayAccess interface and ArrayObject class. Specially, these two can be very handy whenever objects requires the features of arrays. According to PHP documentation, if a class implements ArrayAccess then objects of that class can be accessed as we access arrays. On the other hand, a class that extends ArrayObject, objects of that class work as arrays.
The ArrayAccess interface has four abstract methods, which are ArrayAccess::offsetExists, ArrayAccess::offsetSet, ArrayAccess::offsetGet, and ArrayAccess::offsetUnset. Now, somebody may ask the question: what is an abstract method? A method that does not obtain any implementation, more specifically, a method that does not hold a body, is known as abstract method . Thus each of these abstract methods further needs an implementation.
By default, ArrayObject class implements IteratorAggregate, ArrayAccess, Serializable and Countable interfaces. As a result, all abstract methods of these interfaces are already implemented by built-in ArrayObject class. Therefore, when we extend ArrayObject class by other classes, we may only need to override some of the methods from ArrayObject class. We will see the fact by the last example.
OK, let's now talk about how to introduce the above features through our examples sequentially. Although it is not always be appropriate to use a Dependency Injection Container, but I am so obsessed about using DI Container through my last few articles that, all the examples I am going to introduce today are also based on DI Container. The article on DI container can be reached by this Link
Firstly, we will take an example whereby we intentionally produce some errors or notices for using PHPs unset() and shuffle() functions. Secondly, we will show how to mitigate the problems by implementing ArrayAccess interface by the Container class. In the final example, by extending ArrayObject class by the Container class, we will create objects that perform like arrays.
The examples below are mainly focused on the operations for implementing ArrayAccess and extending ArrayObject by the Container class:
- flights_example.php
- ArrayAccess.php
- ArrayObject.php
At first I have constructed the Container class with the support of two PHP magic methods __set() and __get() which initially handle setting and getting properties for the Container object. One can find more details about these two methods by this Link. The motive of this example is that, I want to execute some regular flights via a number of terminals in a busy airport for performing all the specific tasks which are exclusively handled by the Container object. For that reason, I want to use unset() and shuffle() PHPs built-in functions to control the most recent flights from a flights schedules by the limited terminals in some random fashion. But the problem here is that, by the support of these __set() and __get() methods, the Container object is unable to perform the tasks unlike arrays which can be seen by the following snippet of code:
class Container
{
protected $data = array();
function __set($k, $v)
{
$this->data[$k] = $v;
}
function __get($k)
{
if (!isset($this->data[$k]))
{
throw new Exception(sprintf('Key "%s" does not exists.', $k));
}
return is_callable($this->data[$k])? $this->data[$k]($this) : $this->data[$k];
}
}
$c = new Container();
$c->flights = ['Flight_A', 'Flight_B', 'Flight_C', 'Flight_D', 'Flight_E'];
$c->terminals = ['Terminal_1', 'Terminal_2', 'Terminal_3'];
if(isset($c->flights[1]))
{
unset($c->flights[1]);
}
if(isset($c->flights[4]))
{
unset($c->flights[4]);
}
shuffle($c->flights);
shuffle($c->terminals);
In this case, when using unset() and shuffle() functions by the Container object, the program produces four notices as: "Indirect modification of overloaded property has no effect …". Through the 2nd example we will try to solve these problems. It is mention able that if somebody eager to get more information about how these magic methods __set() and __get() work with the anonymous function shown here then please, visit the article by this Link.
By the example ArrayAccess.php we now have solved the problems which we have faced in flights_example.php and by ArrayObject.php, an object now have greater access to the functionalities that any ordinary array offers.
Stars from the audience would be always appreciated.
A detail illustration of this topic and some of my other articles on different topics can be reached by the medium blog site.