بررسی استثناها در php
Wiki
همراه با php 5 یک روش جدید شیء گرا برای کار با خطاها ارائه شده است.
استثنا یا Exception چیست؟
اگر در حین اجرای عادی اسکریپت، یک خطای خاص رخ دهد، بررسی کننده استثنا، راه اندازی شده و ادامه اجرای اسکریپت را تغییر می دهد، این خطا را می توان با دستورات شرطی، مشخص کرد، این شرط در حقیقت همان استثنای ماست.
برای استفاده از استثناها می توان مستقیماً از کلاس Exception استفاده کرد و آنرا به صورت زیر راه اندازی یا پرتاب (throw) کرد:
<?php
if($error)
{
throw new Exception("خطایی رخ داده است\n");
}
?>
به طور معمول وقتی یک استثنا راه اندازی می شود چه چیزهایی اتفاق می افتد؟
- وضعیت فعلی کد ذخیره می شود.
- ادامه اجرای کد به یک تابع از پیش تعریف شده (بررسی کننده استثنا) منتقل می شود.
- بسته به موقعیت، بررسی کننده استثنا ممکن است اجرای اسکریپت را از وضعیت ذخیره شده از سر بگیرد، یا اجرای اسکریپت را متوقف کند و یا اجرای اسکریپت را از یک مکان متفاوت در کد ادامه دهد.
روش های مختلف بررسی خطا:
- استفاده اصلی از استثناها
- تعریف کلاس استثایِ خودمان
- استثناهای چندگانه
- راه اندازی مجدد استثنا
- تعیین یک مهارکننده استثنای سطح بالا
نکته: یک استثنا همیشه با یک شرط همراه است و نباید برای پرش به جای دیگر استفاده شود.
1- استفاده اصلی از استثناها
Wiki
زمانی که یک استثنا راه اندازی می شود، اجرای کدهای بعد از آن متوقف شده و php سعی به پیدا کردن بلاک تطابقی استثنای مذکور که catch نامیده می شود، خواهد کرد. به زبان ساده تر بعد از بروز خطا و راه اندازی استثنا، ادامه اجرای اسکریپت در یک بلاک که catch نامیده می شود، گرفتار می شود.
نکته:اگر php برای یک استثنا بلاک تطابقی آنرا نیابد، یک fatal error یا خطای مهلک، همراه با پیغام "Uncaught Exception" صادر خواهد شد.
مثال: در این مثال تابع "checkNum" بررسی می کند، اگر پارامتر ورودی آن بزرگتر از "1" بود استثنا راه اندازی شود، البته توجه داشته باشید که استثنای تعریف شده بدون Catch است:
<?php
function checkNum($number)
{
if($number>1)
{
throw new Exception("Value must be 1 or below");
}
return true;
}
checkNum(2);
?>
خروجی کد بالا:
Fatal error: Uncaught exception 'Exception'
with message 'Value must be 1 or below' in C:\webfolder\test.php:6
Stack trace: #0 C:\webfolder\test.php(12):
checkNum(28) #1 {main} thrown in C:\webfolder\test.php on line 6
راه اندازی استثنا همراه با بلاک های try و catch
در مثال بالا برای مدیریت بهتر خطا، ما به یک کد مناسب برای بررسی کردن استثنا نیاز داریم که می تواند شامل بخش های زیر باشد:
- بلاک try: تابعی که یک استثنا را استفاده می کند باید در بلاک "try" باشد. (اگر استثنا راه اندازی نشود، کد داخل این بلاک به طور معمول، ادامه خواهد یافت اما اگر شرط استثنا برقرار شود استثنا اجرا خواهد شد)
- راه انداز یا پرتاب استثنا(throw): یعنی چه طور یک استثنا را راه اندازی شود. هر "throw" باید حداقل یک "catch" داشته باشد.
- بلاک catch: اگر استثانی پرتاب شود، بلاک "catch" آنرا می گیرد و یک شیء شامل اطلاعات استثنا ایجاد می کند.
مثال:
<?php
function checkNum($number)
{
if($number>1)
{
throw new Exception("Value must be 1 or below");
}
return true;
}
try
{
checkNum(2);
//اگر استثنا راه اندازی بشود، خط بعدی اجرا نخواهد شد
echo 'If you see this, the number is 1 or below';
}
catch(Exception $e)
{
echo 'Message: ' .$e->getMessage();
}
?>
خروجی کد بالا:
Message: Value must be 1 or below
توضیح مثال بالا:
- تابع ()checkNum بررسی می کند که آیا پارامتر ورودی آن بزرگتر از 1 است. اگر بزرگتر باشد یک استثنا پرتاب می شود.
- تابع ()checkNum در بلاک "try" فراخوانی می شود
- بلاک "catch" استثناهای پرتاب شده را می گیرد و یک شیء (e$) شامل اطلاعات استثنا ایجاد می کند.
- پیغام خطای استثنا، با فراخوانی تابع ()getMessage از شیء (e$) تولید می شود.
2- ایجاد کلاس استثنایِ خودمان
Wiki
به سادگی می توانیم یک کلاس سفارشی، همراه با توابعی که بتوانند هنگام رخداد یک استثنا در php فراخوانی شوند، ایجاد کرد، لطفاً به مثال زیر توجه فرمایید:
نکته:کلاس جدیدمان باید از کلاس Exception ارثبری داشته باشد.
مثال:
<?php
class customException extends Exception
{
public function errorMessage()
{
$errorMsg = 'Error on line '.$this->getLine().' in '.$this->getFile()
.': <b>'.$this->getMessage().'</b> is not a valid E-Mail address';
return $errorMsg;
}
}
$email = "این آدرس ایمیل توسط spambots حفاظت می شود. برای دیدن شما نیاز به جاوا اسکریپت دارید";
try
{
if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE)
{
throw new customException($email);
}
}
catch (customException $e)
{
echo $e->errorMessage();
}
?>
توضیح مثال:
- کلاس customException از کلاس Exception ارثبری دارد، بنابراین، این کلاس همه ی متدها و خصوصیات را از کلاس قبلی به ارث می برد (getMessage,getFile,getLine)
- تابع ()errorMessage یک پیغام خطا برمی گرداند (درصورتی که آدرس ایمیل نامعتبر باشد).
- متغییر email$ با یک مقدار نامعتبر برای ایمیل تنظیم شده است.
- بلاک try اجرا می شود و چون که آدرس ایمیل نامعتبر است، یک استثنا راه اندازی می شود
- بلاک catch استثنا را می گیرد و یک پیغام خطا نمایش می دهد
3- استثناهای چندگانه
Wiki
برای یک اسکریپت این امکان وجود دارد که به ازای اتفاق افتادن شرط های متفاوت، استثناهای متفاوت با بلاک های catch متفاوت را تعریف کنیم.
مثال:
<?php
class customException extends Exception
{
public function errorMessage()
{
$errorMsg = 'Error on line '.$this->getLine().' in '.$this->getFile()
.': <b>'.$this->getMessage().'</b> is not a valid E-Mail address';
return $errorMsg;
}
}
$email = "این آدرس ایمیل توسط spambots حفاظت می شود. برای دیدن شما نیاز به جاوا اسکریپت دارید";
try
{
// style="font-family: Courier New;">اگر ایمیل معتبر نباشد، استثنا راه اندازی می شود
if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE)
{
throw new customException($email);
}
// style="font-family: Courier New;">اگر در آدرس ایمیل کلمه مشخص شده وجود داشت، استثنا راه اندازی می شود
if(strpos($email, "example") !== FALSE)
{
throw new Exception("$email is an example e-mail");
}
}
catch (customException $e)
{
echo $e->errorMessage();
}
catch(Exception $e)
{
echo $e->getMessage();
}
?>
خروجی کد بالا:
این آدرس ایمیل توسط spambots حفاظت می شود. برای دیدن شما نیاز به جاوا اسکریپت دارید is an example e-mail
توضیح مثال:
- متغییر email$ با یک آدرس ایمیل معتبر تنظیم می شود، اما شامل رشته ی "example" است.
- چون متغییر تعریف شده حاوی رشته ی "example" است? استثنا دوم در بلاک try راه اندازی می شود.
- بلاک catch دوم استثنا را می گیرد و خطای مناسب را برمی گرداند.
نکته: اگر استثنای بوجود آمده، بلاک catch خود را نیابد، شروع به جستجوی یک بلاک catch دیگر در "سطوح بالاتر" خواهد کرد.
دوباره راه اندازی استثناها
Wiki
بعضی مواقع ممکن است مایل باشید که یک استثنا به صورتی متفاوت از آنچه که استاندارد است بررسی شود. این امر با راه اندازی یک استثنا برای بار دوم از داخل بلاک catch امکان پذیر است.
یک اسکریپت خوب، باید خطاهای سیستمی را از کاربران معمولی پنهان کند، چون نمایش این خطاها برای برنامه نویس ها کاربرد دارد و برای کاربران معمولی جالب نیست، یک ایده خوب برای ساخت چنین پیغام هایی، دوباره راه اندازی استثناهاست.
مثال:
<?php
class customException extends Exception
{
public function errorMessage()
{
$errorMsg = $this->getMessage().' is not a valid E-Mail address.';
return $errorMsg;
}
}
$email = "این آدرس ایمیل توسط spambots حفاظت می شود. برای دیدن شما نیاز به جاوا اسکریپت دارید";
try
{
try
{
if(strpos($email, "example") !== FALSE)
{
throw new Exception($email);
}
}
catch(Exception $e)
{
//استثنا دوباره راه اندازی می شود
throw new customException($email);
}
}
catch (customException $e)
{
//display custom message
echo $e->errorMessage();
}
?>
توضیح مثال:
- بلاک try بک بلاک try دیگر را در خود جای داده است و این امکان را فراهم می کند تا از بلاکِ try داخلی یک استثنا که قبلاً راه اندازی شده را دوباره راه اندازی کرد.
- اگر متغییر ایمیل شامل زیر رشته "example" باشد استثنا برای بار اول راه اندازی می شود.
- بلاکِ catch اولی(Exception) استثنا را مهار کرده و در ادامه استثنای customException را راه اندازی می کند.
- بلاکِ catch دومی(customException) بلافاصله بعد از مهار کردن استثنا، پیغام مناسب را چاپ می کند.
تعیین یک بررسی کننده استثنای سطح بالا
Wiki
تابع ()set_exception_handler، نام یک تابع تعریف شده توسط کاربر را به عنوان پارامتر ورودی می گیرد و برای کار با همه ی استثناهایی که بلاک catch برای آنها مشخص نشده است، از تابع مذکور استفاده می کند.
مثال:
<?php
function myException($exception)
{
echo "<b>Exception:</b> " , $exception->getMessage();
}
set_exception_handler('myException');
throw new Exception('Uncaught Exception occurred');
?>
خروجی کد بالا:
Exception: Uncaught Exception occurred
در کد بالا بلاک catch وجود ندارد، درعوض یک بررسی کننده استثنای سطح بالا راه اندازی شده، که می تواند برای گرفتن یا مهار کردن استثناهایی که بلاک catch ندارند، استفاده شود.
قوانین استثناها
Wiki
- با قرار دادن کدهایمان در بلاک try به مهار کردن استثناهای بالقوه کمک کرده ایم.
- هر بلاک try یا throw باید حداقل یک بلاک catch متناظر داشته باشد
- استثناها می توانند درون یک بلاک catch راه اندازی شوند.
یک قانون ساده: چیزی را که راه اندازی(throw) می کنید باید مهار شود(catch).
برای مشاهده فیلم ها و آموزش های پروژه محور برنامه نویسی PHPکلیک کنید.
READ MORE