The Problem
As a developer for the Comprehensive Web Programming API project (url: http://sourceforge.net/projects/cwpapi/) for ACD Incorporated (url: http://www.acdinc.net/), I needed to develop a way of performing a sprintf() on an error message string. The only problem is that the values to substitute in had to be passed as an array, and I did not want to call sprintf() recursively because of the string formatting vulnerabilities this would introduce.
I read about the call_user_func_array() function which allows you to call a function and split out an array into individual arguments to that function. For example: the call call_user_func_array("myfunction", array("param1", "param2");
translates to myfunction("param1", "param2");
All was fine and dandy until I noticed the line that said that the function was introduced into CVS after 4.0.4pl1. AHH! Major problem, I need to support ALL php4 versions!
The Solution
So I did what any self respecting programmer would do, I rolled my own.
NOTE: This implementation is smart enough to call call_user_func_array() if it exists.
The Code!
Enjoy!
function call_func_array($Function, $Replace) { if (function_exists("call_user_func_array")) { return call_user_func_array($Function, $Replace); } $Function = ereg_replace("[^0-9A-Za-z_]", "", $Function); if (!is_array($Replace)) { $Replace[] = $Replace; } /* Reset the variable */ reset($Replace); /* Get a new variable name */ $tmpVariableName = "_test"; //. md5(microtime); $tmpVariableName2 = $tmpVariableName . "_return"; /* Add the "replace" array into the temporary variable */ $GLOBALS["$tmpVariableName"] = &$Replace; $tmpParams = ""; /* Go through the array and do a replace on each */ while (list($tmpKey,$tmpVal) = each($Replace)) { /* Add it on to our list of parameters, we insure index is a integer just to be sure. */ $tmpParams .= ', $GLOBALS["' . $tmpVariableName . '"][' . (integer) $tmpKey . ']'; } /* Trim off our extra comma at the beginning */ $tmpParams = substr($tmpParams, 1); /* Do the call */ $tmpCall = "$GLOBALS["" . $tmpVariableName . "_return"] = $Function($tmpParams);"; eval($tmpCall); /* Get the return value. */ $tmpReturnValue = $GLOBALS["$tmpVariableName2"]; /* Save memory */ unset($GLOBALS["$tmpVariableName"], $GLOBALS["$tmpVariableName2"]); return $tmpReturnValue; }