Greetings community. I'm developing an application using PDO, I'm just starting out and I've had a problem inserting records into the database. Next I put the functions that I am using and the error that it is giving me.
First my controller receives the data as follows:
public function agregar(){
if(!$_POST){
$datos = $this->seccion->listar();
return $datos;
}else{
$permitidos = array("image/jpeg", "image/png", "image/gif", "image/jpg"); // valido los formatos de imagen permitidos
$limite = 700;
if(in_array($_FILES['imagen']['type'], $permitidos) && $_FILES['imagen']['size'] <= $limite * 1024){ //valido si el formato y el peso son aceptados
$nombre = $_FILES['imagen']['name'] . date('is'); //creo el nombre de la imagen
$ruta = "Views" . DS . "templates" . DS . "imagenes" . DS . $nombre; //asigno la ruta de la imagen
move_uploaded_file($_FILES['imagen']['tmp_name'], $ruta);
$this->estudiante->set("nombre" , $_POST['nombre']);
$this->estudiante->set("edad" , $_POST['edad']);
$this->estudiante->set("promedio" , $_POST['promedio']);
$this->estudiante->set("imagen" , $nombre);
$this->estudiante->set("id_seccion" , $_POST['id_seccion']);
$this->estudiante->add();
echo error_reporting();
}
}
}
Then that data is received by the set() function that is in my models
public function set($atributo, $contenido){
$this->$atributo = $contenido;
}
Which passes that data to my add() function on the model
public function add(){
$sql = "INSERT INTO estudiantes(nombres, edad, promedio, img, id_seccion)
VALUES(:nombre, :edad, :promedio, :imagen, :id_seccion)";
$params = [':nombre' => $this->nombre];
$params = [':edad' => $this->edad];
$params = [':promedio' => $this->promedio];
$params = [':imagen' => $this->imagen];
$params = [':id_seccion' => $this->id_seccion];
$this->con->consultaSimple($sql, $params);
}
Finally I execute the query with this function
public function consultaSimple($sql, $binds = []){
$datos = $this->con->prepare($sql);
foreach ($binds as $key => $val) {
$datos->bindParam($key, $val);
}
$datos->execute();
}
Those are all the functions that I use to insert, the error that is generating me is the following:
Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens in C:\xampp\htdocs\pdo\Models\Conexion.php on line 25 22527
I clarify that the line where the error is thrown is in the Simple Query function in the execute() The truth is that I have not been able to resolve this error and I have given it many turns and have not been successful.
edited answer
Good point the one delimited by @xerif in his comment to this answer, for which I retract the following:
I think you're drowning in a glass of water. The problem is thatconsultaSimple($sql, $binds = [])
you clean your array by doing$binds=[]
, that is, the function interprets that the parameter is always an empty array.Actually, as Xerif says, the array was being overwritten and that would be the main reason for the error.
However, I stand by my answer as to the following:
I don't see much use in passing the code to a method just to prepare and execute the query, taking into account that
prepare
andexecute
are already PDO's own methods.Much less do I see the point of doing the binding through a loop
for
(although you are free to do it that way if you wanted to). I say this because in PDO (and that's one of its wonders compared to mysqli), you can pass the array with the parameters directly in theexecute
, without usingbindValue
.I would focus more on improving the function
add
, for example, controlling what happens in it, its possible errors and making it return a result, be it the number of inserted rows or an error message. Also the functionadd
could be more global, giving it, and notconsultaSimple
, the ability to receive the SQL statement and parameters.For example:
This way the method
add
can be used from anywhere.Clearly the error is in the function
add()
, note that you are overwriting $param all the time, so in the end you only send a single value toconsultaSimple()
This part
it should stay like this