¿Cuál es la diferencia entre PDOStatement::bindParam()
y PDOStatement::bindValue()
?
¿Cuál es la diferencia entre PDOStatement::bindParam()
y PDOStatement::bindValue()
?
Respuestas:
La respuesta está en la documentación para bindParam
:
A diferencia de PDOStatement :: bindValue (), la variable está vinculada como referencia y solo se evaluará en el momento en que se llame a PDOStatement :: execute ().
Y execute
llame a PDOStatement :: bindParam () para vincular variables PHP a los marcadores de parámetros: las variables vinculadas pasan su valor como entrada y reciben el valor de salida, si lo hay, de sus marcadores de parámetros asociados
Ejemplo:
$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'
o
$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'
De la entrada manual paraPDOStatement::bindParam
:
[Con
bindParam
] A diferenciaPDOStatement::bindValue()
, la variable está vinculada como referencia y solo se evaluará en el momento en quePDOStatement::execute()
se llame.
Así por ejemplo:
$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'
o
$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
necesitaría volver a vincular los datos cada vez. Con bindParam
solo necesitas actualizar la variable. La razón principal para usar bindValue
sería datos estáticos, por ejemplo, cadenas literales o números.
Aquí hay algunos en los que puedo pensar:
bindParam
, solo puede pasar variables; no valoresbindValue
, puede pasar ambos (valores, obviamente, y variables)bindParam
funciona solo con variables porque permite que los parámetros se den como entrada / salida, por "referencia" (y un valor no es una "referencia" válida en PHP) : es útil con controladores que (citando el manual):admite la invocación de procedimientos almacenados que devuelven datos como parámetros de salida, y algunos también como parámetros de entrada / salida que envían datos y se actualizan para recibirlos.
Con algunos motores de base de datos, los procedimientos almacenados pueden tener parámetros que se pueden usar tanto para la entrada (dando un valor de PHP al procedimiento) como para la salida (devolviendo un valor del proceso almacenado a PHP); para vincular esos parámetros, debe usar bindParam y no bindValue.
De declaraciones preparadas y procedimientos almacenados
Se usa bindParam
para insertar varias filas con un enlace único:
<?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 el propósito más común, debe usar bindValue
.
bindParam
tiene dos comportamientos difíciles o inesperados:
bindParam(':foo', 4, PDO::PARAM_INT)
no funciona, ya que requiere pasar una variable (como referencia).bindParam(':foo', $value, PDO::PARAM_INT)
cambiará $value
a cadena después de ejecutarse execute()
. Esto, por supuesto, puede conducir a errores sutiles que pueden ser difíciles de atrapar.Fuente: http://php.net/manual/en/pdostatement.bindparam.php#94711
No tiene que luchar más, cuando existe una forma de evitar esto:
$stmt = $pdo->prepare("SELECT * FROM someTable WHERE col = :val");
$stmt->execute([":val" => $bind]);