Qual é a diferença entre PDOStatement::bindParam()
e PDOStatement::bindValue()
?
Qual é a diferença entre PDOStatement::bindParam()
e PDOStatement::bindValue()
?
Respostas:
A resposta está na documentação para bindParam
:
Diferente de PDOStatement :: bindValue (), a variável é vinculada como 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'
Na entrada manual paraPDOStatement::bindParam
:
[With
bindParam
] DiferentementePDOStatement::bindValue()
, a variável é vinculada como referência e será avaliada apenas no momento em quePDOStatement::execute()
é chamada.
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'
bindValue
você precisará vincular novamente os dados toda vez. Com bindParam
você só precisa atualizar a variável. A principal razão para o uso bindValue
seria dados estáticos, por exemplo, strings ou números literais.
Aqui estão alguns em que posso pensar:
bindParam
, você só pode passar variáveis; não valoresbindValue
, você pode passar ambos (valores, obviamente, e variáveis)bindParam
funciona apenas com variáveis porque permite que os parâmetros sejam dados como entrada / saída, por "referência" (e um valor não é uma "referência" válida em PHP) : é útil para os drivers que (citando o manual):suporta 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 para entrada (fornecendo um valor do PHP ao procedimento) e saída (retornando um valor do processo armazenado para o PHP); Para vincular esses parâmetros, você precisa usar o bindParam e não o bindValue.
De instruções preparadas e procedimentos armazenados
Use 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 objetivo mais comum, você deve usar bindValue
.
bindParam
tem dois comportamentos complicados ou inesperados:
bindParam(':foo', 4, PDO::PARAM_INT)
não funciona, pois requer passar uma variável (como referência).bindParam(':foo', $value, PDO::PARAM_INT)
mudará $value
para string após a execução execute()
. Obviamente, isso pode levar a erros sutis que podem ser difíceis de detectar.Fonte: http://php.net/manual/en/pdostatement.bindparam.php#94711
Você não precisa mais lutar, quando existe uma maneira como isto:
$stmt = $pdo->prepare("SELECT * FROM someTable WHERE col = :val");
$stmt->execute([":val" => $bind]);