As a community, we can only make progress when somebody pushes the boundaries. This can be done by questioning established best practices, or by coming up with new ideas. Both are the result of a trait that every good developer should have: continuously asking yourself if things can be done even better.

Recently, when we reviewed code that some of our friends had written for a stealth-mode startup, we saw such a different approach that we had never seen in PHP before. We are glad that Tim Bezhashvyly agreed to share his experience with us, and write an article about it.

Even though Rasmus Lerdorf denies the fact, typed arrays exist in PHP. At least to some degree. This wonderful feature sneaked in as a side-effect of variadic functions that were added to the language in PHP 5.6. As you certainly know, PHP functions can receive more arguments than defined as parameters in their signature. An array comprising the full argument list can be obtained using the func_get_args() function. In a nutshell, variadics were introduced to replace ​func_get_args() and improve access to variable function arguments:

1 2 3 4 5 <?php

function foo ( ... $args )

{



}



Regardless how many arguments have been passed to the function above, they are all accessible as elements of the ​$args array. This is nothing special really, until you realize that variadics can be augmented with type declarations:

1 2 3 4 5 <?php

function foo ( Product ... $products )

{



}



So now an array passed to a function can be strictly checked to only contain elements of a specific type. If not, a fatal error will be triggered just like it would in the case of a type mismatch for a regular argument. So from the parameter's point of view it is a typed array! Think about how many input parameter validations can be dropped, how many named constructors can become a thing of the past! How many collection objects whose sole purpose was to carry the set of similar objects will become obsolete.

With the scalar type declarations of PHP 7, the number of possibilities grows:

1 2 3 4 5 <?php

function foo ( string ... $arrayOfStrings )

{



}



When it comes to passing an array to such a function, another feature introduced in PHP 5.6 comes in handy: argument unpacking can convert the array into list of arguments. The function defined above can be called in the following manner:

1 2 <?php

foo ( ... $products ) ;



In the example ​above, $products is an array containing (or not) elements of a required type.

There are two limitations however. Only one variadic is allowed in a function signature and it has to be the last parameter. While the parameters order can hardly be an issue, the limitation of one typed array per function is a bit unpleasant.

It is also possible to check the type of elements while iterating through an array. The way to do it is just to use higher-order functions such as array_map() , array_reduce() , or array_filter() , for instance, ​instead of the rather procedural ​ foreach statement:

1 2 3 4 5 6 7 8 <?php

array_map (

function ( Product $product )

{



} ,

$products

) ;



As you can see in the example above, the type declaration for a closure argument will ensure the type of each array element. A mismatch will lead to a fatal error.

Using higher-order functions instead of regular loops can be even nicer from a readability point of view and safer from an immutability standpoint. However this is already a subject for another article.