فرض کنید ، در یک برنامه فایلی را فراخوانی می کنیم که آن فایل وجود ندارد ، در این حالت با یک استثنا یا exception رو به رو می شویم که برنامه نویس باید برای حالت هایی که فایل وجود ندارد ، راه حلی را ارائه دهد . مانند لاگ گرفتن از exception و نشان دادن یک پیام ساده به کاربر و...
با استفاده از متد set_exception_handler میتوان یک handler اختصاصی برای پردازش استثنا در PHP پیاده سازی کرد ، فرض کنید می خواهیم وجود استثنا در خواندن محتوای یک فایل را بررسی نماییم .
اول یک handler اختصاصی را پیاده سازی می کنیم .
$exceptionHandler = function(Throwable $ex){
print "Exception handler received an exception : " . "<pre>".print_r($ex, true)."</pre>";
};
بعد با متد زیر handler را register می نماییم :set_exception_handler($exceptionHandler);
حال میتوانیم اینگونه حالت های استثنا را مدیریت نماییم :if (file_exists("example.txt")){
file_get_contents("example.txt");
}else{
throw new Exception("File Not Found");
}
چون نام فایلی را که وارد کردیم وجود ندارد ، بنا بر این با یک exception رو به رو می شویم و با پیام زیر رو به رو خواهیم شد و می توانیم به راحتی exception را trace نماییم که این پیام شامل پیام ارور ، کد ارور ، فایلی که ارور در آن رخ داده و شماره خط کدی که دچار مشکل است را به ما نشان می دهد :
Exception handler received an exception :
Exception Object
(
[message:protected] => File Not Found
[string:Exception:private] =>
[code:protected] => 0
[file:protected] => test.php
[line:protected] => 40
[trace:Exception:private] => Array
(
)
[previous:Exception:private] =>
)
می توانیم برای حالتهای مختلف Exception های اختصاصی خودمان را نیز پیاده سازی نماییم ، فرض کنید کاربر قرار است ایمیل را از ورودی به برنامه ما ارسال کند و اگر ایمیل ورودی ، یک ایمیل معتبر نبود ، با یک Exception رو به رو شود .
برای پیاده سازی کلاس اختصاصی Exception خود به صورت زیر باید عمل کنیم ، این کلاس از کلاس Exception ارث بری می کند :
class emailException extends Exception
{
public function errorMessage()
{
//error message
$error = 'Error on line ' . $this->getLine() . ' in ' . $this->getFile()
. ': <i>' . $this->getMessage() . '</i> is not a valid Email address';
return $error;
}
}
حال برای استفاده از این Exception میتوان به صورت زیر عمل کرد :
$email = "something[AT]yahoo.com";
try {
//check if email is validate
if (filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE) {
//throw exception if email is not valid
throw new emailException($email);
}
} catch (emailException $e) {
//display custom message
echo $e->errorMessage();
}
چون ایمیل ورودی یک ایمیل معتبر نیست با exception زیر مواجه خواهیم شد :
Error on line 45 in test.php: something[AT]yahoo.com is not a valid Email address
انواع خطا ها در PHP که شامل خطاهای زیر می باشد :
Notice : این خطا عموما زمانی برخ میدهد که از متغیری استفاده کنیم که تعریف نشده باشد ، مانند مثال زیر :
echo $name;
//خروجی
Notice: Undefined variable: name in test.php on line 53
Fatal error : این خطا جزو خطاهای بحرانی است و هنگامی که این خطا رخ دهد ، از اجرای مابقی برنامه جلوگیری می کند ، مانند زمانی که یک فایلی را require_once می کنیم که وجود خارجی ندارد .
Parse error : این خطا زمانی رخ می دهد که کد برنامه دارای syntax error باشد و مفسر PHP نتواند کدهای نوشته شده را به دلایل اشتباه تایپی ، تفسیر کند .
Warning : این خطا مربوط به زمانی است که برنامه از لحاظ منطق دارای مشکل بوده و یک Warning نشان داده می شود ، مانند تقسیم یک عدد صحیح بر صفر که با Warning زیر رو به رو می شویم :
Warning: Division by zero in test.php on line 53
Error Handler :
با استفاده از تابع set_error_handler و پاس دادن یک تابع به آن ، می توان خطاهای runtime را مدیریت کرد . برای پیاده سازی یک error handler اختصاصی می توان به شیوه زیر عمل کرد :
$errorHandler = function ($errno, $error_string, $error_file, $error_line, $context) {
$error_output = [
"error_code" => $errno,
"error_string" => $error_string,
"file" => $error_file,
"line" => $error_line
];
print "Error handler received error " . '<pre>'.print_r($error_output, true).'</pre>';
};
برای register کردن error handler از تابع زیر استفاده می کنیم :
set_error_handler($errorHandler);
حال فرض کنید اپلیکیشن در حالت runtime می خواهد عملیات I/O را روی یک فایل انجام دهد اما حجم آن فایل نباید بیش از یک مقدار خاص باشد :
const FILE_MAX_SIZE = 2000000;
if (filesize("example.csv") > FILE_MAX_SIZE) {
trigger_error("file size is to large", E_WARNING);
}
در صورت بزرگ تر بودن حجم فایل با ارور زیر مواجه می شویم :
Error handler received error
Array
(
[error_code] => 2
[error_string] => file size is to large
[file] => test.php
[line] => 23
)
توجه نمایید که هیچ گاه نباید اینگونه error ها و exception ها را به صورت مستقیم به کاربر نهایی نشان دهیم ، زیر این عمل می تواند امنیت اپلیکیشن را تهدید کرده و گاهی اوقات اطلاعات حساسی را در خروجی نمایش دهد، همچنین کاربران اصولا نمیتوانند درک درستی از این همه error داشته باشند و همچنین زیبایی اپلیکیشن نیز زیر سوال می رود.
اصولا قسمت های حیاتی برنامه که مستعد error و excption است را لاگ گیری کرده و تمامی این ارور ها را در فایل لاگ میتوان مشاهده کرد .