PHP strict typed arrays

PHP has seen many improvements for the last few years, especially adding the type system, which helps us to avoid runtime errors and make the debugging easier. However, the built-in type system in PHP has some missing parts; for example, we cannot have a strictly typed array, which we are going to address this issue here, and how we can solve it.

Problem with arrays

$array = [];
$array[] = 1;
$array[] = 'first';
$array[] = 'second';
foreach($array as $item){
echo $item;
}

This code works fine, but what if we wanted to add more restrictions over our array?
Before we solve this problem, we need to learn about array collections.

Collections

The easiest way to have a collection is to extends our object from `\ArrayObject` class:

<?phpclass Collection extends \ArrayObject
{
}

Wwe can use the Collection class as an array:

$collection = new Collection([1,2,3]);
$collection[] = 'first';
$collection[] = 'second';
foreach($collection as $item){
echo $item;
}

Now that we have a collection, we can modify our Collection class to check the value’s type before we add it to the array:

We can check the given value by overriding the offsetSet and the append methods from ArrayObject class. If the value was not instance of the collectionType it throws an exception.

Here is how we can use this class:

$collection = new Collection(UserInterface::class);
$collection[] = new User();
$collection[] = new User();
print_r($collection);

The output for this code, as expected, would be an array with two members, but as soon as we try to put a value with other types, we will receive an error:

$collection[] = 'user1';

As you can see, now we are able to specify what types are allowed to add to our arrays. But our Collection has an issue; it only works if we try to add a class into our collection. What if we wanted to have an array that only accepts int or float?

To solve this issue, we need to change our checkType method in the Collection class:

protected function checkType($value): bool
{
switch ($this->collectionType) {
case 'int':
return is_int($value);
case 'string':
return is_string($value);
case 'float':
return is_float($value);
default:
return $value instanceof $this->collectionType;
}
}

As you can see, we checked for different types in the checkType method. To use this class, let’s create another class and call it IntegerCollection:

Simply, by creating a class and extends it from our Collection class, and override the contructor, we can have an array that only accepts int values.

$collection = new InegerCollection();
$collection[] = 1;
$collection[] = 1;
print_r($collection);
$collection[] = 'test'; // throws an exception

Summary

My ideas, thoughts, and tutorials about life, internet, and programming. https://github.com/smoqadam