Mots-clé : exception

PDO, MySQL et erreurs détaillées : comment faire

Voici mon ancien code d’exécution des requêtes SQL :

$stmt = self::$_pdo->prepare($sql);
if ($stmt===false) {
}   
foreach ($tab as $key=>$valeur) {
    $stmt->bindValue($key, $valeur);
}   
$stmt->execute();
if ($stmt===false) {
    throw new Exception(
        "Erreur execution de la requete :\n\"".$sql."\"\n".
        "Paramètres de la requete :\n\"".var_export($tab, true)."\"\n".
        "Details de l'erreur : \n".var_export(self::$_pdo->errorInfo(), true)
    );
}

Le seul (gros) problème, c’est sur erreur d’exécution, il n’y avait aucune explication claire (détail = erreur 0x00). J’ai trouvé la solution : il faut dire de lever une exception si erreur :

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

Et maintenant, tout problème d’exécution de query lève une exception qui contient une erreur vraiment détaillée et utile de la requête.

Php : comment dériver la classe Exception et lui passer un tableau de chaines

Dans la plupart de mes pages, j’ai besoin, lorsqu’il y a une erreur, de mettre un message explicite qui est souvent long. Qui dit long dit plusieurs lignes. Ou bien j’ai envie de stopper l’exécution en cours et d’afficher plusieurs messages. L’idée de base est de lever une exception, mais une exception qui reçoit plusieurs chaînes de caractères comme message d’erreur. Alors j’ai fait ma propre classe en m’inspirant de l’aide sur les exceptions de php.net.

On peut lever une exception de cette façon :

throw new ExceptionErr(
  array(
    "Nous vous avons envoyé la liste récemment.",
    "Afin de garantir une qualité de service ".
    "pour tout le monde, ",
    "nous ne pouvons ré-envoyer la liste que dans ".
    $delai
  ) 
);

Vous pouvez la récupérer ou simplement lire le code. En espérant que cela serve à d’autres personnes :

<?
/**
 * fichier exception_err.php
 *
 * Historique :
 * 21/09/2011 : Olivier Pons
 *              Création
 * @author Olivier Pons
 * @version 1.0
 * @since 1.0
 * @copyright Olivier Pons
 * @package Classes_Base
 */

/**
 * Includes
 */

/**
 * Classe Exception qu'on peut
 * lever en lui passant un tableau
 * en paramètre.
 *
 * @author Olivier Pons
 * @version 1.0
 * @since 1.0
 * @copyright Olivier Pons
 * @package Classes_Base
 *
 */
class ExceptionErr extends Exception
{
  /** 
   * @var array le tableau contenant les lignes d'erreur
   */
  private $TabErr;
  
  /** 
   * Lit le tableau contenant les lignes d'erreur
   * @return array le tableau contenant les lignes d'erreur
   */
  public function getTabErr()
  {
    if (!isset($this->TabErr)) {
      throw new Exception('TabErr : pas initialise');
    }   
    return $this->TabErr;
  }

  /** 
   * Surcharge de la représentation de l'objet sous forme de
   * chaine
   *
   * @return string Représentation de l'objet sous forme de
   *   chaine.
   */
  public function __toString() {
      return __CLASS__ .
        ": [{".$this->code."}]: {".$this->message."} ".
        "- {".var_export($this->TabErr,true)."}\n";
  }

  /** 
   * Constructeur surchargé de la classe "Exception" de base.
   *
   * @param array $tab_err
   *   Tableau contenant les chaines à mettre à la suite dans
   *   un tableau d'erreur (voir les classes qui utilisent
   *   cette classe pour comprendre)
   * @param integer $code
   *   Numéro de code d'erreur
   * @param Exception $previous
   *   Exception précédente
   *
   * @return void
   */
  public function __construct(
    $messages, $code = 0,
    Exception $previous = null) 
  {
      if (!is_array($messages)) {
        throw new Exception("Messages : array attendu");
      }   
      if (count($messages)==0) {
        throw new Exception("Messages : tableau vide");
      }   
      list($message)=each($messages);
      parent::__construct($message, $code, $previous);
      $this->TabErr = $messages;
  }
}

?>