Page 1 of 1
Variable types in argument of function?
Posted: Tue Oct 05, 2010 5:11 am
by aap
I want to make a php function suitable for both scalar and array input like this, which gives the (latest) modification time of one or more files. So return value in both cases is only one integer, but the argument of the function can be a single file name, or a array of file names. It works, but I'm not convinced it is allowed. As far as I know functions are compiled only once, and with strongly typed languages you cannot change the type of arguments after compilation. Anyone has a thought?
Code: Select all
function ms_H11_mtime($file) {
if (is_array($file)) {
foreach ($file as $f) {
$mtimes[] = filemtime($f);
}
return max($mtimes);
} else {
return filemtime($file);
}
}
Re: Variable types in argument of function?
Posted: Tue Oct 05, 2010 6:28 am
by VladSun
It's OK
Re: Variable types in argument of function?
Posted: Tue Oct 05, 2010 11:56 am
by John Cartwright
Knit picking here.. but I would expect if I passed an array of something, to get an array back of each individual element processed. Instead you only return the one with the highest value.
Re: Variable types in argument of function?
Posted: Tue Oct 05, 2010 12:34 pm
by VladSun
Hm.. it really depends on what you are expecting to get back. If you have:
Code: Select all
function getLatestFileModificationTime(mixed $arg)
you may consider a
Code: Select all
getLatestFileModificationTime($fileName)
a simplified and more readable version of
Code: Select all
getLatestFileModificationTime(array($fileName))
Re: Variable types in argument of function?
Posted: Tue Oct 05, 2010 1:17 pm
by John Cartwright
In that case, they probably should be seperate functions/methods then, no?
Re: Variable types in argument of function?
Posted: Tue Oct 05, 2010 2:00 pm
by VladSun
If you ask me - I wouldn't. I'm pretty comfortable with functions accepting different (but cohesive) types of input arguments which are finally casted to a specific one.
I mean:
Code: Select all
function getLatestFileModificationTime($files)
{
if (is_string ($files))
return getLatestFileModificationTime(array($files));
$latestModificationTimes = array();
foreach ($files as $file)
$latestModificationTimes[] = filemtime($file);
return max($latestModificationTimes);
}
is closer to what I would do. Probably because I'm used to use overloading of functions (C++ style) and it's very often used in JavaScript frameworks as ExtJS

. So, the general pattern is:
Code: Select all
function func(mixed $arg)
{
if (is_some_type_1($arg))
return func(type_1_cast($arg));
if (is_some_type_2($arg))
return func(type_2_cast($arg));
...
if (is_some_type_N-1($arg))
return func(type_N-1_cast($arg));
if (is_some_type_N($arg))
return func(type_N_cast($arg));
// main_implementation_for_type_0_goes_here
}
Re: Variable types in argument of function?
Posted: Tue Oct 05, 2010 7:39 pm
by Weirdan
VladSun wrote:
Code: Select all
if (is_string ($files))
return getLatestFileModificationTime(array($files));
is closer to what I would do.
Ouch. Why recurse when you can convert the type and continue?
Code: Select all
switch (true) {
case is_string($files): $files = array($files); break;
case $files instanceof Traversable: $files = iterator_to_array($files); break;
default: // omitted
}
if (!is_array($files)) throw new InvalidArgumentException('$files should be either a string, something traversable or an array');
// work uniformly with $files as array
Re: Variable types in argument of function?
Posted: Wed Oct 06, 2010 2:29 am
by VladSun
It has been always cleaner for me, though it has worse performance.