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


Ответы:


190

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

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

А также execute

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

Пример:

$value = 'foo';
$s = $dbh->prepare('SELECT name FROM bar WHERE baz = :baz');
$s->bindParam(':baz', $value); // use bindParam to bind the variable
$value = 'foobarbaz';
$s->execute(); // executed with WHERE baz = 'foobarbaz'

или

$value = 'foo';
$s = $dbh->prepare('SELECT name FROM bar WHERE baz = :baz');
$s->bindValue(':baz', $value); // use bindValue to bind the variable's value
$value = 'foobarbaz';
$s->execute(); // executed with WHERE baz = 'foo'

667

Из ручной записи для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's value
$sex = 'female';
$s->execute(); // executed with WHERE sex = 'male'

9
Отлично, спасибо! Вопрос - почему вы можете использовать один поверх другого? Например, когда было бы полезно или необходимо, чтобы параметр bind оценивался только во время execute ()?
Coldblackice

32
@Coldblackice Если вы выполняли запрос несколько раз с разными данными. С помощью bindValueвам нужно будет повторно привязывать данные каждый раз. С помощью bindParamвам просто нужно обновить переменную. Основной причиной использования bindValueбудут статические данные, например, буквенные строки или числа.
одинокий

1
Например, вы хотите использовать bindValue с возвращаемыми значениями функции: $ stmt-> bindValue (': status', strtolower ($ status), PDO :: PARAM_STR);
оплачено форбихристом

1
хотел поднять голос, но так как это 666, я оставлю это
eddy147

219

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

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

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

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


@PascalMartin Как раз то, что я хотел знать, можете ли вы связать значения с помощью bindParam. Приветствия.
Иегуда

1
Я до сих пор понятия не имею, что именно это означает, что именно являются переменными и каковы значения. Я использую bindParam для привязки значения к заполнителю, и с помощью bindValue я могу сделать то же самое! - в моем примере, по крайней мере ...
Ричард

29

Из подготовленных выписок и хранимых процедур

Используйте 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();

27

Для наиболее распространенной цели, вы должны использовать 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


4

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

$stmt = $pdo->prepare("SELECT * FROM someTable WHERE col = :val");
$stmt->execute([":val" => $bind]); 

4

Самый простой способ поместить это в перспективу для запоминания поведением (с точки зрения PHP):

  • bindParam: ссылка
  • bindValue: переменная
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.