2017-02-01 2 views
0

Я понимаю, что мы должны передать ссылки на mysqli_stmt_bind_param. Я делаю следующееmysqli_stmt_bind_param - ожидает ссылок

$ref = refValues($data); 
    function refValues($arr){ 
     $refs = array(); 
     foreach($arr as $key => $value) 
      $refs[$key] = &$arr[$key]; 
      var_dump(implode(",", $refs)); 
      return $refs; 
    return $arr; 
} 

У меня есть все мои значения в массиве. Я использую указанную выше функцию для получения ссылок. Got the above answer from SO

Мой PHP версия 5.6

Я связывании Params следующим образом.

mysqli_stmt_bind_param($stmt, $types, $ref); 

$stmt это заявление создано через mysqli_prepare. Она возвращает номер ошибки 0.

$types не что иное, как $types = str_pad('',count($data),'s');

Я проверил $types данные также. Он возвращает ожидаемое количество типов. i.e ssssssss

Если у меня возникли ошибки, я получаю следующее сообщение об ошибке.

Only variables should be passed by reference in test.php 

Я нашел this решение в формате SO. Я не могу назначить 100 переменных. Я не думаю, что это возможно.

Я нашел другую альтернативу call_user_func_arrary.

$values = refValues($data); 
call_user_func_array(array($stmt, 'bind_param'), $values); 

Он возвращает number of bind type doesn't match number of values. Это странно для меня. Я проверил массив и значения. Оба подсчета совпадают. Я не знаю о внутренней реализации call_user_func_array.

Пожалуйста, дайте мне знать, есть ли способ решить эту проблему эффективно.

+0

Ну, во-первых, 'функция refValues ​​($ обр) {' создает копию data' – Xorifelse

+0

'$ @Xorifelse Пожалуйста, см. обновленную ссылку. 34 ответа на ответ. Разве это не создает ссылки? –

+0

В вашем коде '$ ref' - массив (значение), содержащий ссылки. –

ответ

3

Эта линия

mysqli_stmt_bind_param($stmt, $types, $ref); 

означает, что у вас есть один ссылки для связывания.

Почему? Давайте посмотрим:

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

Как вы передадите один аргумент (это $ref) - вы пытаетесь связать только один значение. И $ref is не Ссылка, это массив значений, которые ссылаются. Увидеть разницу? Массив ссылок по ссылке.

Итак, вы взяли второй подход, и это право один:

$values = refValues($data); 
call_user_func_array(array($stmt, 'bind_param'), $values); 

Что здесь ошибка? Вы не прошли типы $types:

// do not assign anything to a variable 
// pass results of `refValues` directly to `call_user_func_array` 
call_user_func_array(array($stmt, 'bind_param'), array_merge(array($types), refValues($data))); 

Что мы делаем здесь: мы пытаемся вызвать $stmt->bind_param и перейти к этой функции аргументов как массив.

Каковы аргументы $stmt->bind_param?

  • первый аргумент типа ($types)
  • следующие аргументы приводятся ссылки на значения ($values)

Теперь он должен работать.

+0

Я получаю 'Предупреждение: Параметр 2 к mysqli_stmt :: bind_param() ожидается как ссылка, значение задано' Любая помощь? –

+0

@GopsAB использовать PDO –

+0

Исправлено, см. Обновление. –

1

Есть два возможных способа избежать хлопот:

  1. Использование PDO. Ваша текущая проблема - это только первая из многих WTF, которые у вас будут с mysqli. В данном конкретном случае это было бы так просто, и естественный в

    $stmt = $db->prepare($sql); 
    $stmt->execute($data); 
    
  2. Хорошо, у вас есть такая блажь использования MySQLi. Затем, до тех пор, как вы используете поддерживаемый PHP версии, you can use a splat or a three dot operator:

    $stmt = $db->prepare($sql); 
    $types = str_repeat('s', count($data)); 
    $statement->bind_param($types, ...$data); 
    $statement->execute(); 
    
+0

Спасибо. Я подумаю об обновлении до PDO. –