<?php
/**
* Whenever you create a function that has an array as a parameter you use a
* type-hint to make sure your parameter is of the right type.
*
* But is this a good idea?
*
* In the same way as using is_string() excludes any objects implementing a
* '__toString' method, using 'Array' as type-hint excludes objects that
* implement the Traversable interface.
*
* My suggestion would be to avoid type-hinting and check for array-ishness yourself
*
* See the code example below for an explanation.
*
* Note: The variable naming scheme used in this code is an adaption of
* Systems Hungarian which is explained at http://p...content-available-to-author-only...r.ca/VariableNamingConvention/
*/
/**
* Check if a given variable can be treated as an Array
*/
function is_arrayish ($p_aSubject) {
$bIsArray = false;
if (is_array($p_aSubject) || $p_aSubject instanceof Traversable
) { $bIsArray = true;
}
return $bIsArray;
}
/**
* Create an Array-ish object
*/
$aNumbers = ['one','two','three'];
$oNumbers = new ArrayObject($aNumbers);// To save us from implementing all those ArrayAccess methods
/**
* A function that only accepts Arrays
*/
function onlyAcceptArrays
(array $p_aSubject) { foreach($p_aSubject as $t_sItem){
echo $t_sItem . PHP_EOL;
}
}
/**
* A function that does accept other Arrayish types
*/
function acceptAllIteratorables($p_aSubject) {
if (is_arrayish($p_aSubject) === false) {
throw new \InvalidArgumentException(
'Argument 1 passed to ' . __METHOD__ . ' must be of the type array or implementation of Traversable, '.
' given'
);
} else {
foreach($p_aSubject as $t_sItem){
echo $t_sItem . PHP_EOL;
}
}
}
/**
* And now... the proof!
*/
// Works
acceptAllIteratorables($oNumbers);
echo '----------------------------------------' . PHP_EOL;
try {
// Throws Exception
acceptAllIteratorables(new stdClass());
} catch(InvalidArgumentException $eInvalidArgument){
echo $eInvalidArgument;
}
echo PHP_EOL . '----------------------------------------' . PHP_EOL;
// Triggers a fatal error
onlyAcceptArrays($oNumbers);
/*EOF*/