Передача по ссылке проблема с PHP 5.3.1 - PullRequest
32 голосов
/ 12 января 2010

Хорошо, это странная проблема, поэтому, пожалуйста, потерпите меня, как я объясню.

Мы обновили наши серверы разработки с 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).

Кто-нибудь испытывал это? Как я могу обойти это?

Спасибо.

Ответы [ 9 ]

45 голосов
/ 21 февраля 2010

Я только что столкнулся с этой же проблемой, вызывая 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;

}
16 голосов
/ 12 января 2010

Вы передаете массив элементов ($ passArray). Второй элемент внутри переданного массива должен быть ссылкой, поскольку это действительно список элементов, передаваемых функции.

6 голосов
/ 21 февраля 2010

На самом деле, имейте в виду, что в PHP 5.3.1 есть ошибка, касающаяся ссылок и всего семейства функций call:

Ошибки PHP # 50394: ссылочный аргумент преобразован в значение в __call

Поведение, которое вы видите, может быть результатом этой ошибки, и любая попытка исправить ее с помощью кода может вызвать проблемы в долгосрочной перспективе.

Проблема была исправлена ​​в SVN-версии PHP. До выхода версии 5.3.2 вы можете скомпилировать новую версию для использования или перейти на более раннюю версию.

3 голосов
/ 05 августа 2010

У нас возникла такая же проблема с этим кодом:

call_user_func(array($strCartHandler, 'CartPurchaseEvent'), $strCartEvent, $objToUser, null, $this);

Мое решение было просто пропустить call_user_func и сделать это:

$strCartHandler::CartPurchaseEvent($strCartEvent, $objToUser, null, $this);
2 голосов
/ 12 января 2010

Я думаю, что не рекомендуется передавать ссылку через функцию. В определении функции вы делаете что-то вроде:

function(&$arg) {

}

Это не сильно вам поможет, но вам, вероятно, не обязательно передавать ссылку в любом случае. Я думаю, вы могли бы попробовать функцию-обертку.

function wrapper($stmt, &$passArray) {
    call_user_func_array($stmt, $passArray);
}
0 голосов
/ 04 мая 2015

У меня похожая проблема, текущий код не работает:

$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");

Надеюсь, это кому-нибудь поможет, удачи:)

0 голосов
/ 10 ноября 2011

Это поможет:

<?php
call_user_func_array(Array($stmt, 'bind_param'), array(&$passArray));

function bind_param ($val)
{
    $val = (is_array($val)) ? $val[0] : $val;

    // operations...
}

?>
0 голосов
/ 12 января 2010

Второй параметр должен быть массивом. по-видимому, это было применено только в 5.3

0 голосов
/ 12 января 2010

Я думаю, что функции mysqli_bind_param() и mysqli_bind_result() очень неудобны в использовании. Я столкнулся с той же трудностью, что и вы, используя их в сочетании с call_user_func_array()

Мой обходной путь - прекратить использовать mysqli и вместо этого использовать PDO_mysql. Он имеет гораздо более простое использование:

$pdoStmt->execute( $passArray );
...