am 16. Februar 2011
Wir hatten ja schon mal vor einiger Zeit einen Genie oder Wahnsinn Beitrag. Da ich heute mal wieder was gebastelt habe, will ich mit dieser Rubrik auch weiter machen.
Ihr kennt ja alle die PHP-Funktion call_user_func_array. Diese nimmt einen callback und eine Anzahl von sortierten Parametern und ruft das in Kombination auf. Die Parameter müssen dabei aber schon in der Reihenfolge sein, wie sie die aufzurufende Methode haben will. Ich fand das irgendwie doof. Ich würde gerne ein assotiatives Array reingeben und er baut mir den Aufruf so zusammen, wie das passt. Also als Beispiel:
function doSomething($argument2, $argument1)
{
echo 'Argument1: '.$argument1;
echo 'Argument2: '.$argument2;
}
call_user_func_assoc_array( 'doSomething', array( 'argument1' => 'arg1', 'argument2' => 'arg2' );
Ihr seht, dass ich die Parameter unten in der “falschen” Reihenfolge drinnen habe. Ich habe heute also, weil ich es für ein Projekt gebraucht habe, diese Methode implementiert. Und zwar wie folgt:
function call_user_func_assoc_array($function, array $param_arr)
{
if (is_array($function))
{
$object = $function[0];
$method = $function[1];
$reflectedListener = new \ReflectionClass($object);
$reflectedMethod = $reflectedListener->getMethod($method);
$parameters = $reflectedMethod->getParameters();
}
else
{
$reflectedFunction = new \ReflectionFunction($function);
$parameters = $reflectedFunction->getParameters();
}
foreach ($parameters as $parameter)
{
$name = $parameter->getName();
if (array_key_exists($name, $param_arr))
{
$orderedParameters[] = $param_arr[$name];
}
else
{
throw new \Exception('Parameter "'.$name.'" not set.');
}
}
call_user_func_array($function, $orderedParameters);
}
Für die meisten Fälle funktioniert es auch schon. Die Syntax wie array( ‘B’, ‘parent::doSomthing’ ) als Callback muss man sich noch mal separat anschauen. Defensiver könnte das auch sein, aber es ist erst mal ein Prototyp, der vielleicht den ein oder anderen inspiriert. Die nächsten Tage werde ich dann auch noch präsentieren, wofür das gut war. Aber jetzt dürft ihr erst mal entscheiden, ob das eine total doofe Idee ist oder ob man so ein paar echt nette Probleme lösen kann.