es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Por qué esta consulta de mysql requiere la llamada PDO::prepare dos veces en php7 (pero no en php8)?

Tengo un fragmento de código sencillo:

$sql = “SELECT * FROM users”;
$stmt = $this->conn->prepare($sql);
$stmt->execute();
echo $stmt->rowCount();

Cuando se ejecuta con PHP7, se devuelve 0. Sin embargo, este resultado es incorrecto/inesperado. El resultado esperado es 15. Si se ejecuta el código anterior en PHP8 se obtiene el resultado esperado.

Si se duplica la línea $stmt = $this->conn->prepare($sql);, como se muestra en el siguiente código, se obtiene el valor correcto en PHP7.

$sql = “SELECT * FROM users”;
$stmt = $this->conn->prepare($sql);
$stmt = $this->conn->prepare($sql);
$stmt->execute();
echo $stmt->rowCount();

Mi conexión se establece de la siguiente manera:

$this->conn = new PDO(‘mysql:host=’ . DB_SERVER . ‘;dbname=’ . DB_NAME . ‘;charset=utf8’,
DB_USER, DB_PASS,
[PDO::MYSQL_ATTR_INIT_COMMAND => “SET NAMES utf8;SET time_zone = ‘” . TIMEZONE . “‘”]);

Es evidente que algo está mal ya que la segunda preparación no debería ser necesaria, pero no sé por dónde empezar. ¿Quizás estoy pasando por alto algo obvio?

Las versiones de PHP que estoy utilizando específicamente son:
PHP 7.2.34
PHP 8.0.8

Aclaración:
Me gustaría que se devuelvan las filas de usuarios (no la cantidad, que es solo para mostrar el problema). Con PHP7 no se obtienen filas, mientras que con PHP8 se obtienen todas las filas solicitadas/existentes.

Aclaración #2:
Sí, lo siento, intentaba proporcionar un ejemplo mínimo de trabajo. En realidad, recuperé e iteré a través de los usuarios. Sin embargo, para simplificar, actualmente solo estoy verificando la cantidad de filas/usuarios devueltos:

$users = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo count($users);

El uso de rowCount() estaba destinado a simplificar el problema.

Las versiones del controlador MySQL son:
mysql (mysqlnd 5.0.12-dev – 20150407)
mysql (mysqlnd 8.0.13)

Aclaración #3:
$stmt->execute(); devuelve falso. Lo siento, ha sido mi error.

Sin embargo, al ver esta pregunta, la salida de print_r($stmt->errorInfo()); es:

Array
(
[0] => 00000
[1] =>
[2] =>
)

He agregado lo siguiente a mi conexión de base de datos, pero no estoy obteniendo más información que la anterior.

$this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

Aclaración 4:
Falsa pista ya que “$pdo->errorInfo() se refiere a la última instrucción que se ejecutó correctamente” https://stackoverflow.com/a/12438685/1489538.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Problema con la ejecución de la declaración PDO execute() en PHP7

    El fragmento de código dado produce una salida inesperada al ejecutarse en PHP7. El código se supone que debe imprimir el número de filas de usuario devueltas, pero en PHP7, imprime 0 en lugar del valor esperado 15. Sin embargo, funciona bien en PHP8 y, si se duplica la línea $stmt = $this->conn->prepare($sql), como en el segundo bloque de código, se obtiene la salida esperada en PHP7.

    La conexión a la base de datos MySQL se establece utilizando la clase PDO. Las versiones del controlador MySQL son mysqlnd 5.0.12-dev - 20150407 para PHP7 y mysqlnd 8.0.13 para PHP8.

    El problema parece estar en el método execute() de la clase PDOStatement, que devuelve false en PHP7. Según la salida de print_r($stmt->errorInfo()), no hay mensaje de error.

    Para investigar más a fondo, se puede usar el método setAttribute() para establecer el modo de error en ERRMODE_EXCEPTION, lo que arrojará una excepción cuando ocurra un error. Esto puede proporcionar información de error más detallada sobre por qué execute() devuelve false.

    En general, parece que hay un error en la implementación de PDO en PHP7 que está causando este problema. Duplicar la declaración prepare() parece ser una solución temporal hasta que se solucione el error.

Comments are closed.