مدیریت خطا و استثنا در php
یک سری قوانین در هر زبانی وجود دارد که عدم رعایت آن برابر با خطا می باشد. این خطا ها سطوح مختلفی دارند. خطاها یا توسط زبان برنامه نویسی تعیین می شوند. برای مدیریت هر خطا ممکن است هر اتفاقی بیفتد.
به طور کل خطاها را در php به دو دسته تقسیم می کنیم. خطاهایی که از ادامه برنامه جلوگیری می کند (terminate execution) و خطاهایی که پس از آن برنامه ادامه پیدا می کند (continue execution).
- terminate execution
- Parse Error : خطای زمان اجرا مثل syntax.مثلا نگذاشتن
, ' " )( {} []
- Fatal Error : خطاهای مثلا redeclare function , call undefined fucntion , require file
- Parse Error : خطای زمان اجرا مثل syntax.مثلا نگذاشتن
- continue execution
- Warning : خطاهایی مثل اشتباه در پارامتر دهی ، include ، header error
- Notice : استفاده از متغیر یا ایندکس تعریف نشده (E_NOTICE)
Error Level Constants
سطوح مختلفی از خطا داریم که برای هر یک یک ثابت در نظر گرفته ایم . در تنظیمات PHP در فایل php.ini ما می توانیم برای نمایش خطاها (پارامتر error_reporting) از ثوابت زیر استفاده کنیم:
E_ALL : تمامی errors و warning
E_ERROR : خطاهای Fatal و زمان اجرا (Parse)
E_PARSE : خطای زمان اجرا (Syntax)
E_NOTICE : خطای notices
Error Handling Functions
trigger_error
: اگر بخواهیم می توانیم خطا تولید کنیم. این تابع دو پارامتر دارد که اول متن خطا و دوم نوع آن می باشد:
if ($divisor == 0) { trigger_error("Cannot divide by zero", E_USER_ERROR); }
set_error_handler
: می توان در زمان اجرای خطا یک تابع را اجرا کند که آن تابع پارامتر های متفاوتی می گیرد.
set_error_handler ( callable $error_handler [, int $error_types = E_ALL | E_STRICT ] )
پارامتر اول تابع callable یک تابع است که پارامتر های زیر را می گیرد تا با توجه به آن اقدامات لازم را انجام دهد:
handler ( int $errno , string $errstr [, string $errfile [, int $errline [, array $errcontext ]]] )
می توان به جای تابع یک رشته تعریف کرد که پیام خاص را نمایش دهد. پارامتر دوم نوع خطا است.
error_reporting
: نمایش خطا در این برنامه به چه شکل باشد. پارامتر ورودی آن یکی از Error Types است.
// Turn off all error reporting error_reporting(0); // Report simple running errors error_reporting(E_ERROR | E_WARNING | E_PARSE); // Reporting E_NOTICE can be good too (to report uninitialized // variables or catch variable name misspellings ...) error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE); // Report all errors except E_NOTICE error_reporting(E_ALL & ~E_NOTICE); // Report all PHP errors (see changelog) error_reporting(E_ALL); // Report all PHP errors error_reporting(-1); // Same as error_reporting(E_ALL); ini_set('error_reporting', E_ALL);
برای این که به کل هیچ خطایی در پروسه شما نمایش داده نشود کد زیر را در ابتدای اجرای پروسه بنویسید:
ini_set('display_error',0); error_reporting(0);
Exceptions
یک process ممکن است در اسنثنایی خطا داشته باشد مثلا به ازای برخی پارامتر ها خطا بخورد که قوانین خطا می تواند توسط ما یا php تعیین گردد.همان طور که خطاهای پیش فرض و custom داشتیم اسنثنا های پیش فرض و custom داریم(منظور منطق اجرای استثنا است).
به طور مثال عملیات تقسیم در ریاضیات عملیاتی مجاز است. اما استثنایی در این میان وجود دارد به نام division by zero که اعداد تقسیم بر صفر غیر مجاز است.
Exception
یک کلاس پیش فرض php است که متدهای کاربردی دارد. زمانی که یک Exception پرتاب (throw) می شود یک شئ از روی این کلاس ساخته می شود. این شئ باید گرفته شود.
throw new Exception();
زمانی که یک استثنا پرتاب می شود (throw) از ادامه برنامه جلوگیری می کنند مگر اینکه توسط catch گرفته شوند. برای گرفتن این شئ از بلوک try…catch استفاده می کنیم. ساختار آن به شکل زیر می باشد
try { //call function } catch (myException $ex) { //exception was thrown } finally { //finally execute }
قسمت finally در پایان چه به ازای اجرای تابع یا دریافت Exception اجرا می گردد.
پس Exception توسط سازنده (نویسنده پروسه که می تواند تابع یا متدی از یک کلاس باشد) تعبیه و در زمان های لازم پرتاب می شود و توسط استفاده کننده (استفاده کننده از تابع یا متدی از یک شئ) catch می شود.
اگر در پروسه ای که استفاده می کنید از Exception استفاده شده بود آن را در بلوک try…catch استفاده شده است.
function inverse($x) { if ($x == 0) { throw new Exception("ziro is exception in this function"); } return 1 / $x; } if (isset($_GET['x'])) { try { echo inverse($_GET['x']); } catch (Exception $ex) { echo $e->getMessage(); } }
اگر تابع را در بلوک try…catch استفاده نمی کردیم خطای (Fatal Error) زیر را دریافت می کردیم
Fatal error: Uncaught Exception: exception thrown
Exception یک کلاس است و می توان از آن فرزند آورد. فرزند یعنی یک Custom Exception که ویژگی های منحصر به فرد تری داشته باشد :
class myException extends Exception { public function myMessage() { echo '<span style="color:orangered;">' . $this->message . '</span>'; } }
به طبع آن بعد از تعریف کلاس می توان از آن استفاده کرد :
try { echo inverse($_GET['x']); } catch (myException $ex) { $ex->myMessage(); }
Trowable : این کلاس هر گونه شئ پرتاب شده از طریق کلاس throw شامل Error یا Exception . به وسیله این کلاس می توان خطاهای موجود در یک اجرا را دریافت کنیم .
try { foo(); } catch (\Throwable $e) { echo $e->getMessage(); }
در کد بالا اگر تابع foo خطایی رخ داده باشد متن خطا را می توانیم در بلوک catch چاپ کنیم. گاها از این کلاس برای سیستم های خطایابی استفاده می شود. دقت داشته باشید Exception استثناست و شامل Error نمی باشد.
دیدگاهتان را بنویسید