Jaka jest różnica między bindParam i bindValue?

Odpowiedzi:

190

Odpowiedź znajduje się w dokumentacji bindParam:

W przeciwieństwie do PDOStatement :: bindValue (), zmienna jest powiązana jako odwołanie i będzie oceniana tylko w momencie wywołania PDOStatement :: execute ().

I execute

wywołaj PDOStatement :: bindParam (), aby powiązać zmienne PHP ze znacznikami parametrów: zmienne powiązane przekazują swoją wartość jako dane wejściowe i otrzymują wartość wyjściową, jeśli taka istnieje, z powiązanych znaczników parametrów

Przykład:

$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'

lub

$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'
akrobata
źródło
667

Z ręcznego wpisu dlaPDOStatement::bindParam :

[With bindParam] W przeciwieństwie do PDOStatement::bindValue()tej zmiennej zmienna jest powiązana jako odwołanie i będzie oceniana tylko w momencie jej PDOStatement::execute()wywołania.

Na przykład:

$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'

lub

$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'
samotny dzień
źródło
9
Świetnie, dziękuję! Pytanie - dlaczego możesz chcieć używać jednego nad drugim? Na przykład, kiedy użyteczne lub konieczne byłoby, aby parametr wiązania był oceniany tylko w czasie wykonywania ()?
Coldblackice 17.07.13
32
@Coldblackice Jeśli wykonałeś zapytanie wielokrotnie z różnymi danymi. Z bindValuektórą trzeba ponownie powiązać dane za każdym razem. Po bindParamprostu musisz zaktualizować zmienną. Głównym powodem użycia bindValuebyłyby dane statyczne, np. Ciągi liter lub liczby.
lonesomeday
1
Na przykład, chcesz użyć bindValue z wartościami zwracanymi przez funkcję: $ stmt-> bindValue (': status', strtolower ($ status), PDO :: PARAM_STR);
paidforbychrist
1
chciałem głosować, ale ponieważ jest 666, zostawię to
eddy147
219

Oto kilka rzeczy, o których mogę pomyśleć:

  • Za pomocą bindParammożesz przekazywać tylko zmienne; nie wartości
  • za pomocą bindValuemożna przekazać obie wartości (oczywiście wartości i zmienne)
  • bindParamdziała tylko ze zmiennymi, ponieważ pozwala podawać parametry jako dane wejściowe / wyjściowe przez „referencję” (a wartość nie jest prawidłową „referencją” w PHP) : przydatne w przypadku sterowników (cytowanie instrukcji):

obsługuje wywoływanie procedur przechowywanych, które zwracają dane jako parametry wyjściowe, a niektóre również jako parametry wejściowe / wyjściowe, które zarówno wysyłają dane, jak i są aktualizowane w celu ich odebrania.

W przypadku niektórych silników DB procedury składowane mogą mieć parametry, które mogą być używane zarówno dla danych wejściowych (podając wartość z PHP do procedury), jak i dla wyjścia (zwracając wartość z przechowywanego proc do PHP); aby powiązać te parametry, musisz użyć bindParam, a nie bindValue.

Pascal MARTIN
źródło
@PascalMartin Właśnie to, co chciałem wiedzieć, możesz powiązać wartości z bindParam. Twoje zdrowie.
yehuda
1
Nadal nie mam pojęcia, co to dokładnie oznacza, jakie dokładnie są zmienne i jakie są wartości. Korzystam z bindParam, aby powiązać wartość z symbolem zastępczym, a dzięki bindValue mogę zrobić to samo! - przynajmniej w moim przykładzie ...
Richard
29

Z przygotowanych instrukcji i procedur przechowywanych

Służy bindParamdo wstawiania wielu wierszy z jednym wiązaniem czasowym:

<?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();
Nezar Fadle
źródło
27

W najczęstszym celu powinieneś użyć bindValue.

bindParam ma dwa trudne lub nieoczekiwane zachowania:

  • bindParam(':foo', 4, PDO::PARAM_INT) nie działa, ponieważ wymaga przekazania zmiennej (jako odniesienia).
  • bindParam(':foo', $value, PDO::PARAM_INT)zmieni się $valuena ciąg po uruchomieniu execute(). To oczywiście może prowadzić do subtelnych błędów, które mogą być trudne do złapania.

Źródło: http://php.net/manual/en/pdostatement.bindparam.php#94711

Denilson Sá Maia
źródło
4

Nie musisz już dłużej walczyć, jeśli istnieje sposób, aby to zrobić:

$stmt = $pdo->prepare("SELECT * FROM someTable WHERE col = :val");
$stmt->execute([":val" => $bind]); 
Thielicious
źródło
4

Najprostszy sposób, aby umieścić to w perspektywie do zapamiętywania według zachowania (pod względem PHP):

  • bindParam: odniesienie
  • bindValue: zmienna
tfont
źródło