¿Cuál es la diferencia entre bindParam y bindValue?

Respuestas:

190

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'
acrosman
fuente
667

De la entrada manual paraPDOStatement::bindParam :

[Con bindParam] A diferencia PDOStatement::bindValue(), la variable está vinculada como referencia y solo se evaluará en el momento en que PDOStatement::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'
solitario
fuente
99
Brillante, gracias! Pregunta: ¿por qué querrías usar uno sobre el otro? Por ejemplo, ¿cuándo sería útil o necesario evaluar el parámetro de enlace solo en el momento execute ()?
Coldblackice
32
@Coldblackice Si estaba ejecutando la consulta varias veces con datos diferentes. Con bindValuenecesitaría volver a vincular los datos cada vez. Con bindParamsolo necesitas actualizar la variable. La razón principal para usar bindValuesería datos estáticos, por ejemplo, cadenas literales o números.
solitario el
1
Por ejemplo, desea usar bindValue con valores de retorno de función: $ stmt-> bindValue (': status', strtolower ($ status), PDO :: PARAM_STR);
paidforbychrist
1
quería votar, pero como es 666, lo dejaré
eddy147
219

Aquí hay algunos en los que puedo pensar:

  • Con bindParam, solo puede pasar variables; no valores
  • con bindValue, puede pasar ambos (valores, obviamente, y variables)
  • bindParamfunciona 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.

Pascal MARTIN
fuente
@PascalMartin Justo lo que quería saber, ¿puede vincular valores con bindParam? Salud.
yehuda
1
Todavía no tengo idea de lo que eso significa exactamente, cuáles son exactamente las variables y cuáles son los valores. ¡Utilizo bindParam para vincular un valor a un marcador de posición y con bindValue puedo hacer lo mismo! - en mi ejemplo al menos ...
Richard
29

De declaraciones preparadas y procedimientos almacenados

Se usa bindParampara 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();
Nezar Fadle
fuente
27

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á $valuea 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

Denilson Sá Maia
fuente
4

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]); 
Thielicious
fuente
4

La forma más simple de poner esto en perspectiva para la memorización por comportamiento (en términos de PHP):

  • bindParam: referencia
  • bindValue: variable
tfont
fuente