oktober 10th, 2007PHP tanač: pretvorba obvestil in opozoril v izjeme
Obvestila, opozorila !?
Prav čudno zveni ta naslov v prevodu ;) Bom kar po domače povedal: pretvorba PHP “notices” in “warnings” v “Exceptions”. Najverjetneje je sedaj slika malce bolj jasna. Po planu nisem imel namena objavit tega prispevka, ker pa ravno delam “skeleton” za eno aplikacijo sem izkoristil priložnost. Namig o konvertiranju opozoril in obvestil sem zasledil na netu že kar nekaj časa nazaj. Pred dnevi sem med arhiviranje starih mailov naletel na “reminder” in sem na brzino pokukal na omenjeni post. Dobil sem idejo, da lahko zadevo uporabim s svojo “debug” funkcijo za “handlanje” izjem – Exceptions.
Prednastavljen error reporting v PHP 4 in PHP 5 je E_ALL & ~E_NOTICE, kar pomeni da ta nastavitev med izvajanjem ne prikazuje obvestil. Pametno je, da prikazovanje obvestil pri razvoju aplikacij vključimo.
PHP 5 prinaša nov error level E_STRICT. Ker E_STRICT ni vključen v E_ALL error level, ga moremo vključiti eksplicitno. Vključitev E_STRICT levela pri razvoju prinaša nekaj koristi. PHP bo izpisoval run-time obvestila in sugestiral na potrebne popravke v kodi. Z upoštevanjem obvestil si predvsem zagotovimo kompatibilnost kode za prihajajoče verzije PHP-ja.
V PHP 5 programiram že kar nekaj časa. Držim se “strict coding standarda”, ki ga predpisuje Zend Framework[1]. Tako pri vseh aplikacijah nastavim error reporting level na E_ALL|E_STRICT.
error_reporting(E_ALL|E_STRICT);
echo $x;
S tem error reporting levelom vsaka nedefinirana spremenljivka[2] sproži obvestilo[3]
![]()
/**
* Foo Bar application
*
* @category Foo
* @package Foo_Static
* @copyright Copyright (c) 2007 Ales Loncar
* @license GNU Public License
* @link http://www.internet-solutions.si
*/
class Foo
{
/**
* Bar method
*/
public function Bar()
{
// static method - not properly defined
}
}
$fooBar = Foo::Bar();
Neupoštevanje standardov prav tako[4]
![]()
try/catch
PHP 5 uporablja podoben model izjem – “Exceptions” kot ostali programski jeziki. Da ne bom preveč modruval, vse je lepo opisano v PHP “manualu“. Omeniti velja le, da ko se zgodi izjema – “exception is thrown”, se koda ki sledi ne izvede, PHP bo poiskusil najti prvi ustrezen block “catch”. V primeru da izjema ni ujeta – “catch”, PHP izvede Fatal Error z sporočilom “Uncaught Exception …”[5]
Veselo na delo, glavna ideja je taka:
- definiramo error handling funkcijo, ki vrže izjemo – exception z ustreznim sporočilom in kodo[6]
- definiramo exception handling funkcijo s katero lovimo – “catch” izjeme, tudi tiste, ki niso v bloku try/catch
- stestiramo error/exception handler na nekaj primerih
set_error_handler
Nastavimo lastno funkcijo za rokovanje z napakami v skripti.
/**
* Global Error Handler
*
* Global error handler class
*
* @author Ales Loncar
* @license GNU Public License
* @category App
* @package App_Error
* @copyright Copyright (c) 2007 Ales Loncar
*/
class General_Error_Handler
{
/**
* Global error handler.
*
* This should not be called by anything - only for uncaught errors.
*
*
*/
public function globalErrorHandler($errno, $errstr, $errfile, $errline)
{
throw new Exception($errstr, $errno);
}
}
/** set ErrorHannlder */
set_error_handler(array(new General_Error_Handler(), 'globalErrorHandler'));
set_exception_handler
Nastavimo privzeto funkcijo za rokovanje z izjemami. S tem ujamemo izjeme katere nismo ujeli v blok try/catch. Izvajanje se ustavi takoj ko se izvede exception_handler.
/**
* Global Exception Handler
*
* Global exception handler class
*
* @author Ales Loncar
* @license GNU Public License
* @category App
* @package App_Error
* @copyright Copyright (c) 2007 Ales Loncar
*/
class General_Exception_Handler
{
/**
* Global exception handler.
*
* This should not be called by anything - only for uncaught exceptions.
*
*/
public function globalExceptionHandler(Exception $exception)
{
$this->_throwException($exception);
}
/**
* Nice debugging info for Exception
*
* @param Exception $e
*/
private function _throwException($e)
{
$o = create_function('$in','echo htmlspecialchars($in);');
// celotno funkcijo najdete v zipu
// totalno sjebe parser saj so v njej php tagi
}
}
/** set Exception Handler */
set_exception_handler(array(new General_Exception_Handler(), 'globalExceptionHandler'));
Sedaj ko imamo oba handlerja, se bomo malce poigrali.
Primer uporabe izjeme v bloku try/catch
/** error reporting */
error_reporting(E_ALL|E_STRICT);
/** debug is true for development */
define('DEBUG', true);
/** let's try some of this stuff */
try {
$x = 0;
if (empty($x)) {
throw new Exception('x is zero', 0);
}
} catch(Exception $e) {
if (DEBUG) {
throw $e;
} else {
if ($e->getCode() == 0) {
// notify about exception
$errorCode = $e->getCode();
$errorMessage = $e->getMessage();
// send mail or write log
// ...
echo "<b>errorCode:</b> $errorCode<br />";
echo "<b>errorMessage:</b> $errorMessage<br />";
echo "<br />";
}
}
}
// continue Execution
echo '<b>continue:</b> Foo bar';
//$x = $y;
Mali komentarček:
Celotna koda je v bloku “try/catch”. Če ne bi definirali exception handlerja in ima konstanta DEBUG vrednost true[7] bo PHP navrgel Fatal Error
Z vključenim exception handlerjem se izvede metoda _throwException() z zelo uporabnim “Stacktracom”, celotnim naborom “Request” metod in “Response” headerjem. Izvajanje skripte se prekine.
![]()
Npr. da aplikacijo objavimo in nastavimo DEBUG vrednost na false[8]. Sedaj v primeru izjeme le te ne vržemo – “thrown”, ampak pogledamo do kakšne napake je prišlo ter obvestimo skrbnika aplikacije oziroma zapišemo vsebino izjeme v log.[9]. Skripta se izvaja normalno naprej.

Če podamo še primer error handlerja, ki pretvori obvestila in opozorila v izjeme. Izven bloka “try/catch” naredimo eno amatersko:
$x = $y;
Ker imamo definiran exception handler se bo koda ustavila na mestu, kjer PHP izpiše obvestilo o nedefinirani spremenljivki.
![]()
Poglejmo še samo, kaj se zgodi takrat če ne bi imeli definiran error handler. Skripta se izvede naprej, PHP pa izpiše obvestilo “Notice: Undefined variable: y in …” saj imamo nastavljen error_reporting na E_ALL|E_STRICT.

Vse skupaj sem zapakiral in lahko po mili volji “dol vlačite”: Error & Exception Handler
Happy blogging(coding)!
- o samem frameworku in kupu uporabnih knjižic enkrat v prihodnosti [↩]
- kot primer [↩]
- Za ta čuden izpis je kriv Xdebug – PHP extension for debugging and profiling. Otom potom :) [↩]
- kot primer [↩]
- le v primeru da nimamo definiranega “custom handlerja” s funkcijo set_exception_handler() [↩]
- tukaj dejansko pretvorimo obvestila in opozorila v izjeme [↩]
- development [↩]
- production [↩]
- z karseda večimi informacijami – stacktrace … [↩]