Description of the problem
The error message you are receiving is because you are not correctly handling errors that may occur during SQL queries.
Call to a member function bind_param()
on boolean
It is telling you that in the line $stmt2->bind_param()
the variable $stmt2
contains a Boolean data and not a mysqli resource with a SQL query.
That's because the call to $db->prepare()
failed:
Return values: mysqli_prepare()
returns a statement object or FALSE
if an error occurs.
Managing errors
To see the error messages that occur, you must change the code as follows:
$stmt2 = $db->prepare("
INSERT INTO puntuacion (
id_actividad,
id_usuario_docente,
id_usuario_evaluador,
puntuacion_obtenida,
puntuacion_evaluada,
observacion,
fecha
) VALUES (
?,
?,
?,
?,
?,
?,
now()
)
");
/* Si falló la consulta mostramos el mensaje de error */
if ($stmt2 === false) {
die($db->error);
}
The same must be done after the $stmt2->execute()
(it also returns false
in case of error):
if ($stmt2->execute() === false) {
die($stmt2->error);
}
You must do this with $stmtp
as well as $stmtp2
.
Root of the problem
Also, when you are going to perform nested queries you must download the buffer from the previous query by $stmt->store_result()
:
/* Primero ejecutamos la consulta (verificando si falló) */
$stmt->execute();
/* Después almacenamos el resultado */
$stmt->store_result();
/* Por último asociamos los campos con variables para el fetch() */
$stmt->bind_result($id_actividad);
/* Ahora podemos trabajar con los resultados */
while ($stmt->fetch()) { ... }
The order is important and there is a note in the $mysqli::bind_result()
documentation that states it this way:
Note: Note that all columns must be linked after calling mysqli_stmt_execute()
and before calling mysqli_stmt_fetch()
.
Remaining the code as follows:
<?php
error_reporting(E_ALL);
require_once 'conexion.php';
$obj = json_decode(file_get_contents('php://input'));
$stmt = $db->prepare("
INSERT INTO usuario (
id_rol,
nombre,
apellidoP,
apellidoM,
correo,
pass,
campus
) VALUES (
?,
?,
?,
?,
?,
?,
?
)"
);
/* Si falló la consulta mostramos el mensaje de error */
if ($stmt === false) {
die($db->error);
}
$stmt->bind_param('issssss',
$obj->id_rol,
$obj->nombre,
$obj->apellidoP,
$obj->apellidoM,
$obj->correo,
$obj->pass,
$obj->campus
);
if ($stmt->execute() === false) {
die($stmt->error);
}
/* Obtenemos el id de la inserción */
$idGenerado = $stmt->insert_id;
/* Ya no necesitamos de nuevo la consulta preparada */
$stmt->close();
if($obj->id_rol == 3) {
$stmt = $db->prepare("SELECT id_actividad FROM actividad");
/* Si falló la consulta mostramos el mensaje de error */
if ($stmt === false) {
die($db->error);
}
if ($stmt->execute() === false) {
die($stmt->error);
}
/* Descargamos los datos para poder hacer consultas anidadas */
$stmt->store_result();
/* Asignamos a $id_actividad el campo por cada fetch() */
$stmt->bind_result($id_actividad);
/* Iteramos los resultados */
while ($stmt->fetch()) {
echo $id_actividad, " ", $idGenerado, PHP_EOL;
$evaluador = 27;
$puntuacion1 = 0;
$puntuacion2 = 0;
$observacion = "0";
$stmt2 = $db->prepare("
INSERT INTO puntuacion (
id_actividad,
id_usuario_docente,
id_usuario_evaluador,
puntuacion_obtenida,
puntuacion_evaluada,
observacion,
fecha
) VALUES (
?,
?,
?,
?,
?,
?,
now()
)
");
/* Si falló la consulta mostramos el mensaje de error */
if ($stmt2 === false) {
die($db->error);
}
$stmt2->bind_param('siiiis',
$id_actividad,
$idGenerado,
$evaluador,
$puntuacion1,
$puntuacion2,
$observacion
);
if ($stmt2->execute() === false) {
die($stmt2->error);
}
$stmt2->close();
}
$stmt->close();
}
echo "registro almacenado";