Хорошо, это странная проблема, поэтому, пожалуйста, несите меня, как я объясню.
Мы обновили наши серверы от PHP 5.2.5 до 5.3.1.
Загружая наш код после переключения, мы начинаем получать ошибки, например:
Warning: Parameter 2 to mysqli_stmt::bind_param() expected to be a reference, value given in /home/spot/trunk/system/core/Database.class.php on line 105
указанная линия (105) выглядит следующим образом:
call_user_func_array(Array($stmt, 'bind_param'), $passArray);
мы изменили строку следующим образом:
call_user_func_array(Array($stmt, 'bind_param'), &$passArray);
в этот момент (поскольку allow_call_time_pass_reference
) отключен, php выбрасывает это:
Deprecated: Call-time pass-by-reference has been deprecated in /home/spot/trunk/system/core/Database.class.php on line 105
Попытавшись исправить это в течение некоторого времени, я сломался и allow_call_time_pass_reference
.
Это избавило от Deprecated
предупреждения, но теперь Warning: Parameter 2 to mysqli_stmt::bind_param() expected to be a reference
будет бросать каждый раз с или без ссылки.
У меня есть нулевая подсказка, как это исправить. Если целевой метод был моим собственным, я бы просто ссылался на входящие вары в объявлении func, но это (относительно) собственный метод (mysqli).
Кто-нибудь испытал это? Как я могу обойти это?
Спасибо.
Вы передаете массив элементов ($ passArray). Второй элемент внутри переданного массива должен быть ссылкой, так как это действительно список элементов, которые вы передаете функции.
Я просто испытал эту же проблему, вызвав bind_param через call_user_func_array и передав массив параметров. Решение заключается в изменении значений в массиве, на который нужно ссылаться. Это не элегантно, но оно работает.
call_user_func_array(array($stmt, 'bind_param'), makeValuesReferenced($passArray)); function makeValuesReferenced($arr){ $refs = array(); foreach($arr as $key => $value) $refs[$key] = &$arr[$key]; return $refs; }
Собственно, имейте в виду, что есть ошибка с PHP 5.3.1, касающаяся ссылок, и всех семейств call
:
Ошибки PHP # 50394: аргумент ссылки преобразован в значение в __call
Поведение, которое вы видите, может быть результатом этой ошибки, и любая попытка исправить его код может вызвать проблемы в конечном итоге.
Проблема была исправлена в версии SVN для PHP. Пока не будет выпущен 5.3.2, вы можете скомпилировать новую версию для использования или перейти на более раннюю версию.
Мы столкнулись с этой проблемой:
call_user_func(array($strCartHandler, 'CartPurchaseEvent'), $strCartEvent, $objToUser, null, $this);
Мое решение состояло в том, чтобы просто пропустить call_user_func
и сделать это:
$strCartHandler::CartPurchaseEvent($strCartEvent, $objToUser, null, $this);
Я думаю, что устаревшее – это передача ссылки через функцию. В определении функции вы делаете что-то вроде:
function(&$arg) { }
Это не поможет вам, но вы, вероятно, не должны передавать ссылку. Я думаю, вы могли бы попробовать функцию обертки.
function wrapper($stmt, &$passArray) { call_user_func_array($stmt, $passArray); }
Я думаю, что функции mysqli_bind_param()
и mysqli_bind_result()
очень неудобны в использовании. Я столкнулся с той же трудностью, что и вы, используя их в сочетании с call_user_func_array()
Мое обходное решение состояло в том, чтобы прекратить использование mysqli и вместо этого использовать PDO_mysql. Это намного проще:
$pdoStmt->execute( $passArray );
Это поможет:
<?php call_user_func_array(Array($stmt, 'bind_param'), array(&$passArray)); function bind_param ($val) { $val = (is_array($val)) ? $val[0] : $val; // operations... } ?>
У меня есть аналогичная проблема, текущий код не работал:
$query="Select id,name FROM mytable LIMIT ?,?"; $params=Array('ii'); array_push($params,$from_var); array_push($params,$to_var); ... $stmt=$link->prepare("$query"); $ref=new ReflectionClass('mysqli_stmt'); $method=$ref->getMethod("bind_param"); $method->invokeArgs($stmt,$params); ...
Он сказал, что «Параметр 2 для mysqli_stmt :: bind_param () ожидается как ссылка, значение, данное"
И затем, в отчаянии, я попытался взять $ from_var и $ to_var в кавычки. И это сработало!
$params=Array('ii'); array_push($params,"$from_var"); array_push($params,"$to_var");
Надеюсь, это поможет кому-то, удачи 🙂
Второй параметр должен быть массивом. по-видимому, это было соблюдено только в 5.3