Exceptions Handling in PHP

php exception handling

PHP-তে Exception handling হল এমন একটি প্রক্রিয়া যা PHP script এক্সেকিউশন করার সময় ঘটা বিভিন্ন রকমের errors, exceptions এবং অপ্রত্যাশিত events গুলি ডেভেলপারদের হ্যান্ডেল করতে এবং ম্যানেজ করতে দেয় , যা Exceptions গুলি exceptional বা error conditions গুলি নির্দেশ করতে ব্যবহৃত হয় যা কোড এক্সেকিউশনের স্বাভাবিক প্রবাহকে ব্যাহত করে।

যখন একটি exceptional পরিস্থিতি দেখা দেয়, যেমন runtime error বা একটি unexpected input, তখন একটি exception object তৈরি হয় এবং সেটি throw করা হয়। সাথে সাথে এটি প্রোগ্রামের স্বাভাবিক এক্সেকিউশনের পরিবর্তে একটি exception handler হিসাবে পরিচিত কোডের একটি বিশেষ ব্লকে নিয়ন্ত্রণ স্থানান্তর করে। এবং exception handler টি তখন throw করা exception টি catch করতে পারে, error টি লগ করতে পারে, recovery actions সম্পাদন করতে পারে বা ইউজারকে একটি error message প্রদর্শন করতে পারে।

পিএইচপি-তে, exception handling এর কাজ try-catch ব্লক নামে পরিচিত একটি প্রক্রিয়ার মাধ্যমে কাজ করে। পিএইচপি-তে exception handling কীভাবে এবং কি কি ধাপে কাজ করে তা নিম্নে দেখানো হলো :

  1. The try block: যে কোডটি পোটেনশিয়াললি একটি exception Throw করতে পারে সেটি একটি try ব্লকের ভিতরে স্থাপন করা হয়। এই ব্লকটি তার স্কোপের মধ্যে ঘটে যাওয়া exception গুলি পর্যবেক্ষণ এবং ক্যাপচার করার জন্য রেস্পন্সিবল৷ যদি try ব্লকের মধ্যে একটি exception throw করা হয়, তখন কোডের normal execution টি immediately interrupted হয় এবং এর control সংশ্লিষ্ট catch ব্লকে স্থানান্তরিত হয়।
  2. The throw statement: যেকোনো একটি exception কে throw করতে, আপনি throw statement ব্যবহার করতে পারেন। এটি সাধারণত try block এর মধ্যে রাখা হয় যখন একটি exceptional situation সম্মুখীন হয়, তখন throw statement একটি exception object তৈরি করে, যা exception সম্পর্কে ইনফরমেশন, যেমন এর type এবং message কে অন্তর্ভুক্ত করে।
  3. The catch block: যখন একটি exception কে try ব্লকের মধ্যে throw করা হয়, তখন এক্সিকিউশনটি উপযুক্ত catch ব্লকে চলে যায় যা throw করা exception এর type এর সাথে মেলে। catch ব্লক catch কীওয়ার্ডের পরে exception ক্লাস নির্দিষ্ট করে exception এর ধরনটি নির্দিষ্ট করে। এর পরে exception টি হ্যান্ডেল করার জন্য কোড থাকে, যেমন error টি লগ করা, recovery actions সম্পাদন করা বা একটি error message প্রদর্শন করা।
  4. Multiple catch blocks: বিভিন্ন ধরণের exceptions হ্যান্ডেল করার জন্য multiple catch blocks থাকতে পারে। catch ব্লকগুলি top to bottom পর্যন্ত ক্রমানুসারে মূল্যায়ন করা হয় এবং প্রথম ম্যাচিং catch ব্লকটি এক্সেকিউট করা হয়। এটি আপনাকে তাদের টাইপ এর উপর ভিত্তি করে বিভিন্ন exceptions গুলিকে ভিন্নভাবে হ্যান্ডেল করতে দেয়।
  5. The finally block: finally ব্লকটি optional এবং catch ব্লক অনুসরণ করে। এটিতে এমন কোড থাকে যা একটি exception throw করা বা catch করা হোক বা নাহোক তা নির্বিশেষে এক্সেকিউট করা হবে। এই ব্লকটি সাধারণত ক্লিনআপ অ্যাকশন বা রিলিজ রিসোর্স সঞ্চালন করতে ব্যবহৃত হয়। একটি ম্যাচিং catch ব্লক না পাওয়া গেলেও এই ব্লকটি এক্সেকিউট করা হয়।

Zend Certified PHP Engineering (ZCPE) Course

Exception Handling with try….catch Block

এবার চলুন একটি উদাহরণ দিয়ে Exception Handling এর try এবং catch ব্লকের ব্যবহার দেখা যাক:

class Calculator
{
    public function divide($numerator, $denominator)
    {
        if ($denominator === 0) {
            throw new Exception("Division by zero is not allowed.");
        }

        return $numerator / $denominator;
    }
}

$calculator = new Calculator();

try {
    $result = $calculator->divide(10, 0);
    echo "Result: " . $result;
} catch (Exception $e) {
    echo "Caught exception: " . $e->getMessage();
}

  • এই উদাহরণে, আমাদের একটি Calculator class রয়েছে যা division অর্থাৎ ভাগের কাজ করে। divide method টি প্যারামিটার হিসাবে একটি numerator অর্থাৎ হর এবং একটি denominator অর্থাৎ লব (divisor) নেয়। যদি হরটি শূন্য হয়, যার ফলে zero দ্বারা বিভাজন হবে, এর ফলে Exception class তখন একটি exception সেই সাথে একটি descriptive error message সহ নিক্ষেপ করা হবে।
  • মূল কোডে, আমরা Calculator ক্লাসের একটি instance তৈরি করি এবং zero হর দিয়ে একটি division সম্পাদন করার চেষ্টা করি। কোডটি একটি try ব্লকে wrappe অর্থাৎ মোড়ানো হয়, যেখানে আমরা division করার চেষ্টা করি। যদি একটি exception try ব্লকের মধ্যে throw করা হয়, তবে এটি সংশ্লিষ্ট ক্যাচ catch দ্বারা ধরা হয়।
  • এই ক্ষেত্রে, zero exception দ্বারা বিভাজন (division ) ঘটলে, catch ব্লক exception টি catch করে এবং $e->getMessage() ব্যবহার করে error message প্রদর্শন করে। এটি আমাদের error situation কে সুন্দরভাবে হ্যান্ডেল করতে এবং ইউজারদেরকে meaningful feedback অর্থাৎ অর্থপূর্ণ প্রতিক্রিয়া প্রদান করতে দেয়।
  • exception handling ছাড়া, zero দ্বারা বিভাজন একটি fatal error সৃষ্টি করবে এবং স্ক্রিপ্টটি আকস্মিকভাবে বন্ধ করে দেবে। আর তাই আমরা, exception handling ব্যবহার করে এই exception টি catch পারি, এটি যথাযথভাবে হ্যান্ডেল করতে পারি এবং কোডটি এক্সেকিউশন চালিয়ে যেতে পারি।

এই উদাহরণটির মাধ্যমে আমরা বুঝতে পারলাম কিভাবে exception handling PHP কোডে exceptional পরিস্থিতি ম্যানেজিং এবং হ্যান্ডলিং করতে সাহায্য করতে পারে, errors গুলির জন্য আরও controlled এবং recoverable পদ্ধতি প্রদান করে।

PHP Exception Handling Methods

PHP Exception Handling এ নিম্নোক্ত বাই ডিফল্ট আপনি নিম্নোক্ত Method গুলো থাকায়, আপনি এগুলো অনায়াসেই ব্যবহার করতে পারেন :

1. getMessage()

এটি ব্যবহার করে Exception Object এর প্রথম প্যারামিটার হিসেবে যে Message পাঠানো হবে, সেটি এই মেথড দিয়ে আপনি উক্ত মেসেজকে রিসিভ করতে পারবেন।

<?php
try {
  throw new Exception("An error occurred");
} catch(Exception $e) {
  echo $e->getMessage();
}
?>

2. getCode()

আপনি চাইলে Exception Object এর দ্বিতীয় প্যারামিটার হিসেবে একটি Error Code পাঠাতে পারেন, আর উক্ত Error Code টি দেখানোর জন্য getCode() Method ব্যবহার করতে পারেন।

<?php
try {
  throw new Exception("An error occurred", 120);
} catch(Exception $e) {
  echo "Error code: " . $e->getCode();
}
?>

3. getFile()

আপনার Error টি সোর্স কোডের কোন file থেকে আসছে তা দেখানোর জন্য getFile() Method ব্যবহার করতে পারেন।

<?php
try {
  throw new Exception("An error occurred");
} catch(Exception $e) {
  echo "Error in this file: " . $e->getFile();
}
?>

4. getLine()

আপনার Error টি সোর্স কোডের কোন Line থেকে আসছে তা দেখানোর জন্য getLine() Method ব্যবহার করতে পারেন।

<?php
try {
  throw new Exception("An error occurred");
} catch(Exception $e) {
  echo $e->getLine();
}
?>

Zend Certified PHP Engineering (ZCPE) Course

5. getTrace()

আপনি যদি একটা error এর সব ধরণের তথ্য যেমন , কোন ফাইল, কোন লাইন এমনকি কোন ফাঙ্কশন থেকে এসেছে এইরকম সব গুলো error একসাথে Trace করতে চান , তাহলে আপনি getTrace() Method ব্যবহার করতে পারেন ।

<?php
function myFunction($num) {
  throw new Exception("An error occurred");
}

try {
  myFunction(5);
} catch (Exception $e) {
  print_r($e->getTrace());
}
?>

6. getTraceAsString()

আপনি যদি একটা error এর সব ধরণের তথ্য যেমন , কোন ফাইল, কোন লাইন এমনকি কোন ফাঙ্কশন থেকে এসেছে এইরকম সব গুলো error একসাথে একটি Array এর পরিবর্তে একটি String আকারে Trace করতে চান , তাহলে আপনি getTrace() Method ব্যবহার করতে পারেন।

<?php
function myFunction($num) {
  throw new Exception("An error occurred");
}

try {
  myFunction(5);
} catch (Exception $e) {
  print_r($e->getTraceAsString());
}
?>

7. getPrevious()

একাধিক error এর মধ্যে সর্বশেষ error কোনটি ছিল তা দেখতে চাইলে , আপনি getPrevious() Method ব্যবহার করতে পারেন।

<?php
try {
  try {
    throw new Exception("An error occurred", 1);
  } catch(Exception $e1) {
    throw new Exception("Another error occurred", 2, $e1);
  }

} catch (Exception $e2) {
  echo $previous = $e2->getPrevious();
  echo $previous->getMessage();
}
?>

__toString()

__toString() ফাংশনটি exception handling এ একটি exception object কে string হিসেবে উপস্থাপন এবং কাস্টমাইজ করতে ব্যবহার করা যেতে পারে। একটি custom exception class এর মধ্যে এই magic method টি প্রয়োগ করে, আপনি ব্যাখ্যা করতে পারেন কিভাবে exception টিকে একটি string হিসাবে উপস্থাপন করা উচিত যখন এটি converted হয় বা একটি string context হিসেবে ব্যবহার করা হয়।

PHP exception handling এ __toString() ফাংশনটি কীভাবে ব্যবহার করবেন তার একটি উদাহরণ এখানে রয়েছে:

class CustomException extends Exception
{
    public function __toString()
    {
        return "CustomException: [{$this->code}]: {$this->message}\n";
    }
}

try {
    throw new CustomException("An error occurred.", 500);
} catch (CustomException $e) {
    echo $e; // Implicitly calls __toString()
}

এই উদাহরণে, আমাদের একটি CustomException ক্লাস রয়েছে যা বিল্ট-ইন Exception ক্লাসকে এক্সটেন্ড করে। CustomException ক্লাসের মধ্যে, আমরা __toString() পদ্ধতি প্রয়োগ করি কিভাবে Exception টিকে একটি স্ট্রিং-এ রূপান্তর করা হবে তা নির্ধারণ করতে।

__toString() method এ , আমরা exception class name, error code এবং error message কে অন্তর্ভুক্ত করে একটি স্ট্রিং হিসেবে কাস্টমাইজ করি।

try ব্লকে, আমরা একটি নির্দিষ্ট error message এবং error code সহ একটি CustomException অবজেক্ট throw করি।

catch ব্লকে, যখন আমরা $e object এর echo করি, তখন পিএইচপি স্পষ্টভাবে CustomException ক্লাসের __toString() method কে কল করে। এবং এটি আমাদের exception স্ট্রিং রিপ্রেজেন্টেশন কে কাস্টমাইজ করতে দেয় যখন এটি একটি স্ট্রিং-এ রূপান্তরিত হয়।

উপরের কোডের আউটপুট হবে নিম্নরূপ:

CustomException: [500]: An error occurred.

একটি custom exception class এর মধ্যে __toString() method প্রয়োগ করে, আপনি নিয়ন্ত্রণ করতে পারেন কিভাবে exception টি একটি স্ট্রিং হিসাবে রিপ্রেজেন্ট করা হয়। এটি আপনাকে আরও অর্থপূর্ণ এবং বর্ণনামূলক ত্রুটি error messages করতে দেয় যখন exception টি একটি string context এ ব্যবহার করা হয়।

PHP Exception Handling এ ‘finally’ block কি?

PHP exception handling এ, finally ব্লক হল কোডের একটি optional ব্লক যা try এবং catch ব্লক এর ঠিক পরেই বসে। এটি একটি exception throw বা catch হোক বা না হোকে নির্বিশেষে নির্দিষ্ট কোড এক্সেকিউট করা একটি mechanism প্রদান করে।

finally ব্লকের উদ্দেশ্য হল exception handling process এর ফলাফল নির্বিশেষে নির্দিষ্ট কিছু actions বা cleanup operations এক্সেকিউট হয়েছে তা নিশ্চিত করা। এটি try ব্লক এবং কোনো সংশ্লিষ্ট catch ব্লকের পরে কার্যকর করে।

এখানে PHP-তে try-catch-finally ব্লকের সাধারণ স্ট্রাকচার রয়েছে:

try {
    // Code that may throw an exception
} catch (ExceptionType $e) {
    // Exception handling code
} finally {
    // Code that will always execute
}

finally ব্লকটি এমন পরিস্থিতিতে উপযোগী যেখানে আপনাকে রিসৌর্স গুলোকে রিলিজ করা, ডাটাবেস কানেকশন ক্লোজ করা, বা টেম্পোরারি ফাইল ক্লিন করার মতো কাজ সম্পাদন করতে হবে, কোনো exception ঘটুক বা না ঘটুক না কেন।

finally ব্লক সম্পর্কে বোঝার জন্য এখানে কিছু key পয়েন্ট রয়েছে:

  1. Execution guarantee:finally ব্লকের ভিতরের কোডটি সর্বদা এক্সেকিউট করা হয়, exception throw করা বা catch করা যাই হোক না কেন। এটি নিশ্চিত করে যে finally ব্লকে নির্দিষ্ট অপারেশন গুলি এক্সেকিউট হয়েছে, একটি গ্যারান্টি প্রদান করে যে নির্দিষ্ট ক্লিনআপ অপারেশন বা প্রয়োজনীয় টাস্কগুলির কাজ হয়েছে।
  2. Placement: সব catch ব্লকের (যদি থাকে) পরে finally ব্লক স্থাপন করা হয়। এটি শেষ catch ব্লক অনুসরণ করে এবং try-catch-finally স্ট্রাকচারের চূড়ান্ত ব্লক।
  3. Multiple catch blocks: যদি একাধিক catch ব্লক থাকে, তবে catch exception এর টাইপের উপর ভিত্তি করে তাদের মধ্যে শুধুমাত্র একটি এক্সেকিউট করা হবে। তারপর সেই catch ব্লকটি এক্সেকিউট করার পরে, finally ব্লকটি এক্সেকিউট করা হবে।
  4. Usage scenarios: finally ব্লকটি সাধারণত বিভিন্ন ধরণের রিসৌর্স রিলিজ করার জন্য ব্যবহৃত হয়, যেমন ফাইল বা ডাটাবেস কানেকশন ক্লোজ করা, সেইসাথে ক্লিনআপ অপারেশন্স সম্পাদন করার জন্য। এটি নিশ্চিত করতেও ব্যবহার করা যেতে পারে যে নির্দিষ্ট কিছু একশন্স সবসময় নেওয়া হয়, যেমন logging, transactions চূড়ান্ত করা, বা status information আপডেট করা।

Zend Certified PHP Engineering (ZCPE) Course

এবার চলুন একটি উদাহরণ দিয়ে Exception Handling এর try এবং catch ব্লকের এর সাথে finally block এর একটা ব্যবহার দেখা যাক:

<?php
function openFile($filename)
{
    $file = fopen($filename, 'r');
    
    try {
        // Code that performs operations on the file
        if ($file) {
            // Read data from the file
            $data = fread($file, filesize($filename));
            echo "File content: " . $data;

            // Perform other file operations
            // ...
        }
    } catch (Exception $e) {
        echo "Caught exception: " . $e->getMessage();
    } finally {
        // Ensure the file is always closed
        if ($file) {
            fclose($file);
        }
        echo "Finally block executed.";
    }
}

// Usage
openFile('example.txt');

  • এই উদাহরণে, আমাদের একটি openFile function রয়েছে যা একটি ফাইল ওপেন করতে এবং এটিতে কিছু অপারেশন করব। এখানে আমরা try ব্লকের মধ্যে ফাইল টি রিড করার চেষ্টা করেছি। এর জন্য আমরা প্রথমে try ব্লকের মধ্যে কোডটি ফাইল এর উপর যেকোন অপারেশন করার আগে ফাইল হ্যান্ডেল ($file) বিদ্যমান কিনা তা পরীক্ষা করি। এটি ফাইলের content পড়ার জন্য fread ফাংশন ব্যবহার করে এবং echo “File content:”. $data; দিয়ে এটি প্রদর্শন করে। এর মধ্যে কোডটি রান করা কালীন যদি কোনো exception ঘটে, তাহলে এটি সংশ্লিষ্ট catch ব্লক দ্বারা catch করা হয়, যা error message প্রদর্শন করে।
  • একটি exception throw করা বা catch যাই হোক না কেন, finally ব্লকের ভিতরে কোডটি সর্বদা execute করা হয়। এই ক্ষেত্রে, finally ব্লক নিশ্চিত করে যে ফাইলটি সর্বদা বন্ধ আছে কিনা তা পরীক্ষা করে ফাইল হ্যান্ডেল ($file) আছে কিনা এবং তারপর fclose($file) কল করে এটি বন্ধ করে।
  • finally block ব্যবহার করে আপনি cleanup actions সম্পাদন করতে বা resources গুলো release করতে পারবেন, এবং নিশ্চিত করতে পারবেন যে একটি exception ঘটুক বা না ঘটুক না কেন প্রয়োজনীয় operations গুলি এক্সেকিউট হবে। এই উদাহরণে, এমনকি যদি ফাইল অপারেশন চলাকালীন যখন একটি exception throw করা হয়, তখন finally ব্লকের কারণে ফাইলটি এখানে সঠিকভাবে বন্ধ হবে।
  • finally block ব্যবহার করে আপনি database connections গুলোকে রিলিজ, ফাইল হ্যান্ডলগুলি ক্লোজ করা, বা try ব্লকের মধ্যে ব্যবহৃত কোনও resources কে cleaning করার মতো কাজের জন্য সহায়ক হতে পারে। এছাড়াও এটি নিশ্চিত করে যে crucial cleanup এর কাজ গুলি সর্বদা এক্সেকিউট হয়, এমনকি যদি একটি exception throw হোক বা না হোক।

PHP তে Custom exception handling কি?

PHP তে Custom exception handling বলতে আপনার কোডে নির্দিষ্ট exception পরিস্থিতি পরিচালনা করতে custom exception class গুলো তৈরি এবং ব্যবহার করার অনুশীলনকে বোঝায়। শুধুমাত্র built-in exception ক্লাসের উপর নির্ভর করার পরিবর্তে, আপনি আপনার নিজস্ব exception class গুলি ডিফাইন করতে পারেন যা exceptional condition সম্পর্কে আরও নির্দিষ্ট এবং অর্থপূর্ণ তথ্য প্রদান করে।

custom exception class তৈরি করে, আপনি আপনার অ্যাপ্লিকেশনের নির্দিষ্ট চাহিদার সাথে মেলে এমন exception handling class করতে পারেন। এটি আপনাকে আরও সুক্ষ এবং বিশেষ উপায়ে বিভিন্ন ধরণের exceptions গুলিকে আলাদা করতে এবং হ্যান্ডেল করতে দেয়।

নিম্নে একটি উদাহরণ রয়েছে যা প্রদর্শন করে যে কীভাবে পিএইচপি-তে একটি custom exception ক্লাস তৈরি এবং ব্যবহার করতে হয়:

<?php
class CustomException extends Exception
{
    public function __construct($message, $code = 0, Exception $previous = null)
    {
        parent::__construct($message, $code, $previous);
    }

    public function __toString()
    {
        return __CLASS__ . ": [{$this->code}]: {$this->message}\n";
    }
}

function performOperation($value)
{
    try {
        if (!is_numeric($value)) {
            throw new CustomException("Invalid argument: Value must be numeric.");
        }

        if ($value < 0) {
            throw new CustomException("Invalid operation: Value cannot be negative.");
        }

        // Perform the operation
        $result = sqrt($value);
        echo "Result: " . $result;
    } catch (CustomException $e) {
        echo "Caught custom exception: " . $e->getMessage();
    }
}

// Usage
performOperation(-5);

  • এই উদাহরণে, আমরা একটি CustomException নামে custom exception class ডিফাইন করি যা বিল্ট-ইন Exception class কে extends করে। CustomException ক্লাস কাস্টমাইজেশনের জন্য constructor এবং __toString() method কে ওভাররাইড করি।
  • performOperation function এর মধ্যে, কিছু exceptional conditions এর সম্মুখীন হলে আমরা CustomException-এর instances throw করি। এই ক্ষেত্রে, মানটি numeric না হলে বা এটি negative হলে, আমরা নির্দিষ্ট error messages সহ একটি CustomException throw করি।
  • catch block টি তারপরে CustomException টাইপের exception catch করে এবং সেই অনুযায়ী এটি হ্যান্ডেল করে, $e->getMessage() ব্যবহার করে custom error message প্রদর্শন করে।

custom exception handling ব্যবহার করে, আপনি আপনার অ্যাপ্লিকেশনে নির্দিষ্ট error পরিস্থিতির জন্য উপযোগী exception classes তৈরি করতে পারেন। এটি আরও বর্ণনামূলক এবং নির্দিষ্ট exception messages, উন্নত error reporting, এবং exception handling কোডের আরও ভাল সংগঠন এবং management এর অনুমতি দেয়।

তবে আপনি চাইলে উপরের উদাহরণটিকে Custom Exception ব্যবহারের পরিবর্তে বিভিন্ন Built-in Exception Handler ব্যবহার করতে পারেন :

function performOperation($value)
{
    try {
        if (!is_numeric($value)) {
            throw new InvalidArgumentException("Invalid argument: Value must be numeric.");
        }

        if ($value < 0) {
            throw new RuntimeException("Invalid operation: Value cannot be negative.");
        }

        // Perform the operation
        $result = sqrt($value);
        echo "Result: " . $result;
    } catch (InvalidArgumentException | RuntimeException $e) {
        echo "Caught exception: " . $e->getMessage();
    }
}

// Usage
performOperation(9);
echo "<br>";
performOperation(-5);
echo "<br>";
performOperation("abc");

  • এই উদাহরণে, আমাদের একটি performOperation ফাংশন রয়েছে যা প্যারামিটার হিসাবে একটি মান নেয় এবং এটিতে একটি square root operation করে। যাইহোক, এখানে কিছু নির্দিষ্ট শর্ত আছে যা বিভিন্ন exceptions হতে পারে।
  • ফাংশনের ভিতরে, আমরা কোডটি আবদ্ধ করার জন্য একটি try ব্লক ব্যবহার করি যা exceptions গুলি throw করতে পারে। এই ক্ষেত্রে, মানটি numeric না হলে, একটি InvalidArgumentException throw করবে, এবং যদি মানটি negative হয়, একটি RuntimeException throw করবে।
  • catch ব্লক একাধিক exception handling syntax ব্যবহার করে (catch (InvalidArgumentException | RuntimeException $e)) একটি একক ব্লকে উভয় টাইপের exceptions ধরতে। এটি তারপর $e->getMessage() ব্যবহার করে সংশ্লিষ্ট error message প্রদর্শন করে exceptions গুলি হ্যান্ডেল করে।

একাধিক exception handling ব্যবহার করে, আমরা একটি একক catch ব্লকের মধ্যে বিভিন্ন টাইপের exception গুলি হ্যান্ডেল করতে পারি, code duplication এড়াতে এবং কোডের readability এবং maintainability উন্নতি করতে পারি।

Zend Certified PHP Engineering (ZCPE) Course

Multiple catch and Multiple throw in exception handling

আপনি চাইলে যেকোনো অপারেশন এ একাধিক throw এবং একাধিক catch ব্যবহার করতে পারেন :

function performOperation($value)
{
    try {
        if ($value < 0) {
            throw new InvalidArgumentException("Invalid argument: Value cannot be negative.");
        }

        if (!is_numeric($value)) {
            throw new RuntimeException("Invalid operation: Value must be numeric.");
        }

        // Perform the operation
        $result = sqrt($value);
        echo "Result: " . $result;
    } catch (InvalidArgumentException $e) {
        echo "Caught InvalidArgumentException: " . $e->getMessage();
    } catch (RuntimeException $e) {
        echo "Caught RuntimeException: " . $e->getMessage();
    } catch (Exception $e) {
        echo "Caught Exception: " . $e->getMessage();
    }
}

// Usage
try {
    performOperation(-5);
} catch (Exception $e) {
    echo "Caught Exception: " . $e->getMessage();
}

এই উদাহরণে, performOperation ফাংশনটি একটি মানকে প্যারামিটার হিসাবে নেয় এবং এটিতে একটি square root অপারেশন করার চেষ্টা করে। অপারেশন চলাকালীন ঘটতে পারে এমন বিভিন্ন ধরণের exceptions গুলি হ্যান্ডেল করার জন্য আমাদের একাধিক catch ব্লক রয়েছে।

  • প্রথম catch ব্লকটি InvalidArgumentException catch করে যদি মানটি negative হয় এবং একটি নির্দিষ্ট error message এর সাথে একটি exception throw করে।
  • দ্বিতীয় catch ব্লক RuntimeException catch করে যদি মানটি numeric না হয় এবং একটি নির্দিষ্ট error message সহ একটি exception throw করে।
  • তৃতীয় catch ব্লক অন্য যেকোনো ধরনের exception এর জন্য সাধারণ ফলব্যাক হিসাবে exceptions কে catch করে।

Nested Exception Handling কি?

PHP-তে Nested exception handling বলতে বোঝায় একটি exception handling ব্লকের মধ্যে অন্য আরেকটি exception handling catch এবং সেটি হ্যান্ডলিং করার অনুশীলন। এটি কোড এক্সিকিউশনের বিভিন্ন স্তরে handle exceptions গুলিকে হ্যান্ডেল করতে নেস্টেড nested try-catch blocks গুলি ব্যবহার করে।

try-catch block গুলোকে nesting করে, আপনি আরও সুক্ষ এবং specialized exception handling প্রদান করতে পারেন। অভ্যন্তরীণ try-catch ব্লকগুলি নির্দিষ্ট exceptions গুলি ধরতে পারে, সেগুলি পরিচালনা করতে পারে এবং অপশনাল্লি নতুন exceptions গুলি পুনরায় throw করতে পারে বা বাইরের catch ব্লকগুলিতে exceptions গুলি propagate করতে পারে।

Nested exception handling আপনাকে কোড এক্সিকিউশনের বিভিন্ন স্তরে exceptions গুলি পরিচালনা করতে এবং context বা exception এর ধরণের উপর ভিত্তি করে exception পরিচালনার বিভিন্ন স্তর সরবরাহ করতে দেয়। এটি exception পরিচালনার উপর ফ্লেক্সিবিলিটি এবং নিয়ন্ত্রণ প্রদান করে, আপনাকে কোড এক্সেকিউশনের বিভিন্ন স্তরে নির্দিষ্ট কাজ বা অতিরিক্ত হ্যান্ডলিং করার অনুমতি দেয়।

নিম্নে nested exception handling একটি বাস্তব উদাহরণ দেওয়া হলো:

Scenario: File Import এবং Validation System

ধরুন, আপনি এমন একটি সিস্টেম তৈরি করছেন যা external file গুলি থেকে ডেটা import করে, data validation করে এবং একটি ডাটাবেসে valid data সংরক্ষণ করে। এই ফাইলগুলি reading এবং writing এর সময় আপনি বিভিন্ন file-related exceptions গুলি হ্যান্ডেল করতে চান। এই পরিস্থিতিতে আপনি কীভাবে nested exception handling প্রয়োগ করতে পারেন তা এখানে দেখানো হলো:

<?php
class FileOperationException extends Exception {}

class ReadFileException extends FileOperationException {}
class WriteFileException extends FileOperationException {}
class DataValidationException extends Exception {}

function importAndValidateData($filename) {
    try {
        // Attempt to read the data from the file
        $data = readAndProcessFile($filename);

        try {
            // Perform data validation on the imported data
            if (!validateData($data)) {
                throw new DataValidationException('Data validation failed.');
            }

            // If validation succeeds, save data to the database
            saveToDatabase($data);
            echo 'Data imported and validated successfully.' . PHP_EOL;

        } catch (DataValidationException $e) {
            // Handle data validation exception
            echo 'Data Validation Exception: ' . $e->getMessage() . PHP_EOL;
        }

    } catch (ReadFileException $e) {
        // Handle file reading exception
        echo 'Read File Exception: ' . $e->getMessage() . PHP_EOL;
    } catch (FileOperationException $e) {
        // Handle other file operation exceptions
        echo 'File Operation Exception: ' . $e->getMessage() . PHP_EOL;
    }
}

// Function to read and process file
function readAndProcessFile($filename) {
    try {
        // Attempt to open the file for reading
        $file = fopen($filename, 'r');
        if (!$file) {
            throw new ReadFileException('Unable to open the file for reading.');
        }

        try {
            // Attempt to read from the file
            $data = fread($file, filesize($filename));
            if ($data === false) {
                throw new ReadFileException('Unable to read from the file.');
            }

            // Process the data (e.g., parse, analyze, or display)
            echo "File Data: $data" . PHP_EOL;

            return $data;

        } catch (ReadFileException $e) {
            // Handle the specific read file exception
            echo 'Read File Exception: ' . $e->getMessage() . PHP_EOL;
            return false; // or perform additional error handling as needed
        } finally {
            fclose($file);
        }

    } catch (ReadFileException $e) {
        // Handle the general read file operation exception
        echo 'Read File Operation Exception: ' . $e->getMessage() . PHP_EOL;
        return false; // or perform additional error handling as needed
    } catch (FileOperationException $e) {
        // Handle other file operation exceptions
        echo 'File Operation Exception: ' . $e->getMessage() . PHP_EOL;
        return false; // or perform additional error handling as needed
    }
}


// Function to validate data
function validateData($data) {
    // Simulate data validation
    // If validation fails, throw a DataValidationException
    if (strlen($data) < 10) {
        throw new DataValidationException('Data validation failed: Data is too short.');
    }

    // Additional validation logic can be added here

    return true; // Return true if data is valid
}


// Function to save data to the database
function saveToDatabase($data) {
    // Simulate saving data to the database
    // In a real-world scenario, you would implement database interaction here

    // For the sake of this example, we'll just print a message
    echo 'Data saved to the database: ' . $data . PHP_EOL;
}

// Example usage
$filename = 'example.txt';
importAndValidateData($filename);

এই উদাহরণে, আমরা ডাটাবেস এবং ফাইল-সম্পর্কিত exceptions গুলির জন্য nested exception handling করেছি।

এই পরিস্থিতিতে, importAndValidateData ফাংশন একটি external file থেকে ডেটা read করে, এটি validate করে এবং ডেটাবেসে সংরক্ষণ করে। nested exception handling আপনাকে এই প্রক্রিয়ার বিভিন্ন স্তরে বিভিন্ন exceptions পরিচালনা করতে দেয়:

  • ReadFileException: যদি ফাইলটি বিদ্যমান না থাকে বা read করা না যায় , তবে এটি file reading level caught এবং handle করা হয়।
  • DataValidationException: যদি ডাটা validation ব্যর্থ হয়, তাহলে সেটা ধরা হয় এবং validation level পরিচালনা করা হয়।
  • FileOperationException: অন্যান্য file operation exceptions গুলির Generic handling (reading বা validation এর জন্য নির্দিষ্ট নয়)।

এই scenario টি দেখায় কিভাবে nested exception handling একটি robust এবং controlled file import এবং validation system তৈরি করতে ব্যবহার করা যেতে পারে যা অপারেশনের বিভিন্ন পর্যায়ে বিস্তারিত error handling করে।

Zend Certified PHP Engineering (ZCPE) Course

Omitting the caught variable

PHP 8.0 বা তার পরের ভার্সন গুলোতে আপনি চাইলে একটি ভেরিয়েবলের জন্য Exception এসাইন না করে exception হ্যান্ডলিং করতে পারেন :

<?php

class SpecificException extends Exception {}

function test() {
    throw new SpecificException('Oopsie');
}

try {
    test();
} catch (SpecificException) {
    print "A SpecificException was thrown, but we don't care about the details.";
}
?>

Throw as an expression

PHP 8.0 বা তার পরের ভার্সন গুলোতে আপনি চাইলে একটি Exception কে expression হিসেবে throw করতে পারেন :

<?php

function test() {
    do_something_risky() or throw new Exception('It did not work');
}

try {
    test();
} catch (Exception $e) {
    print $e->getMessage();
}
?>

Set Your Own Exception Handling

PHP তে আপনি চাইলে set_exception_handler() function ব্যবহার করে আপনার নিজস্ব Custom Exception Handler সেট করতে পারেন। এবং একই সাথে যদি এইরকম একাধিক Exception Handler সেট করা হয়ে থাকে , তাহলে আপনি চাইলে restore_exception_handler() function ব্যবহার করে পূর্বের অবস্থায় ফিরে যেতে পারেন :

<?php
function blue_exception_handler(Exception $exception) {
  echo '<span style="color:blue">Uncaught exception: ' , $exception->getMessage(), "</span>\n";
}

function red_exception_handler(Exception $exception) {
    echo '<span style="color:red">Uncaught exception: ' , $exception->getMessage(), "</span>\n";
  }

set_exception_handler("blue_exception_handler");

set_exception_handler('red_exception_handler');

restore_exception_handler();



    throw new Exception("Some error message");

?>


আমি মাসুদ আলম, বাংলাদেশের ৩৬ তম Zend Certified Engineer । ২০০৯ সালে কম্পিউটার সাইন্স থেকে বেচেলর ডিগ্রী অর্জন করি। দীর্ঘ ১৫ বছর আমি Winux Soft, SSL Wireless, IBCS-PRIMAX, Max Group, Canadian International Development Agency (CIDA), Care Bangladesh, World Vision, Hellen Keller, Amarbebsha Ltd সহ বিভিন্ন দেশি বিদেশী কোম্পানিতে ডেটা সাইন্স, মেশিন লার্নিং, বিগ ডেটা, ওয়েব ডেভেলপমেন্ট এবং সফটওয়্যার ডেভেলপমেন্ট এর উপর বিভিন্ন লিডিং পজিশন এ চাকরি এবং প্রজেক্ট লিড করি। এছাড়াও বাংলাদেশের ১৮৫ জন জেন্ড সার্টিফাইড ইঞ্জিনিয়ার এর মধ্যে ১২০ এরও অধিক ছাত্র আমার হাতে জেন্ড সার্টিফাইড ইঞ্জিনিয়ার হয়েছেন। বর্তমানে w3programmers ট্রেনিং ইনস্টিটিউট এ PHP এর উপর Professional এবং Advance Zend Certified PHP -8.2 Engineering, Laravel Mastering Course with ReactJS, Python Beginning To Advance with Blockchain, Machine Learning and Data Science, Professional WordPress Plugin Development Beginning to Advance কোর্স করাই। আর অবসর সময়ে w3programmers.com এ ওয়েব টেকনোলজি নিয়ে লেখালেখি করি।

Leave a Reply