পিএইচপি এক্সেপশন হ্যান্ডেলিং
প্রোগ্রামে কোনো নির্দিষ্ট error সংঘটিত হলে এক্সিকিউশন(execution)-র স্বাভাবিক ধারাকে পরিবর্তন করার জন্য এক্সেপশন(Exception) ব্যবহার করা হয়।
এক্সেপশন কি
কোড এক্সিকিউশনের সময় কোনো নির্দিষ্ট error বা ব্যতিক্রমধর্মী কন্ডিশনের সৃষ্টি হলে, কোড এক্সিকিউশন(execution)-র স্বাভাবিক ধারাকে পরিবর্তন করার জন্য এক্সেপশন(Exception) ব্যবহার করা হয়। এই কন্ডিশন(conditon)-কে এক্সেপশন বলা হয়।
পিএইচপি ৫ আসার পরে error নিয়ন্ত্রণে নতুন মাত্রা হিসাবে অবজেক্ট ওরিয়েন্টেড পদ্ধতি যোগ হয়েছে।
এক্সেপশনের উৎপত্তি হলে সাধারণত নিচের বিষয়সমূহ সংঘটিত হয়ঃ
- সাম্প্রতিক কোডের ফিল্ড সংরক্ষিত হয়।
- কোডের এক্সিকিউশন বর্তমান অবস্থা থেকে পূর্ব নির্ধারিত বা কাস্টম এক্সেপশন হ্যান্ডেলার ফাংশনের কাছে সুইচ করবে।
- পরিস্থিতির উপর ভিত্তিকরে হ্যান্ডেলার সংরক্ষিত কোডের ফিল্ড থেকে এক্সিকিউশন চালু করতে পারে, স্ক্রিপ্ট এক্সিকিউশন শেষ করে দিতে পারে অথবা ভিন্ন লোকেশন থেকে স্ক্রিপ্ট চলমান রাখতে পারে।
এই অধ্যায়ে নিম্নোক্ত error হ্যান্ডেলিং মেথডসমূহ নিয়ে আলোচনা করবোঃ
- এক্সেপশনের মৌলিক ব্যবহার
- কাস্টম(custom) এক্সেপশন হ্যান্ডেলার তৈরি
- মাল্টিপল(Multiple) এক্সেপশন
- এক্সেপশনকে পুনরায় নিক্ষেপ(Re-throwing) করা
- টপ লেভেলের এক্সেপশন হ্যান্ডেলার সেট করা
বিঃদ্রঃ শুধুমাত্র error কন্ডিশন নিয়ে কাজ করার জন্য এক্সেপশন ব্যবহার করা উচিৎ। কোনো নির্দিষ্ট পয়েন্টে এক স্থান থেকে অন্য স্থানে লাফ দিয়ে যাওয়ার জন্য এটি ব্যবহার করা উচিৎ নয়।
এক্সেপশনের মৌলিক ব্যবহার
যখন কোনো এক্সেপশন নিক্ষিপ্ত হয় তখন এটিতে যে কোড থাকে তা সম্পাদিত(executed) হয় না, এক্ষেত্রে পিএইচপি এর সাথে মিলসম্পন্ন ক্যাচ( "catch") ব্লককে খুঁজে বের করার চেষ্টা করে।
যদি কোনো এক্সেপশন ধরতে না পারে তাহলে Uncaught Exception ম্যাসেজের মাধ্যমে মারাত্মক ভুল(fatal error) প্রেরণ করবে।
এক্সেপশনকে নিক্ষেপ করে না ধরলে কি হয় তা উদাহরণের মাধ্যমে দেখা যাক।
<?php
//এক্সেপশনসহ একটি ফাংশন তৈরি করুন
function checkNumber($num) {
if($num>1) {
throw new Exception("Value must be 1 or below");
}
return true;
}
//এক্সেপশনকে ট্রিগার করুন
checkNumber(2);
?>
( ! ) Fatal error: Uncaught exception 'Exception' with message 'Value must be 1 or below'
( ! ) Exception: Value must be 1 or below
Try, throw এবং catch
আমরা যদি উপরের উদাহরণে error কে এড়িয়ে চলতে চাই তাহলে এক্সেপশন হ্যান্ডেল করার জন্য উপযুক্ত কোড লেখার প্রয়োজন হবে।
উওযুক্ত এক্সেপশন হ্যান্ডেলিং কোডে নিম্নোক্ত বিষয়সমূহ থাকেঃ
- Try - এক্সেপশন ব্যবহার করে এমন ফাংশনকে "try" ব্লকের মধ্যে রাখতে হয়। যদি কোনো এক্সেপশন না থাকে তাহলে স্বাভাবিকভাবেই কোড সম্পাদিত হোয়বে। কিন্তু যদি এক্সেপশন থাকে তাহলে এটি নিক্ষিপ্ত("thrown") হয়।
- Throw - এটির মাধ্যমে এক্সেপশন ছুড়ে ফেলা হয়। মনে রাখতে হবে প্রত্যেকটি থ্রো("throw") ব্লকের জন্য কমপক্ষে একটি ক্যাচ("catch") ব্লক থাকবে। অর্থাৎ কোনো কিছু ছুড়ে ফেলার পরে তা পূনরুদ্ধার করতে হবে অথবা ধরতে হবে।
- ছুড়ে ফেলা এক্সেপশনকে Catch - ক্যাচ("catch") ব্লক পূনরুদ্ধার করে এবং এক্সেপশনের তথ্য সম্বলিত একটি অবজেক্ট তৈরি করে।
চলুন বৈধ্য কোড সম্বলিত এক্সেপশনকে ট্রিগার(trigger) করার চেষ্টা করিঃ
<?php
// এক্সেপশনের সহিত একটি ফাংশন তৈরি
function checkNumber($num) {
if($num > 1) {
throw new Exception("Value must be 1 or below");
}
return true;
}
// "try" ব্লকের মধ্যে এক্সেপশন নিক্ষিপ্ত হবে
try {
checkNumber(2);
// যদি এক্সেপশনটি নিক্ষিপ্ত হয়, তাহলে এই লিখাটি প্রদর্শিত হবে না
echo "If you see this, the number is 1 or below";
}
// এক্সেপশনটি ক্যাচ করে
catch(Exception $obg) {
echo 'Message: ' .$obg->getMessage();
}
?>
Message: Value must be 1 or below
উপরের উদাহরণের ব্যাখ্যাঃ
উপরের কোড এক্সেপশন থ্রো করে এবং ধরেঃ
- প্রথমে checkNumber() ফাংশনের সৃষ্টি হয়। এটি সংখ্যাটি ১ এর চেয়ে বড় কিনা তা চেক করে। যদি বড় হয় তাহলে এক্সেপশন থ্রো হয়।
- "try" ব্লক থেকে checkNumber() ফাংশনকে কল করা হয়।
- checkNumber() ফাংশনের মধ্যে এক্সেপশনকে ছুড়ে ফেলা হয়।
- "catch" ব্লক ছুড়ে ফেলা এক্সেপশনকে তুলে আনে এবং এক্সেপশনের তথ্য নিয়ে একটি অবজেক্ট($obg) তৈরি করে
- এক্সেপশন অবজেক্ট থেকে $obg->getMessage() কে কল করে এক্সেপশন থেকে error ম্যাসেজকে প্রিন্ট করা হয়।
যাইহোক, প্রত্যেক throw এর জন্য একটি catch থাকে এটি টপ লেভেল হ্যান্ডেলার সেট করে error হ্যান্ডেল করার জন্য।
একটি কাস্টম এক্সেপশন ক্লাস তৈরি
একটি কাস্টম এক্সেপশন হ্যান্ডেলার তৈরি করতে আপনাকে অবশ্যই একটি ফাংশন নিয়ে বিশেষ ক্লাস তৈরি করতে হবে আর যখনই পিএইচপিতে এক্সেপশন ঘটবে তখনই ঐ ফাংশনটি ডাকা হবে। ক্লাসটি অবশ্যই এক্সেপশন ক্লাসের এক্সটেনশন(extension) হতে হবে।
কাস্টম এক্সেপশন ক্লাস পিএইচপি এক্সেপশন ক্লাস থেকে প্রোপার্টি সমুহ ইনহেরিট করতে পারে এবং আপনি এটিতে কাস্টম ফাংশন যোগ করতে পারেন।
চলুন একটি এক্সেপশন ক্লাস তৈরি করা যাকঃ
<?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';
return $errorMsg;
}
}
$email = "someone@example...com";
try {
// ই-মেইলটি সঠিক নাকি ভুল তা পরীক্ষা করছে
if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE) {
// ই-মেইলটি যদি বৈদ না হয় সেক্ষেত্রে এক্সেপশনটি নিক্ষিপ্ত হবে
throw new customException($email);
}
}
catch (customException $obg) {
// কাস্টম মেসেজটি প্রদর্শিত হবে
echo $obg->errorMessage();
}
?>
নতুন ক্লাসটি পুরাতন এক্সেপশন ক্লাসের অনুলিপি এর সাথে নতুন করে errorMessage()
ফাংশনটি যুক্ত হয়েছে। যেহেতু নতুন ক্লাসটি পুরাতন ক্লাসের অনুলিপি এবং এটি পুরাতন ক্লাসেরই মেথোড এবং প্রোপার্টি সমুহ ইনহেরিট করছে, সুতরাং আমরা এক্সেপশন ক্লাসের মেথোড সমূহ এইভাবে ব্যবহার করতে পারিঃ- getLine()
, getFile()
এবং getMessage()
উপরের উদাহরণের ব্যাখ্যাঃ
উপরের কোডটি একটি এক্সেপশন throws করছে এবং কাস্টম এক্সেপশন ক্লাস catches করছেঃ
customException()
ক্লাসটি পুরানো এক্সেপশন ক্লাসের এক্সটেনশন হিসাবে তৈরি করা হয়। এই পদ্ধতিটি পুরানো এক্সেপশন ক্লাস থেকে সমস্ত মেথোড এবং প্রোপার্টি সমূহ ইনহেরিট করতে সক্ষম।- এই ক্লাসে
errorMessage()
ফাংশনটি তৈরি করা হয়েছে। এই ফাংশনটি একটি ত্রুটি মেসেজ ফেরত পাঠায় যদি কোনো ইমেলের ঠিকানা অবৈদ হয়। - যদি ইমেলের ঠিকানাটি ভুল হয় সেক্ষেত্রে $email ভেরিয়েবিলটি স্ট্রিং দ্বারা পূর্ণ করা হয়।
- "try" ব্লকটি কার্যকর হয় এবং ই-মেইলের ঠিকানাটি অবৈদ হওয়ার কারনে একটি এক্সেপশন নিক্ষেপ করা হয়
- "catch" ব্লকটি নিক্ষিপ্ত এক্সেপশনটি ধারন করে এবং ত্রুটি মেসেজটি প্রদর্শন করে।
একাধিক এক্সেপশন(exceptions)
একাধিক শর্ত পরীক্ষা করার জন্য স্ক্রিপ্টে একাধিক এক্সেপশন ব্যবহার করা সম্ভব।
কয়েকটি if..else ব্লক, একটি switch অথবা নেস্ট একাধিক এক্সেপশন ব্যবহার করা সম্ভব। এই সকল এক্সেপশন গুলো বিভিন্ন এক্সেপশন ক্লাস ব্যবহার করতে পারে এবং বিভিন্ন ত্রুটি মেসেজ রিটার্ন করেঃ
<?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';
return $errorMsg;
}
}
$email = "someone@example.com";
try {
// ই-মেইলটি সঠিক নাকি ভুল তা পরীক্ষা করছে
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 $obg) {
echo $obg->errorMessage();
}
catch(Exception $obg) {
echo $obg->getMessage();
}
?>
উপরের উদাহরণের ব্যাখ্যাঃ
উপরের কোডটি দুইটি শর্ত পরীক্ষা করে এবং যদি একটিও শর্ত সত্যি না হয় সেক্ষেত্রে একটি এক্সেপশন throws করেঃ
customException()
ক্লাসটি পুরানো এক্সেপশন ক্লাসের এক্সটেনশন হিসাবে তৈরি করা হয়। এই পদ্ধতিটি পুরানো এক্সেপশন ক্লাস থেকে সমস্ত মেথোড এবং প্রোপার্টি সমূহ ইনহেরিট করতে সক্ষম।- এই ক্লাসে
errorMessage()
ফাংশনটি তৈরি করা হয়েছে। এই ফাংশনটি একটি ত্রুটি মেসেজ ফেরত পাঠায় যদি কোনো ইমেলের ঠিকানা অবৈদ হয়। - $email ভ্যারিয়েবলটি একটি বৈধ ই-মেইল ঠিকানা হয় তবে এটি স্ট্রিং আকারে ধারন করে এবং ই-মেইলের ঠিকানায় "example" লিখাটি উল্লেখ রয়েছে।
- "try" ব্লকটি কার্য-সম্পাদন করে কিন্তু প্রথম শর্তটি কোনো এক্সেপশন নিক্ষেপ করে না।
- ই-মেইলের ঠিকানার মধ্যে "example" লিখাটি উল্লেখ থাকায় দ্বিতীয় শর্তটি সত্য হয় এবং একটি এক্সেপশন নিক্ষেপ করে।
- "catch" ব্লকটি নিক্ষিপ্ত এক্সেপশনটি ধারন করে এবং ত্রুটি মেসেজটি প্রদর্শন করে।
যদি এক্সেপশনটি customException ক্লাসের মাধ্যমে নিক্ষেপ করা হতো এবং সেখানে ক্যাচ করার মত কোনো customException থাকতো না, সেক্ষেত্রে শুধুমাত্র বেস এক্সেপশনটি ক্যাচ করতো এবং এই এক্সেপশোনটি সেখানে হ্যান্ডেল করা হতো।
পুনরায় নিক্ষিপ্ত এক্সেপশন
কখনও কখনও, যখন একটি এক্সেপশন নিক্ষিপ্ত হয়, তখন আপনি ইচ্ছা করলে এর চিরাচরিত উপায় ব্যাতিত ভিন্ন উপায়ে এটিকে হ্যান্ডেল করতে পারেন। একটি "catch" ব্লকের মধ্যে একটি এক্সেপশনকে দ্বিতীয়বার নিক্ষেপ করা সম্ভব।
একটি স্ক্রিপ্ট সিস্টেমের ত্রুটি গুলো ব্যবহারকারীর কাছ থেকে লুকিয়ে ফেলে। একজন কোডারের জন্য সিস্টেমের ত্রুটি গুলো অনেক গুরুত্বপুর্ণ হতে পারে, কিন্তু একজন ব্যবহারকারীর কাছে সিস্টেমের ত্রুটি গুলো বিরক্তিকর মনে হতে পারে। সুতরাং, ব্যবহারকারীর জন্য জিনিসগুলো আরো সহজতর করার জন্য এক্সেপশন গুলোকে পুনরায় দ্বিতীয়বার ব্যবহারকারীর উপযুক্ত মেসেজ সহকারে নিক্ষেপ করা হয়ঃ
<?php
class customException extends Exception {
public function errorMessage() {
// ত্রুটি মেসেজ
$errorMsg = $this->getMessage()." is not a valid E-mail.";
return $errorMsg;
}
}
$email = "someone@example.com";
try {
try {
// ই-মেইলের ঠিকানায় "example" লিখাটি বিদ্যমান কিনা তা পরীক্ষা করছে
if(strpos($email, "example") !== FALSE) {
// ই-মেইলটি যদি বৈদ না হয় সেক্ষেত্রে এক্সেপশনটি নিক্ষিপ্ত হবে
throw new Exception($email);
}
}
catch(Exception $obg) {
// পুনরায় নিক্ষিপ্ত এক্সেপশন
throw new customException($email);
}
}
catch (customException $obg) {
// কাস্টম মেসেজটি প্রদর্শিত হবে
echo $obg->errorMessage();
}
?>
উপরের উদাহরণের ব্যাখ্যাঃ
উপরের কোডে ই-মেইলের ঠিকানা পরীক্ষা করা হয় এবং যদি ই-মেইলের ঠিকানার মধ্যে "example" লিখাটি উল্লেখ থাকে, সেক্ষেত্রে এক্সেপশনটি আবার পুনরায় নিক্ষেপ করা হয়ঃ
customException()
ক্লাসটি পুরানো এক্সেপশন ক্লাসের এক্সটেনশন হিসাবে তৈরি করা হয়। এই পদ্ধতিটি পুরানো এক্সেপশন ক্লাস থেকে সমস্ত মেথোড এবং প্রোপার্টি সমূহ ইনহেরিট করতে সক্ষম।- এই ক্লাসে
errorMessage()
ফাংশনটি তৈরি করা হয়েছে। এই ফাংশনটি একটি ত্রুটি মেসেজ ফেরত পাঠায় যদি কোনো ইমেলের ঠিকানা অবৈদ হয়। - $email ভ্যারিয়েবলটি একটি বৈধ ই-মেইল ঠিকানা হয় তবে এটি স্ট্রিং আকারে ধারন করে এবং ই-মেইলের ঠিকানায় "example" লিখাটি উল্লেখ রয়েছে।
- "try" ব্লকটির মধ্যে আরো একটি "try" ব্লক বিদ্যমান থাকে, যেন এক্সেপশনকে পুনরায় নিক্ষেপ করা সম্ভব হয়।
- যখনই ই-মেইলের মধ্যে "example" লিখাটি উল্লেখ থাকবে, তখনই এক্সেপশনটি নিক্ষেপ করা হবে।
- "catch" ব্লকটি একটি এক্সেপশন ধরবে এবং পুনরায় একটি "customException" নিক্ষেপ করবে।
- অন্য একটি "catch" ব্লক "customException" কে ক্যাচ করবে এবং ত্রুটি মেসেজটি প্রদর্শন করবে।
যদি এক্সেপশনটি তার বর্তমান "try" ব্লকে কোনো "catch" খুঁজে না পায়, সেক্ষেত্রে এটি বর্তমান "try" ব্লকে উপরের স্তরে "catch" ব্লক খুঁজে।
উপরের স্তরের এক্সেপশন হ্যান্ডেলার সেট করুন
set_exception_handler() ফাংশনটি ব্যবহারকারী কর্তৃক ডিফাইনকৃত ফাংশন যা, যে সকল এক্সেপশন গুলো ক্যাচ করা হয়না তাদের হ্যান্ডেল করেঃ
<?php
function ownException($obgxception) {
echo "<b>Exception:</b> " . $obgxception->getMessage();
}
set_exception_handler('ownException');
throw new Exception('Non Catchable Exception occurred');
?>
Message: Non Catchable Exception occurred
উপরের কোডটিতে কোনো "catch" ব্লক নেই। এর পরিবর্তে উপরের স্তরে ফাংশনটি কাজ করা চালু করে, যা ক্যাচ না হওয়া এক্সেপশন গুলো হ্যান্ডেল করে।
এক্সেপশনের জন্য নিয়মাবলী
- সম্ভাব্য এক্সেপশন গুলো ধরতে সাহায্য করার জন্য কোডগুলো "try" ব্লক দ্বারা বেষ্টিত থাকতে পারে।
- প্রতিটি "try" ব্লক অথবা "throw" এর জন্য অবশ্যই একটি "catch" ব্লক থাকে।
- বিভিন্ন ক্লাসের এক্সেপশন গুলো ধরার জন্য একাধিক "catch" ব্লক ব্যবহার করা যেতে পারে।
- "try" ব্লকে একটি "catch" ব্লকের মধ্যে এক্সেপশন গুলো নিক্ষেপ অথবা পুনরায় নিক্ষেপ করা যেতে পারে।
একটি সাধারন নিয়মঃ যদি আপনি কিছু নিক্ষেপ করেন, আপনাকে তা ধরতেই হবে।