Qual é a diferença entre bindParam e bindValue?
Pergunta
Qual é a diferença entre PDOStatement::bindParam()
e PDOStatement::bindValue()
?
Solução
A resposta está na documentação para bindParam
:
Ao contrário de PDOStatement::bindValue(), a variável é vinculada como uma referência e só será avaliada no momento em que PDOStatement::execute() for chamado.
E execute
chame PDOStatement::bindParam() para vincular variáveis PHP aos marcadores de parâmetro:variáveis vinculadas passam seu valor como entrada e recebem o valor de saída, se houver, de seus marcadores de parâmetro associados
Exemplo:
$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'
ou
$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'
Outras dicas
A partir de a entrada manual para PDOStatement::bindParam
:
Com
bindParam
] DiferentePDOStatement::bindValue()
, a variável está vinculada como uma referência e só será avaliada no momento em quePDOStatement::execute()
é chamado.
Então, por exemplo:
$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'
ou
$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'
Aqui estão alguns em que posso pensar:
- Com
bindParam
, você só pode passar variáveis;não valores - com
bindValue
, você pode passar ambos (valores, obviamente, e variáveis) bindParam
funciona apenas com variáveis porque permite que parâmetros sejam dados como entrada/saída, por "referência" (e um valor não é uma "referência" válida em PHP) :é útil com drivers que (citando o manual):
Suporte a invocação de procedimentos armazenados que retornam dados como parâmetros de saída e alguns também como parâmetros de entrada/saída que enviam dados e são atualizados para recebê -los.
Com alguns mecanismos de banco de dados, os procedimentos armazenados podem ter parâmetros que podem ser usados tanto para entrada (fornecendo um valor do PHP para o procedimento) quanto para saída (retornando um valor do proc armazenado para o PHP);para vincular esses parâmetros, você deve usar bindParam e não bindValue.
A partir de Declarações preparadas e procedimentos armazenados
Usar bindParam
Para inserir várias linhas com uma ligação única:
<?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();
Para o propósito mais comum, você deve usar bindValue
.
bindParam
tem dois comportamentos complicados ou inesperados:
bindParam(':foo', 4, PDO::PARAM_INT)
não funciona, pois requer a passagem de uma variável (como referência).bindParam(':foo', $value, PDO::PARAM_INT)
vai mudar$value
Para cordas depois de correrexecute()
. Isso, é claro, pode levar a bugs sutis que podem ser difíceis de capturar.
Fonte: http://php.net/manual/en/pdostatement.bindparam.php#94711
Você não precisa mais lutar, quando existe uma maneira de Lilke isto:
$stmt = $pdo->prepare("SELECT * FROM someTable WHERE col = :val");
$stmt->execute([":val" => $bind]);
A maneira mais simples de colocar isso em perspectiva para memorização por comportamento (em termos de PHP):
bindParam:
referênciabindValue:
variável