Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: "throw" w __autoload
Forum PHP.pl > Forum > PHP > Object-oriented programming
pawel_k
witam wszystkich.
mam taki mały problem, czy da się przechwycić wyjątki wyrzucone przez __autoload() ?

kod mam następujący:

  1. <?php
  2. try
  3. {
  4. $resConn = DB::getConn();
  5. $objSmarty->display('common/index.tpl');
  6. }
  7. catch(DBconnError $e1)
  8. {
  9. $objSmarty->display('common/DBerror.tpl');
  10. }
  11. catch(NoClassFoundError $e2)
  12. {
  13.  $objSmarty->display('common/NoClassFoundError.tpl');
  14. }
  15.  
  16. ?>


a w klasie DB:
  1. <?php
  2. class DB
  3. {
  4. /**
  5.  * resConnection - przechwuje identyfikator połączenia z bazą danych
  6.  *
  7.  * @var resource
  8.  * @access private
  9.  */
  10. private static $resConnection;
  11.  
  12. /**
  13.  * objDataBase - obiekt odpowiedzialny za komunikację z bazą danych
  14.  *
  15.  * @var object
  16.  * @access private
  17.  */
  18.  private static $objDataBase;
  19.  
  20. /**
  21.  * Konstruktor - tworzy nowy obiekt odpowiedzialny za komunikację z bazą danych
  22.  *
  23.  * @param void
  24.  * @access private
  25.  * @return void
  26.  * @throws NoClassFoundError
  27.  * @throws DBconnError
  28.  */
  29. private function __construct()
  30. {
  31. try
  32. {
  33. $strDB_Class = DB_TYPE.'DB_handler';
  34. $this->objDataBase = new $strDB_Class();
  35.  
  36. }
  37. catch(NoClassFoundError $e)
  38. {
  39. throw $e;
  40. }
  41.  
  42. if(!($this->resConnection = $this->objDataBase->getConnection()))
  43. {
  44. throw new DBconnError();
  45. }
  46. }
  47.  
  48. /**
  49.  * getConn metoda zwraca identyfikator połączenia
  50.  *
  51.  * @param void
  52.  * @access public
  53.  * @return resource
  54.  * @throws NoClassFoundError
  55.  * @throws DBconnError
  56.  */
  57. public static function getConn()
  58. {
  59. if(!self::$resConnection)
  60. {
  61. try
  62. {
  63. new DB();
  64. }
  65. catch(NoClassFoundError $e1)
  66. {
  67. throw $e1;
  68. }
  69. catch(DBconnError $e2)
  70. {
  71. throw $e2;
  72. }
  73. }
  74. return self::$resConnection;
  75. }
  76. }
  77.  
  78. ?>


autoloader wyglada tak:
  1. <?php
  2.  
  3. function __autoload($strClass)
  4. {
  5. if(file_exists('../modules/'.$strClass.'/class.'.$strClass.'.php'))
  6. {
  7. @require_once('../modules/'.$strClass.'/class.'.$strClass.'.php');
  8. }
  9. else
  10. {
  11. throw new NoClassFoundError();
  12. }
  13. }
  14.  
  15. ?>


i teraz jak próbuję wczytać klasę która nie istnieje to zamiast przechwycić mi błąd najpierw w klasie DB i przekazać go do obsłużenia do index.php wyświetla mi w przeglądarce:
Cytat
Fatal error: Function __autoload(PostgresqlDB_handler) threw an exception of type 'NoClassFoundError' in /var/www/projekty/framework/libs/DB/class.DB.php on line 56

można jakoś przechwycić ten wyjątek?
Ociu
Nie da się. Można to wyrzucić tak jak to było w phiendzie2, czyli w eval() utworzyć klasę, gdzie w jej konstruktorze będzie wypluwany wyjątek.
pawel_k
pogooglowalem troche i znalazlem cos takiego:
http://bugs.php.net/bug.php?id=31102

właściwie to zmieniłem konstruktor tak jak mniej wiecej tam było, czyli
  1. <?php
  2. private function __construct()
  3. {
  4. try
  5. {
  6. $strDB_Class = DB_TYPE.'DB_handler';
  7. __autoload($strDB_Class);
  8. $this->objDataBase = new $strDB_Class();
  9. #__autoload("Bug"); // Prints "exception caught."
  10. }
  11. catch(NoClassFoundError $e)
  12. {
  13. throw $e;
  14. }
  15. catch(Exception $e2)
  16. {
  17. throw $e2;
  18. }
  19.  
  20. if(!($this->resConnection = $this->objDataBase->getConnection()))
  21. {
  22. throw new DBconnError();
  23. }
  24. }
  25.  
  26. ?>
chociaż za ładnie kod nie wygląda i trzeba jeszcze przerobić __autoload()...

a możesz napisać jak by to wyglądało z eval() ?
hwao
w __autoload wyrzuconych wyjadkow nie obsluzysz winksmiley.jpg

Dopiero w PHP6 ma to byc
Radarek
Z tym, ze jaki jest sens tego? Skoro danej klasy nie znaleziono tzn ze cos zostalo zle zaprogramowane (bo przeciez nie moze zdarzyc sie sytuacja, ze nie znaleziono definicji klasy). Nawet jesli zlapiesz wyjatek 'NoClassFoundError' to co zrobisz z takim wyjatkiem? (swoja droga zgodnie ze sposobem nazywania klas wyjatkow powinno byc 'NoClassFoundException', ale to szczegol smile.gif ).
pawel_k
nie do końca coś zle zostało zaprogramowane, po prostu wczytywany jest moduł który akurat nie jest załadowany...

a co do nazewnictwa to stosuję zasadę że ---Error to wyjątki przerywające sktypt po których wyświetlona zostaje strona z info o błędzie (np. w przypadku gdy nie można połączyć się z bazą danych info o problemach technicznych i że zapraszam później smile.gif ), ---Exception powodują zmianę trypu wykonania, np przeniesienie na inną podstronę...
Ociu
Myślę, że hawk nie będzie miał nic przeciwko:
  1. <?php
  2. eval("class $strClass { public function __construct() { throw new NoSuchClassException('$strClass not found'); } }");
  3. ?>
chmolu
Da się wywalać wyjątki w __autoload. Trzeba tylko trochę to obejść. Przykład z Phienda:

  1. <?php
  2. if (!class_exists($class, false) && !interface_exists($class, false)) {
  3. eval("class $class { public function __construct() { throw new ClassNotFoundException('$class not found'); } }");
  4. }
  5. ?>
pawel_k
thx Ociu i chmolu :]
hwao
Cytat(chmolu @ 2006-02-04 23:37:45)
Da się wywalać wyjątki w __autoload. Trzeba tylko trochę to obejść.

a obsluzysz je?
aleksander
set_exception_handler ?
bela
Set_exception_handler to główne zło świata :] A bardziej serio, to to jest zla praktyka, bo poczatkujacy developer mysli sobie, ze jesli moze utworzyc handler, no to po co lapac wyjatki.
Ja w pliku index mam klauzure try/catch, tam gdzie wywoluje aplikacji i jest si.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.