В чем разница между bindParam и bindValue?

338

В чем разница между PDOStatement::bindParam() и PDOStatement::bindValue()?

  • 29
    это> реальный <вопрос, так как руководство может быть сложно понять разницу между этими двумя ...
Теги:
pdo
bindparam
bindvalue

8 ответов

167
Лучший ответ

Ответ приведен в документации для bindParam:

В отличие от PDOStatement:: bindValue() переменная привязана как ссылка и будет оцениваться только в момент вызова PDOStatement:: execute().

И execute

вызвать PDOStatement:: bindParam() для привязки переменных PHP к маркерам параметров: связанные переменные передают их значение в качестве входных данных и получают выходное значение, если таковое имеется, их связанных маркеров параметров

  • 3
    Вероятно, не для чего-то такого простого.
  • 1
    @Simon_eQ Мой ответ или ты имел в виду @acrosman?
Показать ещё 7 комментариев
591

От ввод вручную для PDOStatement::bindParam:

bindParam] В отличие от PDOStatement::bindValue(), переменная привязана как ссылка и будет оцениваться только в момент вызова PDOStatement::execute().

Итак, например:

$sex = 'male';
$s = $dbh->prepare('SELECT name FROM students WHERE sex = :sex');
$s->bindParam(':sex', $sex); // use bindParam to bind the variable
$sex = 'female';
$s->execute(); // executed with WHERE sex = 'female'

или

$sex = 'male';
$s = $dbh->prepare('SELECT name FROM students WHERE sex = :sex');
$s->bindValue(':sex', $sex); // use bindValue to bind the variable value
$sex = 'female';
$s->execute(); // executed with WHERE sex = 'male'
  • 8
    Отлично, спасибо! Вопрос - почему вы можете использовать один поверх другого? Например, когда было бы полезно или необходимо, чтобы параметр bind оценивался только во время execute ()?
  • 26
    @Coldblackice Если вы выполняли запрос несколько раз с разными данными. С bindValue вам нужно каждый раз bindValue данные. С bindParam вам просто нужно обновить переменную. Основной причиной использования bindValue являются статические данные, например, буквенные строки или числа.
Показать ещё 3 комментария
217

Вот некоторые из них, о которых я могу думать:

  • С bindParam вы можете передавать только переменные; не значения
  • с bindValue, вы можете передать оба значения (значения, очевидно, и переменные)
  • bindParam работает только с переменными, поскольку позволяет параметрам задаваться как входные/выходные данные посредством "reference" (а значение не является допустимой "ссылкой" в PHP): полезно с драйверами, которые (цитируя руководство):

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

С некоторыми механизмами БД хранимые процедуры могут иметь параметры, которые могут использоваться как для ввода (дающего значение от PHP к процедуре), так и для вывода (возвращающего значение из хранимого proc на PHP); чтобы связать эти параметры, вы должны использовать bindParam, а не bindValue.

  • 0
    спасибо, могу принять только один, хотя
  • 1
    милости просим :-) (не беспокойтесь об этом ^^)
Показать ещё 7 комментариев
21

Для наиболее общей цели вы должны использовать bindValue.

bindParam имеет два сложных или неожиданных поведения:

  • bindParam(':foo', 4, PDO::PARAM_INT) не работает, поскольку для этого требуется передать переменную (в качестве ссылки).
  • bindParam(':foo', $value, PDO::PARAM_INT) изменит $value на строку после запуска execute(). Это, конечно, может привести к тонким ошибкам, которые могут быть трудно поймать.

Источник: http://php.net/manual/en/pdostatement.bindparam.php#94711

18

Из Подготовленные утверждения и хранимые процедуры

Используйте bindParam для вставки нескольких строк с одной привязкой времени:

<?php

$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (?, ?)");
$stmt->bindParam(1, $name);
$stmt->bindParam(2, $value);

// insert one row
$name = 'one';
$value = 1;
$stmt->execute();

// insert another row with different values
$name = 'two';
$value = 2;
$stmt->execute();
  • 4
    именно так все должны использовать bindParam. Если это только для одной строки, просто используйте bindValue
  • 0
    Это ясно для меня.
1

Вам больше не нужно бороться, когда существует способ lilke this:

$stmt = $pdo->prepare("SELECT * FROM someTable WHERE col = :val");
$stmt->execute([":val" => $bind]); 
  • 0
    Я думаю, что вы здесь не правы, согласно php.net/manual/en/pdostatement.execute.php (Пример # 2), он должен быть противоположен $stmt->execute([':val' => $bind]); ,
  • 0
    Я знаю, что уже исправил это, когда я отправил с моего iphone, но почему-то это не применимо, или я потерял Wi-Fi. Готово, спасибо, что дали мне знать.
1

Простейший способ выразить это (с точки зрения PHP):

  • bindParam: ссылка
  • bindValue: переменная
  • 1
    ссылка не ресурс
-2

Ключевое различие между двумя методами, которое можно прочитать из документа для bindParam(), заключается в том, как передается переменная параметра в вызове процедуры.

Метод bindParam() привяжет маркер параметра к имени переменной PHP, которая будет содержать выходное значение, а не значение. Кроме того, это значение оценивается только тогда, когда вызывается PDOStatement :: execute().

... переменная привязана как ссылка и будет оцениваться только в момент вызова PDOStatement :: execute().

Для сравнения, метод bindValue() привяжет маркер параметра к значению переменной PHP, ссылающейся на него, и поэтому сразу же доступен в момент вызова PDOStatement :: execute().

Важно отметить, что при использовании метода bindParam(), если ваш параметр является параметром OUT, то есть он привязывается к переменной, которая получает свое значение из хранимой процедуры, тогда вы должны явно указать длину, как указано в документации параметра длины:

длина

Длина типа данных. Чтобы указать, что параметр является параметром OUT из хранимой процедуры, вы должны явно задать длину.

Вы должны установить длину выходного параметра в соответствии с максимальной ожидаемой длиной, определенной в вашей базе данных.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню