2011-04-16 28 views
13

¿Hay alguna manera de poner estas declaraciones bindParam en una sola declaración?PDO bindParam en una declaración?

$q = $dbc -> prepare("INSERT INTO accounts (username, email, password) VALUES (:username, :email, :password)"); 
$q -> bindParam(':username', $_POST['username']); 
$q -> bindParam(':email', $_POST['email']); 
$q -> bindParam(':password', $_POST['password']); 
$q -> execute(); 

que estaba usando mysqli preparados antes de donde fue posible, me pasa a PDO para el apoyo assoc_array. En el sitio web de php.net para PDO, los muestra en líneas separadas, y en todos los ejemplos que he visto están en líneas separadas.

¿Es posible?

+0

para assoc_array support? ¿No te refieres a los marcadores de posición nombrados? –

+0

Simplemente curioso, ¿vas a usarlo siempre de esta manera? ninguna función auxiliar y tal? –

+0

Recién comencé a usar PDO hoy, no tengo idea de qué es una función auxiliar, si me lo explicas amablemente. – Basic

Respuesta

22

Ejemplo 2 de la página execute es lo que quiere:

$sth->execute(array(':calories' => $calories, ':colour' => $colour)); 

Es posible que desee ver en los otros ejemplos también. Con los parámetros de signo de interrogación, sería:

$q = $dbc -> prepare("INSERT INTO accounts (username, email, password) VALUES (?, ?, ?)"); 
$q->execute(array($_POST['username'], $_POST['email'], $_POST['password'])); 

Si esas son las únicas columnas, sólo puede escribir:

$q = $dbc -> prepare("INSERT INTO accounts VALUES (?, ?, ?)"); 
$q->execute(array($_POST['username'], $_POST['email'], $_POST['password'])); 
+0

Gracias por esta, también una última pregunta, tengo una consulta SELECT en la que solo se necesita un marcador de posición: correo electrónico, sería mejor almacenarlo en una matriz, eliminando la línea de código bindParam de la ecuación, pero la matriz solo almacenará 1 variable ya que tengo solo un marcador de posición: el correo electrónico, ¿cuál es mejor? – Basic

+0

@Basic, tiendo a usar una matriz independientemente. Yo también prefiero? marcadores de posición. Sin embargo, ambos son subjetivos. –

4

función auxiliar es una función que hace que te ayudan a evitar la escritura montón de repetitivo código cada vez que quiera ejecutar una consulta.
Esto se llama "programación" y casi no hay nada en este sitio, al menos bajo la etiqueta "PHP".
Mientras que muchos peiople piensan que la programación significa copiar/pegar trozos de código de ejemplos manuales, es algo diferente. Aunque es difícil de aprender pero realmente vale la pena, especialmente si te estás dedicando al desarrollo web.

Como se puede ver, hay una respuesta aceptada hizo ninguna ayuda real para ti, ya que todavía tiene que escribir algo como

$sth->execute(array(':username' => $_POST['username'], 
        ':email' => $_POST['email'] 
        ':password' => $_POST['password']); 

tantas veces como muchos campos de la tabla, por lo que no hay mucha diferencia de su enfoque inicial, aún le hace escribir cada nombre de campo CUATRO veces.

Pero al ser un programador, puede usar los poderes de programación. Un bucle, por ejemplo, uno de los operadores de programación angular.
Cada vez que ves repeticiones, sabes que debe haber un ciclo.

por ejemplo, puede configurar una lista de campos, nombrándolos solo una vez. Y deje que un programa haga el resto.

por ejemplo, una función tal como éste

function pdoSet($fields, &$values, $source = array()) { 
    $set = ''; 
    $values = array(); 
    if (!$source) $source = &$_POST; 
    foreach ($fields as $field) { 
    if (isset($source[$field])) { 
     $set.="`$field`=:$field, "; 
     $values[$field] = $source[$field]; 
    } 
    } 
    return substr($set, 0, -2); 
} 

está dando una serie de nombres de campos, puede producir tanto instrucción de inserción y la matriz de datos para usted. Programado. Por lo tanto, su código se convierten en no más de estas 3 líneas cortas:

$fields = array('username', 'email', 'password'); 
$stmt = $dbh->prepare("INSERT INTO accounts SET ".pdoSet($fields,$values)); 
$stmt->execute($values); 
+0

¡Respuesta impresionante! Probaré esto :) Y nunca copio y pego, pero tengo unos pocos peldaños en la escalera inferior a tu atm: p – Basic

+0

No necesitas repetir los nombres de campo si usas marcadores de posición '?', Que I * did * mention (y que se muestra en los ejemplos que recomendé). –

+1

@Matthew '?' Marcadores de posición es solo un lugar de CUATRO. Por favor, no pierdas tu tiempo con comentarios. Un fragmento para producir tanto conciso como utilizable en el código REAL LIFE será suficiente. –

1

Personalmente, yo prefiero usar una función de contenedor para todos DOP, lo que simplifica considerablemente el código necesario.

Por ejemplo, para ejecutar consultas con destino (bueno, todas mis preguntas), hago esto:

$iterable_resultset = query("INSERT INTO accounts (username, email, password) VALUES (:username, :email, :password)", array(':username'=>'bob', ':email'=>'[email protected]', ':password'=>'bobpassword')); 

Tenga en cuenta que no sólo es el sql simplemente una cadena, pero en realidad es una cadena reutilizable, ya que simplemente puede pasar el sql como una cadena y cambiar la matriz de variables para pasar si desea realizar una inserción similar inmediatamente después de esa (no aplicable a esta situación, pero aplicable a otros casos de uso sql).

El código que utilizo para crear esta función de contenedor es de la siguiente manera:

/** 
* Run bound queries on the database. 
* 
* Use: query('select all from players limit :count', array('count'=>10)); 
* Or: query('select all from players limit :count', array('count'=>array(10, PDO::PARAM_INT))); 
* 
* Note that it returns foreachable resultset object unless an array is specifically requested. 
**/ 
function query($sql, $bindings=array(), $return_resultset=true) { 
DatabaseConnection::getInstance(); // Gets a singleton database connection 
$statement = DatabaseConnection::$pdo->prepare($sql); // Get your pdo instance, in this case I use a static singleton instance. You may want to do something simpler. 

foreach ($bindings as $binding => $value) { 
if (is_array($value)) { 
$first = reset($value); 
$last = end($value); 
// Cast the bindings when something to cast to was sent in. 
$statement->bindParam($binding, $first, $last); 
} else { 
$statement->bindValue($binding, $value); 
} 
} 

$statement->execute(); 

if ($return_resultset) { 
return $statement; // Returns a foreachable resultset 
} else { 
// Otherwise returns all the data an associative array. 
return $statement->fetchAll(PDO::FETCH_ASSOC); 
} 
} 

// Wrapper to explicitly & simply get a multi-dimensional array. 
function query_array($sql_query, $bindings=array()) { 
return query($sql_query, $bindings, false); // Set return_resultset to false to return the array. 
} 

Como se señaló en los comentarios, que te gustaría utilizar su propio método para establecer una conexión de base de datos y obtener una inicializado pdo, pero en general permite cortar el sql encuadernado a solo una línea.

3

+1 a Matthew Flaschen por la respuesta aceptada, pero le mostraré otro consejo. Si utiliza parámetros SQL con nombres iguales a las entradas de $ _POST, se podría aprovechar el hecho de que $ _POST es ya una matriz:

$q->execute($_POST); 

Los nombres de los parámetros SQL tienen el prefijo dos puntos (:) pero las claves en la matriz $ _POST no lo son. Pero las versiones modernas de PDO tienen en cuenta esto: ya no es necesario usar prefijos de dos puntos en las teclas de la matriz que pasa a execute().

Pero debe tener cuidado de que cualquiera pueda agregar parámetros adicionales a cualquier solicitud web, y debe obtener solo el subconjunto de params $ _POST que coincidan con los parámetros en su consulta.

$q = $dbc -> prepare("INSERT INTO accounts (username, email, password) 
    VALUES (:username, :email, :password)"); 
$params = array_intersect_key($_POST, array("username"=>1,"email"=>1,"password"=>1)); 
$q->execute($params); 
4

su sentido común es totalmente correcto que el objetivo de la codificación es salvar a escribir ... pero su solución no ayuda con el bit BindParams. No pude encontrar nada más sobre esto en línea, así que aquí hay algo que finalmente me convenció para trabajar: ¡espero que sea útil para alguien!

//First, a function to add the colon for each field value. 
function PrepareString($array){ 
//takes array (title,author); 
//and returns the middle bit of pdo update query :title,:author etc 
    foreach($array as $k =>$v){ 
     $array[$k]=':'.$v; 
    } 
    return implode(', ', $array); 
} 

Entonces ...

function PdoInsert($table_name,$array){ 

    $db = new PDO(); //however you create your own pdo 

//get $fields and $vals for statement 
    $fields_vals=array_keys($array); 
    $fields=implode(',',$fields_vals); 
    $vals=PrepareString($fields_vals); 
    $sql = "INSERT INTO $table_name($fields) VALUES ($vals)"; 

    $qwe=$db->prepare($sql); 


    foreach ($array as $k =>$v){ 
     //add the colon to the key 
     $y=':'.$k; 
     //god knows why it doesn't like $qwe->bindParam($y,$v,PDO::PARAM_STR); 
     // but it really doesn't! So we refer back to $array. 
     //add checks for different binding types here 

(ver PDO::PARAM_INT is important in bindParam?)

 $qwe->bindParam($y,$array[$k],PDO::PARAM_STR); 

    } 
    if ($qwe->execute()==true){ 
     return $db->lastInsertId(); 
    } 
    else { 
     return $db->errorCode(); 
    } 
} 

A continuación, puede insertar cualquier cosa por hacer

PdoInsert('MyTableName',array('field1'=>$value1,'field2'=>$value2...)); 

Tener previamente desinfectados sus valores de curso .

Cuestiones relacionadas