web-dev-qa-db-fra.com

PHP Try and Catch for SQL Insert

J'ai une page sur mon site Web (trafic élevé) qui fait une insertion à chaque chargement de page.

Je suis curieux de connaître le moyen le plus rapide et le plus sûr (de détecter une erreur) et de continuer si le système ne parvient pas à insérer l'insertion dans MySQL. Devrais-je utiliser essayer/attraper ou mourir ou quelque chose d'autre. Je veux m'assurer que l'insertion a bien lieu, mais si, pour une raison quelconque, je ne veux pas que la page continue à se charger de toute façon.

...
$db = mysql_select_db('mobile', $conn);
mysql_query("INSERT INTO redirects SET ua_string = '$ua_string'") or die('Error #10');
mysql_close($conn);
...
22
meme

Le fait de vérifier la documentation montre que cela retourne false en cas d’erreur. Utilisez donc le statut de retour plutôt que or die(). Il renverra false s'il échoue, que vous pouvez vous connecter (ou ce que vous voulez faire), puis continuez.

$rv = mysql_query("INSERT INTO redirects SET ua_string = '$ua_string'");
if ( $rv === false ){
     //handle the error here
}
//page continues loading
25
Yacoby

Cela peut faire l'affaire,

function createLog($data){ 
    $file = "Your path/incompletejobs.txt";
    $fh = fopen($file, 'a') or die("can't open file");
    fwrite($fh,$data);
    fclose($fh);
}
$qry="INSERT INTO redirects SET ua_string = '$ua_string'"   
$result=mysql_query($qry);
if(!$result){
    createLog(mysql_error());
}
10
VKGS

Vous pouvez implémenter des exceptions de projection sur les requêtes mysql. Ce dont vous avez besoin est d’écrire un wrapper pour la fonction mysql_query, par exemple:

// user defined. corresponding MySQL errno for duplicate key entry
const MYSQL_DUPLICATE_KEY_ENTRY = 1022;

// user defined MySQL exceptions
class MySQLException extends Exception {}
class MySQLDuplicateKeyException extends MySQLException {}

function my_mysql_query($query, $conn=false) {
    $res = mysql_query($query, $conn);
    if (!$res) {
        $errno = mysql_errno($conn);
        $error = mysql_error($conn);
        switch ($errno) {
        case MYSQL_DUPLICATE_KEY_ENTRY:
            throw new MySQLDuplicateKeyException($error, $errno);
            break;
        default:
            throw MySQLException($error, $errno);
            break;
        }
    }
    // ...
    // doing something
    // ...
    if ($something_is_wrong) {
        throw new Exception("Logic exception while performing query result processing");
    }

}

try {
    mysql_query("INSERT INTO redirects SET ua_string = '$ua_string'")
}
catch (MySQLDuplicateKeyException $e) {
    // duplicate entry exception
    $e->getMessage();
}
catch (MySQLException $e) {
    // other mysql exception (not duplicate key entry)
    $e->getMessage();
}
catch (Exception $e) {
    // not a MySQL exception
    $e->getMessage();
}
7
Nemoden

si vous voulez enregistrer l'erreur, etc., vous devez utiliser try/catch, sinon viens de mettre @ avant mysql_query

edit: vous pouvez utiliser try catch comme ceci; afin que vous puissiez enregistrer l'erreur et laisser la page continuer à charger 

function throw_ex($er){  
  throw new Exception($er);  
}  
try {  
mysql_connect(localhost,'user','pass'); 
mysql_select_db('test'); 
$q = mysql_query('select * from asdasda') or throw_ex(mysql_error());  
}  
catch(exception $e) {
  echo "ex: ".$e; 
}
5
engvrdr

En développant la réponse de yasaluyari, je m'en tiendrai à quelque chose comme ceci:

Nous pouvons simplement modifier notre mysql_query comme suit:

function mysql_catchquery($query,$emsg='Error submitting the query'){
    if ($result=mysql_query($query)) return $result;
    else throw new Exception($emsg);
}

Maintenant, nous pouvons simplement l'utiliser comme ceci, un bon exemple:

try {
    mysql_catchquery('CREATE TEMPORARY TABLE a (ID int(6))');
    mysql_catchquery('insert into a values(666),(418),(93)');
    mysql_catchquery('insert into b(ID, name) select a.ID, c.name from a join c on a.ID=c.ID');
    $result=mysql_catchquery('select * from d where ID=7777777');
    while ($tmp=mysql_fetch_assoc($result)) { ... }
} catch (Exception $e) {
    echo $e->getMessage();
}

Notez comme c'est beau. Chaque fois que l'un des qq échoue, nous gtfo avec nos erreurs. Et vous pouvez également noter qu'il n'est pas nécessaire maintenant de stocker l'état des requêtes d'écriture dans une variable $result à des fins de vérification, car notre fonction le gère maintenant tout seul. Et de la même manière qu'il gère les sélections, il affecte simplement le résultat à une variable comme le fait la fonction normale, tout en gérant les erreurs qu'il contient.

Notez également que nous n’avons pas besoin de montrer les erreurs réelles car elles comportent un risque énorme pour la sécurité, particulièrement avec cette extension obsolète. C'est pourquoi notre valeur par défaut ira très bien la plupart du temps. Cependant, si nous souhaitons informer l'utilisateur d'une erreur de requête particulière, nous pouvons toujours transmettre le deuxième paramètre pour afficher notre message d'erreur personnalisé.

2
Anonymous
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

Je ne sais pas s'il existe une version mysql de cela, mais l'ajout de cette ligne de code permet de lancer mysqli_sql_exception.
Je sais, passé beaucoup de temps et la question est déjà vérifiée mais j'ai eu une réponse différente et cela pourrait être utile.

1
starkm
    $sql = "INSERT INTO   customer(FIELDS)VALUES(VALUES)";
    mysql_query($sql);
    if (mysql_errno())
    {
            echo "<script>alert('License already registered');location.replace('customerform.html');</script>";
    }   
0
Vishal
$new_user = new User($user);
$mapper = $this->spot->mapper("App\User");

try{
    $id = $mapper->save($new_user);     
}catch(Exception $exception){

    $data["error"] = true;
    $data["message"] = "Error while insertion. Erron in the query";
    $data["data"] = $exception->getMessage();

    return $response->withStatus(409)
    ->withHeader("Content-Type", "application/json")
    ->write(json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));        
}

si une erreur survient, vous obtiendrez quelque chose comme ceci->

{
    "error": true,
    "message": "Error while insertion. Erron in the query",
    "data": "An exception occurred while executing 'INSERT INTO \"user\" (...) VALUES (...)' with params [...]:\n\nSQLSTATE[22P02]: Invalid text representation: 7 ERROR:  invalid input syntax for integer: \"default\"" }

avec code d'état: 409.

0
Bharat Chhabra