پی ایچ پی مدیریت استثنا

خطا (Exception) برای تغییر مسیر عادی اجرای اسکریپت در صورت بروز خطاها استفاده می‌شود.

چه چیزی است؟

PHP 5 روش جدیدی برای مدیریت خطا بر اساس شیء ارائه داده است.

مدیریت خطا برای تغییر مسیر عادی اجرای اسکریپت در صورت بروز خطاها (خطاهای غیرقابل پیش‌بینی) استفاده می‌شود. این وضعیت به عنوان خطا شناخته می‌شود.

وقتی که خطایی رخ داد، معمولاً اتفاق می‌افتد:

  • وضعیت فعلی کد ذخیره خواهد شد
  • اجرای کد به مدیریتکنندگان خطای پیش‌تعیین شده تغییر خواهد کرد
  • بسته به شرایط، مدیریتکننده ممکن است از وضعیت کد ذخیره شده مجدداً شروع به اجرای کد کند، اجرای اسکریپت را قطع کند یا از مکان دیگری در کد شروع به اجرای اسکریپت کند

ما روش‌های مختلف مدیریت خطا را نشان خواهیم داد:

  • استفاده ابتدایی از خطا
  • ایجاد مدیریتکنندگان خطای سفارشی
  • خطاهای چندگانه
  • پرتاب مجدد خطا
  • تنظیم مدیریتکنندگان خطای بالایی

استفاده ابتدایی از خطا

وقتی که خطایی پرتاب شود، کد بعدی اجرا نمی‌شود، PHP سعی خواهد کرد بلوک کد "catch" مطابقی پیدا کند.

اگر خطایی نگرفته شود و از set_exception_handler() برای مدیریت مناسب استفاده نشده باشد، یک خطای جدی (خطای حیاتی) رخ خواهد داد و پیام خطا "Uncaught Exception" (خطای غیرقابل گرفتن) نمایش داده خواهد شد.

بیایید سعی کنیم یک خطا پرتاب کنیم و آن را نگرفتیم:

<?php
//فونکشنی ایجاد کنید که از خطا استفاده کند
//ایک غلطی بول سکتا فونکشن بنائیں
 {
 فونکشن checkNum($number)
  {
  اگر ($number>1)
  }
 بول 'پیغام: ' .$e->getMessage();
 }
//exception trigger
// "try" کد بلاک میں غلطی کو بول دیا جائیگا
?>

کد بالا خطایی مانند زیر را دریافت خواهد کرد:

خطای حیاتی: خطا غیرقابل گرفتن 'Exception' 
با پیام 'مقدار باید 1 یا کمتر باشد' در C:\webfolder\test.php:6 
Stack trace: #0 C:\webfolder\test.php(12): 
checkNum(28) #1 {main} پرتاب شده در C:\webfolder\test.php در خط 6

کوشش، پرتاب و گرفتن

برای جلوگیری از خطاهایی که در مثال بالا رخ داد، باید کد مناسب برای مدیریت خطاها ایجاد کنیم.

برای مدیریت صحیح، برنامه باید شامل موارد زیر باشد:

  1. کوشش کن - فونکشن‌هایی که از خطاها استفاده می‌کنند باید در بلوک کد "کوشش" قرار گیرند. اگر خطایی رخ ندهد، کد به صورت عادی ادامه خواهد داد. اما اگر خطایی رخ داد، یک خطا به بیرون پرتاب خواهد شد.
  2. Throw - 这里规定如何触发异常。每一个 "throw" 必须对应至少一个 "catch"
  3. بولیں - یہاں سے غلطی کو کیسے بولنا چاہئے، ہر 'throw' کو کم سے کم ایک 'catch' سے دوسرا کریں

کچ کریں - "catch" کد بلاک غلطی کو کچ سکتا ہے، اور ایک اشیاء بناتا ہے جس میں غلطی کی معلومات شامل ہوتی ہیں

<?php
ایک غلطی بولیں:
//ایک غلطی بول سکتا فونکشن بنائیں
 {
 فونکشن checkNum($number)
  {
  اگر ($number>1)
  }
 بول 'پیغام: ' .$e->getMessage();
 }
بول رتائی;
try
 {
 // "try" کد بلاک میں غلطی کو بول دیا جائیگا
 checkNum(2);
 // اگر غلطی بول دی جائی، اس متن کو نہیں دکھایا جائے گا
 }
//غلطی کا کچ کریں
catch(Exception $e)
 {
 بول 'پیغام: ' .$e->getMessage();
 }
?>

بالاترین کد اس طرح کی غلطی کو حاصل کرتا ہے:

پیغام: کوئی اقدار 1 یا نیچل سے کم ہونا چاہئے

مثال کی وضاحت:

بالاترین کد نے غلطی کو بول دیا اور اس کو کچ لیا:

  1. checkNum() فونکشن کی تشکیل کی جاتی ہے، جو اعداد کو 1 سے زیادہ کا پتہ لگانا چاہئے، اگر کسی اعداد کو 1 سے زیادہ کا پتہ لگا تو اس میں کسی غلطی کو بول دیا جاتا ہے
  2. "try" کد بلاک میں checkNum() فونکشن کو بول دیا جاتا ہے
  3. checkNum() فونکشن میں غلطی کو بول دیا جاتا ہے
  4. "catch" کد بلاک اس کی غلطی کو حاصل کرتا ہے، اور ایک اشیاء ($e) بناتا ہے جس میں غلطی کی معلومات شامل ہوتی ہیں
  5. exception کے اشیاء سے $e->getMessage() کو بولنے کے ذریعے اس کی غلطی کا پیغام نکالنا

بھلکہ، 'هر throw کو catch کا دوسرا ہونا چاہئے' کے اصول کی پیروی کی، میں ایک اعلیٰ سطح کا معالجہ کلاس بناسکتا ہوں تاکہ چھو رہی غلطیاں کا معالجہ کیا جاسکے۔

خودساز کلاس Exception بنائیں

خودساز کلاس کی تشکیل دوبارہ کی معالجہ بنانے میں سادگی کی وجہ سے ممکن ہوتی ہے۔ ہم نے ایک مخصوص کلاس بنائی ہے، جو جب پی ایچ پی میں کسی غیر متوقع حالت کا واقع ہوتا ہے تو اس کی فونکشنوں کو بول سکتا ہے۔ اس کلاس کو exception کی کلاس کی ایک ترقی کی حیثیت سے دیکھا جانا چاہئے۔

یہ خودساز کلاس exception کی کلاس کی تمام اقدار کو وراثت لیندی ہے، آپ اس میں خودساز فونکشنوں کو شامل کرسکتے ہیں۔

ہم شروع کر رہے ہیں کہ exception کلاس بنائیں:

<?php
class customException extends Exception
 {
 public function errorMessage()
  {
  //غلط پیغام
  $errorMsg = 'Error on line '.$this->getLine().' in '.$this->getFile()
  : <b>'.$this->getMessage().'</b> نمی‌تواند یک آدرس ایمیل معتبر باشد;
  return $errorMsg;
  }
 }
$email = "someone@example...com";
try
 {
 //check if 
 if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE)
  {
  //ایمیل نہیں صحیح ہونے کی صورت میں کیوکستکشن پھرکشا دیجئے
  throw new customException($email);
  }
 }
catch (customException $e)
 {
 //دکھانے والی کیوکستکشن
 echo $e->errorMessage();
 }
?>

این کلاس جدید یک کپی از کلاس خطای قدیمی است که به آن functhonserrorMessage() اضافه شده است. به دلیل اینکه این کلاس یک کپی از کلاس قدیمی است، از ویژگی‌ها و روش‌های کلاس قدیمی ارث می‌برد، بنابراین می‌توانیم از روش‌های کلاس خطا استفاده کنیم، مانند getLine()، getFile() و getMessage().

مثال کی وضاحت:

کد بالا یک خطا پرتاب می‌کند و آن را با استفاده از یک کلاس خطای سفارشی می‌گیرد:

  1. customException() کیوکستکشن کیوکستکشن کیوکستکشن کی ایک توسیع کے طور پر بنائی گئی ہے، جس سے یہ اس کیوکستکشن کی تمام خاصیتوں اور کیوکستکشنوں کو وارث بنتی ہے۔
  2. функشنerrorMessage() ایجاد کنید. اگر آدرس ایمیل نامعتبر باشد، این функشن پیام خطایی بازمی‌گرداند
  3. $email را به یک رشته آدرس ایمیل نامعتبر تنظیم کنید
  4. بلوک "try" اجرا می‌شود، به دلیل اینکه آدرس ایمیل نامعتبر است، یک خطا پرتاب می‌شود
  5. بلوک "catch" خطاها را می‌گیرد و پیام خطا را نمایش می‌دهد

خطاهای چندگانه

می‌توان برای یک اسکریپت چندین خطا استفاده کرد تا شرایط مختلف را بررسی کرد.

می‌توان از چندین بلوک if..else یا یک بلوک switch یا چندین خطای پیچیده استفاده کرد که از کلاس‌های مختلف خطا استفاده می‌کنند و پیام‌های خطای مختلفی را بازمی‌گردانند:

<?php
class customException extends Exception
{
public function errorMessage()
{
//غلط پیغام
$errorMsg = 'Error on line '.$this->getLine().' in '.$this->getFile()
: <b>'.$this->getMessage().'</b> نمی‌تواند یک آدرس ایمیل معتبر باشد;
return $errorMsg;
}
}
$email = "someone@example.com";
try
 {
 //check if 
 if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE)
  {
  //ایمیل نہیں صحیح ہونے کی صورت میں کیوکستکشن پھرکشا دیجئے
  throw new customException($email);
  }
 //ایمیل آدرس میں "example" جملے کا موقف چکا جائے
 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();
 }
?>

مثال کی وضاحت:

کد بالا دو شرط را تست می‌کند، اگر هیچ یک از شرط‌ها برقرار نباشد، یک خطا پرتاب می‌شود:

  1. customException() کیوکستکشن کیوکستکشن کیوکستکشن کی ایک توسیع کے طور پر بنائی گئی ہے، جس سے یہ اس کیوکستکشن کی تمام خاصیتوں اور کیوکستکشنوں کو وارث بنتی ہے۔
  2. errorMessage() کیوکستکشن بنائی گئی ہے، اگر ایمیل آدرس غیر صحیح ہو تو اس کیوکستکشن نے غلط پیغام واپس دیا ہے۔
  3. بلوک "try" اجرا می‌شود، در شرط اول، خطایی پرتاب نمی‌شود.
  4. به دلیل اینکه ایمیل شامل رشته "example" است، شرط دوم خطا را فعال می‌کند.
  5. بلوک "catch" خطاها را می‌گیرد و پیام خطای مناسب را نمایش می‌دهد

اگر customException نتواند گرفته شود و فقط base exception گرفته شده باشد، خطا در آنجا پردازش می‌شود.

پرتاب مجدد خطا

بعض وقت‌ها، وقتی یک خطا پرتاب می‌شود، ممکن است بخواهید آن را به روشی متفاوت از استاندارد پردازش کنید. می‌توانید دوباره یک خطا را در یک بلوک "catch" پرتاب کنید.

اسکریپت کو استعمال کنندگان کو سسٹم غلطوں سے پوشانا چاہئیے۔ سسٹم غلطوں کا لفظ پروگرامر کے لئے اہم ممکن ہو، لیکن استعمال کنندگان ان پر دلچسپی نہیں رکھتے۔ استعمال کنندگان کو آسان طور پر استعمال کرنے کی آسانی کے لئے، آپ دوبارہ کیوکستکشن پھرکشا دی سکتے ہیں جس میں استعمال کنندگان کے لئے معقول پیغامات شامل ہو:

<?php
class customException extends Exception
 {
 public function errorMessage()
  {
  //غلط پیغام
  $errorMsg = $this->getMessage().' is not a valid E-Mail address.';
  return $errorMsg;
  }
 }
$email = "someone@example.com";
try
 {
 try
  {
  //ایمیل آدرس میں "example" جملے کا موقف چکا جائے
  if(strpos($email, "example") !== FALSE)
   {
   //ایمیل نہیں صحیح ہونے کی صورت میں کیوکستکشن پھرکشا دیجئے
   throw new Exception($email);
   }
  }
 catch(Exception $e)
  {
  //کیوکستکشن دوبارہ پھرکشا دیجئے
  throw new customException($email);
  }
 }
catch (customException $e)
 {
 //دکھانے والی کیوکستکشن
 echo $e->errorMessage();
 }
?>

مثال کی وضاحت:

بالا کا کد ایمیل آدرس میں "example" جملے کا موقف چکا ہے، اگر موقف موجود ہو تو دوبارہ کیوکستکشن پھرکشا دی گئی ہے:

  1. customException() کیوکستکشن کیوکستکشن کیوکستکشن کی ایک توسیع کے طور پر بنائی گئی ہے، جس سے یہ اس کیوکستکشن کی تمام خاصیتوں اور کیوکستکشنوں کو وارث بنتی ہے۔
  2. errorMessage() کیوکستکشن بنائی گئی ہے، اگر ایمیل آدرس غیر صحیح ہو تو اس کیوکستکشن نے غلط پیغام واپس دیا ہے۔
  3. $email متغیر کو ایک موثر ای میل آدرس کا تعین کیا گیا ہے، لیکن اس میں "example" جملے شامل ہے۔
  4. try کیوکستکشن میں دوسرے try کیوکستکشن شامل ہے، جس کی وجہ سے کیوکستکشن دوبارہ پھرکشا دی گئی ہے۔
  5. ایمیل میں "example" جملے کی وجہ سے کیوکستکشن چل پئی ہے۔
  6. catch کیوکستکشن نے اس کیوکستکشن کو کچلی اور دوبارہ کیوکستکشن کیوکستکشن کا پھرکشا دیا۔
  7. مقابله کیوکستکشن کا محصل ہوا، اور ایک غلط پیغام دکھایا گیا۔

اگر استثنایی در بلوک فعلی "try" ناکاوش شود، آن استثنا در سطح بالاتر به دنبال بلوک catch خواهد گشت.

تنظیم مدیریت استثنا سطح بالایی (Top Level Exception Handler)

توابع set_exception_handler() می‌تواند فانکشنی کاربر تعریف شده برای مدیریت تمام استثناهای ناکاوش تنظیم کند.

<?php
فانکشن myException($exception)
{
echo "<b>استثنا:</b> " , $exception->getMessage();
}
set_exception_handler('myException');
پرتاب جدید استثنا('استثنا ناکاوش رخ داد');
?>

خروجی کد بالا باید مشابه این باشد:

استثنا: استثنا ناکاوش رخ داد

در کد بالا، بلوک catch وجود ندارد بلکه برنامه‌ریزی استثنا به سطح بالاتر پیاده می‌شود. باید از این تابع برای گرفتن تمام استثناهای ناکاوش استفاده کرد.

قوانین استثنا

  • کد‌هایی که نیاز به مدیریت استثنا دارند باید در بلوک try قرار گیرند تا استثناهای پنهان را بگیرند.
  • هر بلوک try یا throw باید حداقل یک بلوک catch مشابه داشته باشد.
  • با استفاده از چندین بلوک catch می‌توان استثناهای مختلفی را گرفت.
  • می‌توان استثنایی را در بلوک کد catch مجدداً پرتاب کرد (پرتاب مجدد).

به طور خلاصه: اگر استثنایی پرتاب شد، باید آن را گیر بیاورید.