[英]Getting call_user_func_array() to work with prepared sql statements
[英]Does the following call to call_user_func_array() work?
我有幾個庫,它們使用的代碼類似於以下代碼。
$args = array_merge(array(&$target, $context), $args);
$result = call_user_func_array($callback, $args);
兩種情況下的代碼都不同,但是我所展示的代碼實際上是完成的。 $callback
函數使用以下簽名:
function callback(&$target, $context);
庫都說明和第三方代碼(稱為插件或擴展)都采用了該函數簽名,這意味着沒有一個擴展將回調定義為例如function my_extension_loader_callback($target, $context)
。
使我感到困惑的是call_user_func_array()的文檔中的以下句子。
在PHP 5.4之前,param_arr中的引用變量通過引用傳遞給函數,無論該函數是否希望通過引用傳遞各個參數。 這種形式的調用時按引用傳遞不會發出棄用通知,但是仍然不推薦使用,並且已在PHP 5.4中刪除。 此外,這不適用於內部功能,為此必須遵循功能簽名。 函數通過引用期望參數時按值傳遞會導致警告,並使
call_user_func()
返回FALSE
。
特別是,突出顯示的句子似乎暗示着對PHP代碼中定義的函數不執行此操作。
以這種方式使用call_user_func_array()
是否可以在PHP 5.4中使用?
在較新版本的PHP中,使用call_user_func_array
,如果函數需要引用, call_user_func_array
值傳遞被視為錯誤。
在PHP 5.3.3之前,這是有效的PHP代碼:
//first param is pass by reference:
my_function(&$strName){
}
//passing by value, not by reference, is now incorrect if passing by reference is expected:
call_user_func_array("my_function", array($strSomething));
//correct usage
call_user_func_array("my_function", array(&$strSomething));
上面的按值傳遞沒有警告就不再可能(我的項目也被設置為對任何類型的錯誤(通知,警告等)拋出異常。)因此,我必須解決此問題。
解決方案我遇到了這個問題,這就是我解決的方法(我有一個小型RPC服務器,因此在反序列化參數后沒有諸如引用值之類的東西):
//generic utility function for this kind of situations
function &array_make_references(&$arrSomething)
{
$arrAllValuesReferencesToOriginalValues=array();
foreach($arrSomething as $mxKey=>&$mxValue)
$arrAllValuesReferencesToOriginalValues[$mxKey]=&$mxValue;
return $arrAllValuesReferencesToOriginalValues;
}
盡管$strSomething
沒有通過引用傳遞,但array_make_references
會將其作為對自身的引用:
call_user_func_array("my_function", array_make_references(array($strSomething)));
我認為PHP專家們正在考慮幫助人們捕獲被錯誤調用的函數(一個隱蔽的陷阱),這通常在通過call_user_func_array
時發生。
如果call_user_func_array()
返回false
,則說明您有問題,否則一切都很好。
默認情況下,不再通過引用傳遞參數,但是您可以顯式地進行傳遞。 唯一的麻煩可能是您的引用在array_merge()
期間丟失了,還沒有測試。
當有多個站點使用通過引用傳遞參數的call_user_func_array
時,我升級到PHP5.4時發現了同樣的問題。
我所做的解決方法非常簡單,它包括使用eval()用完整的函數調用替換call_user_func_array
本身。 這不是最優雅的解決方案,但適合我的目的:)
這是舊的代碼:
call_user_func_array($target, &$arguments);
我替換為:
$my_arguments = '';
for ($i=0; $i<count($arguments); $i++) {
if ($i > 0) { $my_arguments.= ", "; }
$my_arguments.= "\$arguments[$i]";
}
$evalthis = " $target ( $my_arguments );";
eval($evalthis);
希望這可以幫助!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.