> The more angles we approach this, the more it looks like generics, or at
> least the same basis.
Which is well outside the scope of what I'd like to see, so let's look at
form 2 in closer detail - the all functions.
bool all_array( mixed $var ) {
if (is_iterable($var) && !is_callable) {
foreach ($var as $v) {
if (!is_array($v)) return false;
}
return true;
}
return false;
}
That is the base function signature and implementation. The is_callable()
above prevents iteration over generators, potentially consuming them for no
purpose.
The other functions in the family and their single value equivalents are:
is_bool -> all_bool
is_callable -> all_callable
is_double -> all_double
is_float -> all_float
is_int -> all_int
is_iterable -> all_iterable
is_long -> all_long
is_null -> all_null
is_numeric -> all_numeric
is_object -> all_object
is_real -> all_real
is_resource -> all_resource
is_scalar -> all_scalar
is_string -> all_string
is_subclass_of -> all_are
On the last one - is_subclass_of is generally more useful than is_a, but
will doing this cause confusion? Also, not all of these need to be
included - the above is a list of candidate functions to create. Of all of
these all_string() would probably see the most use followed by
all_numeric().
This will give the tools to do the desired assertions in a clean, easy to
read manner. Collections that must be of a single iterable class can also
be verified:
assert($a instanceof \SomeClass && all_string($a));
But most of the time $a will merely be an array.