Preguntas de exception de PDO: cómo atraparlas

Estoy usando PDO para volver a escribir una interfaz de website para una database. Solía ​​usar la extensión mysql, pero nunca me había molestado con el event handling errores, y los pocos manejadores de errores que tenía eran básicamente copyr y pegar.

Ahora me gustaría hacer esto bien. Sin embargo, tengo problemas para detectar los errores de la forma en que me gustaría (errores como "Entrada duplicada", "Valor nulo", etc. en MySQL). ¿Cuánto de mi statement debe estar en el bloque de testing? ¿Debería estar todo allí? Estoy usando un Include() para conectarme a mi DB (que tiene su propio event handling errores), por lo que solo la ejecución de la consulta tiene errores en este código. No puedo entender por qué no se está cometiendo un error al ejecutar el siguiente código:

 try { $stmt = $db->prepare("INSERT INTO tbl_user (id, name, password, question, answer) VALUES (NULL, :name, :password, :question, :answer)"); $stmt->bindValue(":name", $_POST['name']); $stmt->bindValue(":password", $_POST['password']); $stmt->bindValue(":question", $_POST['question']); $stmt->bindValue(":answer", $_POST['answer']); $stmt->execute(); echo "Successfully added the new user " . $_POST['name']; } catch (PDOException $e) { echo "The user could not be added.<br>".$e->getMessage(); } 

Entonces mis preguntas: ¿TODO TIENE que estar en el bloque de testing? ¿Puedo simplemente poner la ejecución en el bloque de testing? Debería captar el error Duplicate value "John" in key "name" , pero en su lugar continuará con el post de éxito. (Al intentar agregar dos usuarios "John"). Revisé en PHPMyAdmin; el índice es único y arroja el error como se esperaba, simplemente no usa este código.

Deberías mirar la documentation. Pero si no encuentras nada, puedes agregar otro truco:

 <?php try { $stmt = $db->prepare("INSERT INTO tbl_user (id, name, password, question, answer) VALUES (NULL, :name, :password, :question, :answer)"); $stmt->bindValue(":name", $_POST['name']); $stmt->bindValue(":password", $_POST['password']); $stmt->bindValue(":question", $_POST['question']); $stmt->bindValue(":answer", $_POST['answer']); $stmt->execute(); echo "Successfully added the new user " . $_POST['name']; } catch (PDOException $e) { echo "DataBase Error: The user could not be added.<br>".$e->getMessage(); } catch (Exception $e) { echo "General Error: The user could not be added.<br>".$e->getMessage(); } ?> 

Esto debe funcionar porque todas las excepciones de los complementos PHP henetworkingan de la class PHP nativa Exception. (Desde 5.0 si mi memory está bien).

Preguntas de exception de PDO: cómo atraparlas

Como una regla –

NO los atrape .

Por ejemplo, su código aquí debe escribirse de esta manera

 $stmt = $db->prepare("INSERT INTO tbl_user (id, name, password, question, answer) VALUES (NULL, :name, :password, :question, :answer)"); $stmt->bindValue(":name", $_POST['name']); $stmt->bindValue(":password", $_POST['password']); $stmt->bindValue(":question", $_POST['question']); $stmt->bindValue(":answer", $_POST['answer']); $stmt->execute(); echo "Successfully added the new user " . $_POST['name']; 

sin ningún bash o atrapar llamadas. Porque no tiene un escenario particular para manejar una exception aquí (un eco simple apenas count como un escenario de manejo).

En su lugar, permita que suba al manejador de errores de toda la aplicación (no se asuste con el término, PHP ya tiene uno incorporado).

Sin embargo, tengo problemas para detectar los errores de la forma en que me gustaría (errores como "Entrada duplicada", "Valor nulo", etc. en MySQL).

Solo en caso de que tenga un cierto escenario , debe usar el operador try-catch, pero siempre debe verificar si el error que obtuvo es el esperado. De lo contrario, una exception debe ser relanzada:

 try { $pdo->prepare("INSERT INTO users VALUES (NULL,?,?,?,?)")->execute($data); } catch (PDOException $e) { if ($e->getCode() == 1062) { // Take some action if there is a key constraint violation, ie duplicate name } else { throw $e; } } 

y por supuesto (ya que resultó ser el problema principal para esta pregunta), debe configurar PDO en modo de exception, ya sea en un parámetro constructor simplemente agregando el código

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

justo después de conectar.

    Intereting Posts