PDO - UPDATE - PHP

0

I have a problem with an UPDATE, to simplify the data I take it from a form and they pass it as parameters to a function, I do the UPDATE and when it does the execute () it tells me that if it was done, but it never does the modification.

    global $conn;
    $producto = $conn->prepare
    ("UPDATE productos SET nombre = ?, precio = ?,
     marca = ?, presentacion = ?, stock = ? WHERE idproducto = ?");

    $producto->bindValue(1, $id);
    $producto->bindValue(2, $nombre);
    $producto->bindValue(3, $precio);
    $producto->bindValue(4, $marca);
    $producto->bindValue(5, $presentacion);
    $producto->bindValue(6, $stock);

   if($producto->execute())
    {
        $respuesta = "El articulo se actualizo con exito";
        header("location: ". BACK_END_URL ."/?rta=".$respuesta."&color=verde");
    }
   else
   {
       $respuesta = "El articulo no se actualizo con exito";
       header("location: ". BACK_END_URL ."/?rta=".$respuesta."&color=rojo"); 
   } 

If you're wondering, the values of the database are well written as the table, as I say after the execute tells me that it did well but in the database nothing happened.

    
asked by Kurt Labras 24.10.2017 в 03:55
source

2 answers

0

Your UPDATE is dangerous and although you think nothing will happen, something very serious may happen: that the records that are not are being updated.

The variables must be passed in their order, even more if you are using bindValue with markers of position ( ? ).

I have highlighted position on purpose, because here the position is vital.

The Manual says about the order that should be observed when we use bindValue says:

  

For prepared sentences that use parameters of substitution of signs   of interrogation, this [the number used with bindValue] will be the index-1 position of the parameter.

If your query is written like this:

$producto = $conn->prepare
("UPDATE productos SET nombre = ?, precio = ?,
 marca = ?, presentacion = ?, stock = ? WHERE idproducto = ?");

And you use bindValue you must pass the values in this order:

  • name
  • price
  • brand
  • presentation
  • stock
  • product_id

That is:

$producto->bindValue(1, $nombre);
$producto->bindValue(2, $precio);
$producto->bindValue(3, $marca);
$producto->bindValue(4, $presentacion);
$producto->bindValue(5, $stock);
$producto->bindValue(6, $id);

But you are passing first, from what I see, the value that should correspond to id_producto ...

$producto->bindValue(1, $id);  //Este es el último ? de tu consulta ¿sí o no? No debería ser el 1º aquí
$producto->bindValue(2, $nombre);
$producto->bindValue(3, $precio);
$producto->bindValue(4, $marca);
$producto->bindValue(5, $presentacion);
$producto->bindValue(6, $stock);

What happens here is that in your UPDATE name will be equal to $id , price will be equal to name (or zero, who knows), brand will be equal to price ... and so and the record that will be updated will be the one with a id_producto equal to $stock

Your query if it is working, is updating the records that are not. Do you see the danger?

POST-DATA

In case you did not know, with PDO you can completely pass bindValue , creating an array with your values and passing that array in the execute .

Example:

   global $conn; //¿globales?... oh no
   $producto = $conn->prepare
    ("UPDATE productos SET nombre = ?, precio = ?,
     marca = ?, presentacion = ?, stock = ? WHERE idproducto = ?");

    /*array respetando el orden de cada valor*/
    $arrParams=array($nombre,$precio,$marca,$presentacion,$stock,$id);

    /*Pasamos el array en el execute*/
    if($producto->execute($arrParams))
    {
        $respuesta = "El articulo se actualizo con éxito. Filas afectadas:  ".$producto->rowCount();

        header("location: ". BACK_END_URL ."/?rta=".$respuesta."&color=verde");
    }
   else
   {
       $respuesta = "El articulo no se actualizo con exito";
       header("location: ". BACK_END_URL ."/?rta=".$respuesta."&color=rojo"); 
   } 
    
answered by 24.10.2017 в 04:18
0

What you mention happens normally when the query is executed but no row of the table complies with the conditions of the where.

That's why it runs correctly but does not change anything. Use rowcount to know if there were rows affected.

if ( $producto->execute() !== false && $producto->rowCount() > 0 )

Also the parameters are being passed in the wrong order.

You can do this to also make the code more secure:

 global $conn;
  $producto = $conn->prepare
  ("UPDATE productos SET nombre = :nombre, precio = :precio,
   marca = :marca, presentacion = :presentacion, stock = :stock WHERE idproducto = :idproducto");

  $producto->bindValue(':idproducto', $id, PDO::PARAM_INT);
  $producto->bindValue(':nombre', $nombre,PDO::PARAM_STR);
  $producto->bindValue(':precio', $precio, PDO::PARAM_STR);
  $producto->bindValue(':marca', $marca, PDO::PARAM_STR);
  $producto->bindValue(':presentacion', $presentacion, PDO::PARAM_STR);
  $producto->bindValue(':stock', $stock, PDO::PARAM_STR);

 if($producto->execute() !== false && $producto->rowCount() > 0)
  {
      $respuesta = "El articulo se actualizo con exito";
      header("location: ". BACK_END_URL ."/?rta=".$respuesta."&color=verde");
  }
 else
 {
     $respuesta = "El articulo no se actualizo con exito";
     header("location: ". BACK_END_URL ."/?rta=".$respuesta."&color=rojo"); 
 }
    
answered by 24.10.2017 в 05:32