2017-10-03 10 views
0

Voici un SQL non valide et je m'attends à une erreur, mais l'erreur PDO semble toujours 00000, qu'est-ce que j'ai fait de mal?L'exécution d'une mauvaise requête PDO ne génère pas d'erreur

<?php 
run('select now()'); 
run('pls give me an error'); 

function run($sql) { 
    $pdo = new PDO('mysql:host=localhost;db=mydb', $user, $pass); 
    echo $sql . "<br>"; 
    $sth = $pdo->prepare($sql); 
    $sth->execute(); 
    $row = $sth->fetch(PDO::FETCH_ASSOC); 
    print_r($row); 
    print_r($pdo->errorInfo()); 
} 

Et voici le résultat:

select now() 
Array 
(
    [now()] => 2017-10-03 02:58:09 
) 
Array 
(
    [0] => 00000 
    [1] => 
    [2] => 
) 
pls give me an error 
Array 
(
    [0] => 00000 
    [1] => 
    [2] => 
) 

Mais j'ai une autre course page contre le même db et obtenir cette erreur:

Err 1064: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'please give me an error' at line 1

mis à jour

Le autre page est capable de produire une erreur utilise réellement le f uite:

$sth = $pdo->query($sql); 
print_r($pdo->errorInfo()); 

Répondre

1

Pour le syntaxiquement ou de toute autre manière incorrecte des déclarations préparées à vous jeter devez désactiver les instructions préparées émulation:

$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 

Par défaut PDO est configuré pour imiter ceux qui ne honnêtement pas avoir beaucoup de sens.

Lorsque la méthode émulée prépare est désactivée, la méthode PDO::prepare() crée un objet côté serveur temporaire qui contient une instruction préparée, puis l'exécute.

De plus, vous pouvez activer des exceptions PDO, de cette façon, il est plus difficile de ne pas gérer les échecs de requêtes inattendues:

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

Références:

+0

d'erreur bien, si cela selon votre façon: s'il y a erreur sur prepare(), je dois attraper erreur sur execute() - Je n'ai jamais eu cette situation auparavant, et imagin im en cours d'exécution de 2 pages sur la même DB, j'imagine que les paramètres de DB sont tous les mêmes DEFAULT. pourquoi une page toujours pas d'erreur? – SIDU

+0

@SIDU Je ne suis pas sûr de suivre votre question. C'est une configuration PDO, pas celle de la base de données. – zerkms

+0

Merci zerkms! Il suffit de se demander si un paramètre PDO par défaut a été modifié la semaine dernière? – SIDU

0

Je n'ai pas idée pourquoi errorInfo() ne fonctionne parfois pas mais je confirme son comportement. Étant donné que le mode d'erreur de réglage pour les exceptions fonctionne toujours et que les exceptions sont beaucoup plus utiles que la vérification manuelle des erreurs, cette fonction est de toute façon inutile.

Alors, changer votre fonction de cette façon

function run($pdo, $sql, $params = null) { 
    $sth = $pdo->prepare($sql); 
    $sth->execute($params); 
    return $stmt; 
} 

$pdo = new PDO('mysql:host=localhost;db=mydb', $user, $pass); 
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 

run($pdo, 'select now()'); 
run($pdo, 'pls give me an error'); 

et ont votre message de première classe

+0

Le comportement "étrange" vient du fait que "PDOStatement :: fetch" n'adhère pas à la norme SQL-92. La [note de terry] (http://php.net/manual/en/pdostatement.fetch.php#62536) est le seul endroit sur le web où j'ai trouvé cette information.C'est en ce qui concerne le jeu d'enregistrements vide, cependant. Notez qu'il devrait être "_... et renvoie ** FALSE ** à l'appelant". Une pièce importante: "Cela empêche également le mécanisme d'exception de tirer._". –

+0

De toute façon ce comportement n'est observable que dans le cas de 'fetch()', pas dans les autres cas, comme 'fetchAll()', 'query()', etc. J'ai effectué quelques tests sur 'fetch()' deux semaines il y a quelque temps et, si je me souviens bien, dans certains cas de test, le code d'erreur est resté - de façon inattendue - '00000'. –