2010-05-22 8 views
3

J'essaye de construire le site en utilisant OOP en PHP. Tout le monde parle de Singleton, de l'hermétisation, du MVC et de l'utilisation d'exceptions. J'ai donc essayé de le faire comme ceci:Exceptions confusion

bâtiment classe site entier:

class Core 
{ 
    public $is_core; 
    public $theme; 
    private $db; 
    public $language; 
    private $info; 
    static private $instance; 

    public function __construct($lang = 'eng', $theme = 'default') 
    { 
     if(!self::$instance) 
     { 
      try 
      { 
       $this->db = new sdb(DB_TYPE.':host='.DB_HOST.';dbname='.DB_NAME, DB_USER, DB_PASS); 
      } 
      catch(PDOException $e) 
      { 
       throw new CoreException($e->getMessage()); 
      } 
      try 
      { 
       $this->language = new Language($lang); 
      } 
      catch(LangException $e) 
      { 
       throw new CoreException($e->getMessage()); 
      } 
      try 
      { 
       $this->theme = new Theme($theme); 
      } 
      catch(ThemeException $e) 
      { 
       throw new CoreException($e->getMessage()); 
      } 
     } 
     return self::$instance; 
    } 
    public function getSite($what) 
    { 
     return $this->language->getLang(); 
    } 
    private function __clone() { } 

} 

classe thèmes gestion

class Theme 
{ 
    private $theme; 
    public function __construct($name = 'default') 
    { 
     if(!is_dir("themes/$name")) 
     { 
      throw new ThemeException("Unable to load theme $name"); 
     } 
     else 
     { 
      $this->theme = $name; 
     } 
    } 
    public function getTheme() 
    { 
     return $this->theme; 
    } 
    public function display($part) 
    { 
     if(!is_file("themes/$this->theme/$part.php")) 
     { 
      throw new ThemeException("Unable to load theme part: themes/$this->theme/$part.php"); 
     } 
     else 
     { 
      return 'So far so good'; 
     } 
    } 

} 

et l'utilisation:

error_reporting(E_ALL); 

require_once('config.php'); 
require_once('functions.php'); 

try 
{ 
    $core = new Core(); 
} 
catch(CoreException $e) 
{ 
    echo 'Core Exception: '.$e->getMessage(); 
} 
echo $core->theme->getTheme(); 
echo "<br />"; 
echo $core->language->getLang(); 

try 
{ 
    $core->theme->display('footer'); 
} 
catch(ThemeException $e) 
{ 
    echo $e->getMessage(); 
} 

Je ne J'aime ces gestionnaires d'exceptions - je ne veux pas les attraper comme des pokemons ... Je veux utiliser des choses simples: $ core-> theme-> display ('footer'); Et si quelque chose ne va pas, et que le mode débogage est activé, alors l'erreur d'affichage indique. Que devrais-je faire?

Répondre

1

Je ne suis pas familier avec PHP, mais vous devriez arrêter définitivement de faire des exceptions pokemon. Tout d'abord, il ne devrait pas être nécessaire de remplacer chaque exception (PDOException) par une exception spécifique (CoreException). En second lieu, utiliser des blocs de prises multiples dans votre section d'utilisation, comme ceci:

try 
{ 
    $core->theme->display('footer'); 
} 
catch(ThemeException $e) 
{ 
    echo $e->getMessage(); 
} 
catch(PDOException $e) 
{ 
    echo $e->getMessage(); 
} 

Votre classe « Core » peut alors rétrécir considérablement (pas plus try/catch pour chaque élément). Certes, vous montrerez plus de blocs catch à un niveau supérieur, mais c'est ce que vous devriez faire avec la POO et les exceptions.

Enfin, vérifiez s'il existe déjà une super-classe d'exception pour certains sous-ensembles d'exceptions que vous essayez d'intercepter. Cela réduira le nombre de blocs de capture.

+0

Eh bien, je ne fais que commencer, mais cette prise multiple a beaucoup raccourci mon code! J'ai utilisé CoreException parce que je n'ai pas connaissance de cette capture multiple – Misiur

1

Si vous ne voulez pas les attraper et que vous voulez les ignorer, alors vous ne devriez pas jeter les exceptions (en fait, il n'y a pas d'alternative - les exceptions doivent être interceptées ou l'exécution du script se terminera) .

faire quelque chose comme

if (debug_is_on()) 
    throw new MyException(...); 

Alternativement, vous pouvez throw errors au lieu et régler le niveau error_reporting.

+0

Est-ce seulement le moyen? Ensuite, je vais toujours essayer/attraper des erreurs, après vérification est débogage sur. – Misiur

+0

Si le débogage est activé, vous pouvez laisser l'exception non gérée et corriger l'erreur. – Artefacto

1

Vous pouvez envisager d'utiliser un gestionnaire d'erreurs personnalisé et de le définir pour l'application. Ce n'est vraiment une approche valable si vous travaillez sous un modèle de conception comme le contrôleur frontal où le gestionnaire peut être facilement réglé à l'échelle de l'application.

Voici un exemple du gestionnaire que j'utilise généralement:

<?php 
class ErrorHandler 
{ 
    // Private constructor to prevent direct creation of object 
    private function __construct() 
    { 
    } 

    /* Set user error-handler method to ErrorHandler::Handler method */ 
    public static function SetHandler($errTypes = ERROR_TYPES) 
    { 
     return set_error_handler(array ('ErrorHandler', 'Handler'), $errTypes); 
    } 

    // Error handler method 
    public static function Handler($errNo, $errStr, $errFile, $errLine) 
    { 

     $backtrace = ErrorHandler::GetBacktrace(2); 

     $error_message = "\nERRNO: $errNo\nTEXT: $errStr" . 
        "\nLOCATION: $errFile, line " . 
        "$errLine, at " . date('F j, Y, g:i a') . 
        "\nShowing backtrace:\n$backtrace\n\n"; 

     // Email the error details, in case SEND_ERROR_MAIL is true 
     if (SEND_ERROR_MAIL == true) 
     error_log($error_message, 1, ADMIN_ERROR_MAIL, "From: " . 
     SENDMAIL_FROM . "\r\nTo: " . ADMIN_ERROR_MAIL); 

     // Log the error, in case LOG_ERRORS is true 
     if (LOG_ERRORS == true) 
     error_log($error_message, 3, LOG_ERRORS_FILE); 

     /* Warnings don't abort execution if IS_WARNING_FATAL is false 
     E_NOTICE and E_USER_NOTICE errors don't abort execution */ 
     if (($errNo == E_WARNING && IS_WARNING_FATAL == false) || 
     ($errNo == E_NOTICE || $errNo == E_USER_NOTICE)) 
     // If the error is nonfatal ... 
     { 
      // Show message only if DEBUGGING is true 
      if (DEBUGGING == true) 
      echo '<div class="error_box"><pre>' . $error_message . '</pre></div>'; 
     } 
     else 
     // If error is fatal ... 
     { 
      // Show error message 
      if (DEBUGGING == true) 
      echo '<div class="error_box"><pre>'. $error_message . '</pre></div>'; 
      else 
      echo SITE_GENERIC_ERROR_MESSAGE; 

      // Stop processing the request 
      exit(); 
     } 
    } 

    // Builds backtrace message 
    public static function GetBacktrace($irrelevantFirstEntries) 
    { 
     $s = ''; 
     $MAXSTRLEN = 64; 
     $trace_array = debug_backtrace(); 

     for ($i = 0; $i < $irrelevantFirstEntries; $i++) 
     array_shift($trace_array); 
     $tabs = sizeof($trace_array) - 1; 

     foreach ($trace_array as $arr) 
     { 
      $tabs -= 1; 
      if (isset ($arr['class'])) 
      $s .= $arr['class'] . '.'; 
      $args = array(); 

      if (!empty ($arr['args'])) 
      foreach ($arr['args']as $v) 
      { 
       if (is_null($v)) 
       $args[] = 'null'; 
       elseif (is_array($v)) 
       $args[] = 'Array[' . sizeof($v) . ']'; 
       elseif (is_object($v)) 
       $args[] = 'Object: ' . get_class($v); 
       elseif (is_bool($v)) 
       $args[] = $v ? 'true' : 'false'; 
       else 
       { 
        $v = (string)@$v; 
        $str = htmlspecialchars(substr($v, 0, $MAXSTRLEN)); 
        if (strlen($v) > $MAXSTRLEN) 
        $str .= '...'; 
        $args[] = '"' . $str . '"'; 
       } 
      } 

      $s .= $arr['function'] . '(' . implode(', ', $args) . ')'; 
      $line = (isset ($arr['line']) ? $arr['line']: 'unknown'); 
      $file = (isset ($arr['file']) ? $arr['file']: 'unknown'); 
      $s .= sprintf(' # line %4d, file: %s', $line, $file); 
      $s .= "\n"; 
     } 

     return $s; 
    } 
} 
?> 

Vous pouvez ensuite définir quelques constantes faciles à déterminer des comportements de base.

//determines if the application will fail on E_WARNING level errors. 
define('IS_WARNING_FATAL', true); 
//determines error message shown 
define('DEBUGGING', true); 
// The error types to be reported 
define('ERROR_TYPES', E_ALL); 

// Settings about mailing the error messages to admin 
define('SEND_ERROR_MAIL', false); 
define('ADMIN_ERROR_MAIL', '[email protected]'); 
define('SENDMAIL_FROM', '[email protected]'); 


//Saves errors to a file when true 
define('LOG_ERRORS', false); 
define('LOG_ERRORS_FILE', 'path-to-error-log'); 
/* Generic error message to be displayed instead of debug info 
(when DEBUGGING is false) */ 
define('SITE_GENERIC_ERROR_MESSAGE', '<h1>An unknown error occurred! Our webmaster has been notified.</h1>');