Error PDOStatement :: bindParam ()

1

In response to the advice you gave me in the question I asked a few days ago ( Update records using PDO ) I am changing the code to avoid SQL injection with PHP.

The issue is that when I run the update page I get the following error:

  

PDOStatement :: bindParam () expects at most 5 parameters, 15 given   Message: SQLSTATE [HY093]: Invalid parameter number: no parameters were bound

The code is as follows:

<?php

    // Incluimos la clase conexión para crear una que herede de Conexion
    require("conexion.php");

    /*
    * Clase modificar cliente que hereda las propiedades de la clase conexion
    */
   class ModificarCliente extends Conexion {

       // Constructor de la clase
       function __construct(){

           // Constructor de la super clase
           parent::__construct();

       }

    // Método para guardar las modificaciones del cliente
    public function ModificarCliente($datos) {

       // try and catch para capturar errores
       try {

           // Comprobamos que los campos no están vacíos
           if(empty($_POST)){

               echo "Los campos están vacíos, no se puede actualizar.";

           } else {

                // Si no están vacíos guardamos en la variable sql la sentencia de actualización
                $sql = "UPDATE clientes SET
                            nombre = ?,
                            apellidos = ?,
                            alias = ?,
                            telefono = ?,
                            movil = ?,
                            email = ?,
                            direccion = ?,
                            poblacion = ?,
                            provincia = ?,
                            codigopostal = ?,
                            tratamientocapilar = ?,
                            tratamientocorporal = ?,
                            observaciones = ?
                        WHERE idclientes = ?";

           }

            var_dump($datos);

            // Guardamos la variable SQL y preparamos la consulta con la conexion de la base de datos
            $query = $this->conexion_db->prepare($sql);

            // Ligamos parámetros marcadores (?,?,?,... es decir, $datos[nombre], $datos[apellidos], ...)
            // Especificación de tipos de caracteres
            //i->la variable correspondiente es de tipo entero
            //d->la variable correspondiente es de tipo double
            //s->la variable correspondiente es de tipo string
            //b->la variable correspondiente es un blob y se envía en paquetes

        $query->bindParam(1, $datos['nombre'], PDO::PARAM_STR);
        $query->bindParam(2, $datos['apellidos'], PDO::PARAM_STR);
        $query->bindParam(3, $datos['alias'], PDO::PARAM_STR);
        $query->bindParam(4, $datos['telefono'], PDO::PARAM_STR);
        $query->bindParam(5, $datos['movil'], PDO::PARAM_STR);
        $query->bindParam(6, $datos['email'], PDO::PARAM_STR);
        $query->bindParam(7, $datos['direccion'], PDO::PARAM_STR);
        $query->bindParam(8, $datos['poblacion'], PDO::PARAM_STR);
        $query->bindParam(9, $datos['provincia'], PDO::PARAM_STR);
        $query->bindParam(10, $datos['codigopostal'], PDO::PARAM_STR);
        $query->bindParam(11, $datos['tratamientocapilar'], PDO::PARAM_STR);
        $query->bindParam(12, $datos['tratamientocorporal'], PDO::PARAM_STR);
        $query->bindParam(13, $datos['observaciones'], PDO::PARAM_STR);
        $query->bindParam(14, $datos['idcliente'], PDO::PARAM_STR);

        // Ejecutamos la consulta y la guardamos en un array
        $query->execute();

            // Guardamos el resultado en una variable
            $resultado = $query;

            // Cerramos la query
            $query->closeCursor();

            // Devolvemos los resultados a la función
            return $resultado;

            // Vaciamos el objeto
            $this->conexion_db = null;

         } catch (Exception $e) {

           echo "Error en la ejecución de la consulta<br>";
           echo "Mensaje: " . $e->GetMessage() . "<br>";
           echo "Línea: " . $e->getLine();

       }

    }
}
?>

I run var_dump($datos) and var_dump($resultado) to verify that if you are taking the data correctly and this is what it shows:

array (size=16)
  'idcliente' => string '10' (length=2)
  'nombre' => string 'Alicia' (length=6)
  'apellidos' => string 'a' (length=1)
  'alias' => string 'Alicia' (length=6)
  'telefono' => string '222' (length=3)
  'movil' => string '3333' (length=4)
  'email' => string '[email protected]' (length=7)
  'direccion' => string 'a' (length=1)
  'poblacion' => string 'a' (length=1)
  'provincia' => string 'a' (length=1)
  'codigopostal' => string '1' (length=1)
  'tratamientocapilar' => string '1' (length=1)
  'tratamientocorporal' => string '555' (length=3)
  'observaciones' => string '444' (length=3)
  'enviar' => string 'Salvar' (length=6)
  'idclientes' => null

object(PDOStatement)[3]
  public 'queryString' => string 'UPDATE clientes SET

                            nombre = ?,

                            apellidos = ?,

                            alias = ?,

                            telefono = ?,

                            movil = ?,

                            email = ?,

                            direccion = ?,

                            poblacion = ?,

                            provincia = ?,

                            codigopostal = ?,

                            tratamientocapilar = ?,

           '... (length=646)

Edited after correctly including the bindParam method

I have corrected the code to correctly include bindParam for PDO, and it does not show any errors, but it does not update the data in the database and I do not know where the fault may be.

With the data of var_dump that you can see I see that the data that I use to go to the record idclientes is like NULL . The data in the database is of integer type and I have tried to put the text as an integer but when I do a gettype it tells me that it is type string .

Can the fault come from there?

Edited after being fixed

I have already encountered the problem, I was not looking correctly at the input idcliente , I had it in the plural in the marker at position 14 of bindParam .

    
asked by David 29.12.2016 в 17:35
source

3 answers

2

PDOStatement::bindParam() can not receive sss... as parameters.

This syntax is used in the mysqli preparations.

What you can do is change your $query->bindParam( ... ) to:

$query->bindParam(1, $datos['nombre'], PDO::PARAM_STR);
$query->bindParam(2, $datos['apellidos'], PDO::PARAM_STR);
$query->bindParam(3, $datos['alias'], PDO::PARAM_STR);
$query->bindParam(4, $datos['telefono'], PDO::PARAM_STR);
$query->bindParam(5, $datos['nombre'], PDO::PARAM_STR);
$query->bindParam(6, $datos['movil'], PDO::PARAM_STR);
$query->bindParam(7, $datos['direccion'], PDO::PARAM_STR);
$query->bindParam(8, $datos['poblacion'], PDO::PARAM_STR);
$query->bindParam(9, $datos['provincia'], PDO::PARAM_STR);
$query->bindParam(10, $datos['codigopostal'], PDO::PARAM_STR);
$query->bindParam(11, $datos['tratamientocapilar'], PDO::PARAM_STR);
$query->bindParam(12, $datos['tratamientocorporal'], PDO::PARAM_STR);
$query->bindParam(13, $datos['observaciones'], PDO::PARAM_STR);
$query->bindParam(14, $datos['idclientes'], PDO::PARAM_STR);
    
answered by 29.12.2016 / 18:17
source
1

The error is telling you what is wrong:

  

PDOStatement :: bindParam () expects at most 5 parameters, 15 given

You are passing through 15 parameters when you should only pass 5.

From the PHP documentation , these are the parameters you should to pass him:

  • parameter

    The identifier of the parameter. For prepared statements that use named substitution parameters, this will be a parameter name with the form: name. For prepared statements that use question mark substitution parameters, this will be the index-1 position of the parameter.

  • variable

    Name of the PHP variable to be linked to the parameter of the SQL statement.

  • data_type

    The explicit data type for the parameter, using the PDO :: PARAM_ * constants. To return an INOUT parameter from a stored procedure, the bitwise OR operator must be used to set the PDO :: PARAM_INPUT_OUTPUT bits for the data_type parameter.

  • length

    The length of the data type. To indicate that the parameter is an OUT parameter of a stored procedure, the length must be explicitly set.

  • driver_options

answered by 29.12.2016 в 17:44
1

You can use the syntax :variable and PDOStatement::execute to pass an associative array, for example:

$gsent = $gbd->prepare('SELECT name, colour, calories
FROM fruit
WHERE calories < :calories AND colour = :colour');
$gsent->execute(array(':calories' => $calorías, ':colour' => $color));

Applied to your code:

$sql = "UPDATE clientes SET
          nombre = :nombre,
          apellidos = :apellidos,
          alias = :alias,
          telefono = :telefono,
          movil = :movil,
          email = :email,
          direccion = :direccion,
          poblacion = :poblacion,
          provincia = :provincia,
          codigopostal = :codigopostal,
          tratamientocapilar = :tratamientocapilar,
          tratamientocorporal = :tratamientocorporal,
          observaciones = :observaciones
          WHERE idclientes = :idcliente";

 // ...codigo...

 $query = $this->conexion_db->prepare($sql);

 // Eliminamos el valor que esta de mas
 unset($datos['enviar']);

 // Pasamos el arreglo con exactamente los datos a mapearse
 $query->execute($datos);
    
answered by 29.12.2016 в 17:54