J'utilise le script suivant pour utiliser une base de données utilisant PHP:
try{
$db = new PDO('mysql:Host='.$Host.';port='.$port.';dbname='.$db, $user, $pass, $options);
}
catch(Exception $e){
$GLOBALS['errors'][] = $e;
}
Maintenant, je veux utiliser ce handle de base de données pour faire une requête en utilisant ce code:
try{
$query = $db->prepare("INSERT INTO users (...) VALUES (...);");
$query->execute(array(
'...' => $...,
'...' => $...
));
}
catch(Exception $e){
$GLOBALS['errors'][] = $e;
}
Voici le problème:
$GLOBALS['errors'][]
et le script est toujours en cours d'exécution par la suite,Remarque: Variable non définie: db dans C:\xampp\htdocs [...]\test.php à la ligne 32
Erreur fatale: appel d'une fonction membre prepare () sur un non-objet dans C:\xampp\htdocs [...]\test.php à la ligne 32
Remarque: La ligne 32 est l'instruction $query = $db->prepare(...)
.
C'est-à-dire que le script se bloque et que le test/capture semble être inutile. Savez-vous pourquoi ce deuxième essai/attrape ne fonctionne pas et comment le résoudre?
Merci pour l'aide!
EDIT: Il y a de très bonnes réponses. J'ai validé celui qui n'est pas exactement ce que je voulais faire, mais qui est probablement la meilleure approche.
Les blocs try
/catch
ne fonctionnent que pour les exceptions levées (throw Exception
ou une sous-classe de Exception
doit être appelée). Vous ne pouvez pas détecter les erreurs fatales à l'aide de try
/catch
.
Si votre connexion à la base de données ne peut pas être établie, je la considérerais comme étant fatale car vous avez probablement besoin que votre base de données fasse quelque chose de significatif sur la page.
PDO
lève une exception si la connexion ne peut pas être établie. Votre problème spécifique est que $db
n'est pas défini lorsque vous essayez d'appeler une méthode avec cette méthode afin d'obtenir un pointeur null (en quelque sorte) fatal. Plutôt que de parcourir les fonctions de if ($db == null)
, comme le suggèrent d'autres personnes, vous devez simplement corriger votre code pour vous assurer que $db
est toujours défini lorsque vous en avez besoin ou que vous disposez d'un moyen moins fragile de garantir qu'une connexion à une base de données est disponible dans le code qui l'utilise .
Si vous voulez vraiment "attraper" les erreurs fatales, utilisez set_error_handler
, mais cela arrête l'exécution du script sur les erreurs fatales.
En PHP7, nous pouvons maintenant utiliser try catch error fatal avec un travail simple
try {
do some thing evil
} catch (Error $e) {
echo 'Now you can catch me!';
}
Mais normalement, nous devrions éviter d'utiliser catch Error, car cela implique de rater le code qui appartient à la responsabilité du programmeur :-)
Si la connexion à la base de données échoue, $db
de votre premier bloc try .. catch
sera nul. C'est pourquoi plus tard, vous ne pouvez pas utiliser un membre de non-objet, dans votre cas $db->prepare(...)
. Avant d'utiliser cet add
if ($db) {
// other try catch statement
}
Cela garantira que vous disposez d'une instance de base de données pour l'utiliser.
Pourquoi utilisez-vous les instructions try ... catch
pour déclarer cela? Remplacez ceci:
try{
$db = new PDO('mysql:Host='.$Host.';port='.$port.';dbname='.$db, $user, $pass, $options);
}
Avec:
$db = new PDO('mysql:Host='.$Host.';port='.$port.';dbname='.$db, $user, $pass, $options) or die("Cannot Create PDO!");
Ou à votre façon:
$db = new PDO('mysql:Host='.$Host.';port='.$port.';dbname='.$db, $user, $pass, $options) or ($GLOBALS['errors'][] = "Cannot Create PDO!");
Essayez d’ajouter l’instruction if suivante:
if ($db) {
$query = $db->prepare("INSERT INTO users (...) VALUES (...);");
$query->execute(....);
}
else die('Connection lost');
Je ne signalerai pas ce qui a déjà été écrit sur les tests si $db
est vide. Ajoutez simplement qu'une solution "propre" consiste à créer artificiellement une exception si la connexion à la base de données échoue:
if ($db == NULL) throw new Exception('Connection failed.');
Insérez la ligne précédente dans le try - catch
comme suit:
try{
// This line create an exception if $db is empty
if ($db == NULL) throw new Exception('Connection failed.');
$query = $db->prepare("INSERT INTO users (...) VALUES (...);");
$query->execute(array(
'...' => $...,
'...' => $...
));
}
catch(Exception $e){
$GLOBALS['errors'][] = $e;
}
J'espère que cela aidera les autres!
try{
if(!is_null($db))
{
$query = $db->prepare("INSERT INTO users (...) VALUES (...);");
$query->execute(array(
'...' => $...,
'...' => $...
));
}
}
catch(Exception $e){
$GLOBALS['errors'][] = $e;
}