PHP - Error Handling

Xử lý lỗi trong PHP đề cập đến việc tạo ra một quy định trong mã PHP để xác định và khôi phục hiệu quả từ các lỗi thời gian chạy mà chương trình có thể gặp phải. Trong PHP, các lỗi được xử lý với sự trợ giúp của −

  • Hàm die()

  • Hàm Xử Lý Lỗi

The die() Function

Hàm die() là một bí danh của exit() trong PHP. Cả hai đều dẫn đến việc kết thúc kịch bản PHP hiện tại khi được gặp. Một chuỗi tùy chọn nếu được chỉ định trong dấu ngoặc đơn, sẽ được xuất ra trước khi chương trình kết thúc.

die("message");

Example

Đoạn mã sau là một ví dụ điển hình về việc sử dụng die() trong một kịch bản PHP. Nó hiển thị thông báo "File không tìm thấy" nếu PHP không tìm thấy một tệp, nếu không, nó sẽ tiếp tục mở tệp đó để xử lý sau.

<?php
   if(!file_exists("nosuchfile.txt")) {
      die("File not found");
   } else {
      $file = fopen("nosuchfile","r");
      print "Opend file sucessfully";
	  
      // Rest of the code here.
      fclose($file);
   }
?>

Nó sẽ tạo ra output

File not found

Bằng cách sử dụng kỹ thuật trên, bạn có thể dừng chương trình của mình bất cứ khi nào có lỗi xảy ra và hiển thị thông điệp có ý nghĩa hơn và thân thiện với người dùng, thay vì để PHP tạo ra thông điệp lỗi nghiêm trọng.

The Error Handler Function

Việc sử dụng die() để xử lý lỗi được coi là một thiết kế chương trình kém và không hợp lý, vì nó dẫn đến trải nghiệm không tốt cho người dùng trên trang web. PHP cung cấp một giải pháp thay thế tinh tế hơn, cho phép bạn định nghĩa một hàm tùy chỉnh và chỉ định nó để xử lý các lỗi.

Hàm set_error_handler() có các tham số sau −

set_error_handler(?callable $callback, int $error_levels = E_ALL): ?callable

Tham số đầu tiên là một hàm do người dùng định nghĩa, được gọi tự động mỗi khi gặp phải một lỗi.

Hàm callback xử lý lỗi tùy chỉnh nên có các tham số sau -

handler(
   int $errno,
   string $errstr,
   string $errfile = ?,
   int $errline = ?,
   array $errcontext = ?
): bool

Parameters

Parameter Importance Description
errno Required It specifies the error level for the user-defined error. It must be numerical value.
errstr Required It specifies the error message for the user-defined error.
errfile Optional It specifies the filename in which the error occurred.
errline Optional It specifies the line number at which the error occurred.
errcontext Optional It specifies an array containing variables and their values in use when the error occurred.

Nếu hàm callback trả về false, lỗi mặc định sẽ được gọi.

Số $errno là một số nguyên tương ứng với các mức lỗi được định nghĩa sẵn.

Sr.No Constant & Description Value
1 E_ERROR (int) Fatal run-time errors that can not be recovered from. Execution of the script is halted. 1
2 E_WARNING (int) Run-time warnings (non-fatal errors). Execution of the script is not halted. 2
3 E_PARSE (int) Compile-time parse errors. Parse errors should only be generated by the parser. 4
4 E_NOTICE (int) Run-time notices. Something that could indicate an error, but could also happen in the normal course of running a script. 8
5 E_CORE_ERROR (int) Fatal errors that occur during PHP's initial startup. This is like an E_ERROR 16
6 E_CORE_WARNING (int) Warnings (non-fatal errors) that occur during PHP's initial startup. This is like an E_WARNING , 32
7 E_COMPILE_ERROR (int) Fatal compile-time errors. This is like an E_ERROR . 64
8 E_COMPILE_WARNING (int) Compile-time warnings (non-fatal errors). This is like an E_WARNING . 128
9 E_USER_ERROR (int) User-generated error message. This is like an E_ERROR , generated in PHP code by using the PHP function trigger_error(). 256
10 E_USER_WARNING (int) User-generated warning message. This is like an E_WARNING , generated in PHP code by using the function trigger_error(). 512
11 E_USER_NOTICE (int) User-generated notice message. This is like an E_NOTICE generated in PHP code by using the function trigger_error(). 1024
12 E_STRICT (int) Enable to have PHP suggest changes to your code which will ensure the best interoperability and forward compatibility of your code. 2048
13 E_RECOVERABLE_ERROR (int) Catchable fatal error. If the error is not caught by a user defined handler, the application aborts as it was an E_ERROR . 4096
14 E_DEPRECATED (int) Run-time notices. Enable this to receive warnings about code that will not work in future versions. 8192
15 E_USER_DEPRECATED (int) User-generated warning message. This is like an E_DEPRECATED , generated in PHP code by using the function trigger_error(). 16384
16 E_ALL (int) All errors, warnings, and notices. 32767

Example

Hãy xem xét ví dụ sau −

<?php
   error_reporting(E_ERROR);

   function myerrorhandler($errno, $errstr) {
      echo "error No: $errno Error message: $errstr" . PHP_EOL;
      echo "Terminating PHP script"; 
      die();
   }

   set_error_handler("myerrorhandler");

   $f = fopen("nosuchfile.txt", "r");
   echo "file opened successfully";
   // rest of the code
   fclose($f);
?>

Nó sẽ tạo ra output

error No: 2 Error message: fopen(nosuchfile.txt): Failed to open stream: No 
such file or directory
Terminating PHP script

Lớp phân cấp lỗi của PHP bắt đầu từ giao diện throwable. Tất cả các lớp lỗi đã được định nghĩa trước trong PHP đều được kế thừa từ lớp Error.

The ArithmeticError Class

ArithmeticError class được kế thừa từ Error class . Loại lỗi này có thể xảy ra khi thực hiện một số phép toán toán học nhất định, chẳng hạn như thực hiện phép dịch bit với một số âm.

Example

Hãy xem xét ví dụ sau −

<?php
   try {
      $a = 10;
      $b = -3;
      $result = $a << $b;
   } 
   catch (ArithmeticError $e) {
      echo $e->getMessage(); 
   }
?>

Nó sẽ tạo ra output

Bit shift by negative number

Lỗi này cũng được ném ra khi việc gọi hàm intdiv() dẫn đến giá trị vượt quá giới hạn hợp pháp của số nguyên.

Example

Hãy xem xét ví dụ sau −

<?php
   try {
      $a = PHP_INT_MIN;
      $b = -1;
      $result = intdiv($a, $b);
      echo $result;
   } 
   catch (ArithmeticError $e) {
      echo $e->getMessage(); 
   } 
?>

Nó sẽ tạo ra output

Division of PHP_INT_MIN by -1 is not an integer

DivisionByZeroError

Lớp DivisionByZeroError là một lớp con của lớp ArithmeticError. Loại lỗi này xảy ra khi giá trị của mẫu số bằng không trong phép chia.

Example: Modulo by Zero

Hãy xem xét ví dụ sau:

<?php
   try {
      $a = 10;
      $b = 0;
      $result = $a%$b;
      echo $result;
   } 
   catch (DivisionByZeroError $e) {
      echo $e->getMessage(); 
   }
?>

Nó sẽ tạo ra output

Modulo by zero

Điều này cũng có thể xảy ra khi toán tử modulo (%) có 0 là toán hạng thứ hai, và hàm intdiv() có đối số thứ hai là 0.

Example: Division by Zero

Hãy xem xét ví dụ sau −

<?php
   try {
      $a = 10;
      $b = 0;
      $result = $a/$b;
      echo $result;
   } 
   catch (DivisionByZeroError $e) {
      echo $e->getMessage(); 
   }
?>

Nó sẽ tạo ra output

Division by zero 

ArgumentCountError

Bộ phân tích cú pháp PHP ném ra lỗi ArgumentCountError khi số lượng đối số được truyền vào một hàm hoặc phương thức do người dùng định nghĩa ít hơn số lượng trong định nghĩa của nó.

Example

Hãy xem xét ví dụ sau −

<?php
   function add($x, $y) {
      return $x+$y;
   }
   try {
      echo add(10);
   }
   catch (ArgumentCountError $e) {
      echo $e->getMessage();
   }
?>

Nó sẽ tạo ra output

Too few arguments to function add(), 1 passed in C:\xampp\php\test.php on line 9 and exactly 2 expected

TypeError

Lỗi này được nêu ra khi kiểu đối số thực tế và kiểu đối số chính thức không khớp, kiểu trả về không khớp với kiểu đã khai báo.

Example

Hãy xem xét ví dụ sau −

<?php
   function add(int $first, int $second) {
      echo "addition: " . $first + second;
   }

   try {
      add('first', 'second');
   } 
   catch (TypeError $e) {
      echo $e->getMessage(), "";
   }
?>

Nó sẽ tạo ra output

add(): Argument #1 ($first) must be of type int, string given, 
   called in /home/cg/root/63814/main.php on line 7

TypeError cũng được ném ra khi hàm tích hợp của PHP được truyền vào số lượng đối số không chính xác. Tuy nhiên, chỉ thị "strict_types=1" phải được đặt ở đầu.

Example

Hãy xem xét ví dụ sau −

<?php
   declare(strict_types=1);
   try {
      echo pow(100,2,3);
   }
   catch (TypeError $e) {
      echo $e->getMessage(), "";
   }
?>

Nó sẽ tạo ra output

pow() expects exactly 2 parameters, 3 given

Exceptions Handling in PHP

PHP có một mô hình ngoại lệ tương tự như các ngôn ngữ lập trình khác. Các ngoại lệ rất quan trọng và cung cấp khả năng kiểm soát tốt hơn trong việc xử lý lỗi.

Hãy giải thích từ khóa mới liên quan đến ngoại lệ.

  • Try − Một hàm sử dụng ngoại lệ nên nằm trong một khối "try". Nếu ngoại lệ không được kích hoạt, mã sẽ tiếp tục như bình thường. Tuy nhiên, nếu ngoại lệ được kích hoạt, một ngoại lệ sẽ được "ném" ra.

  • Throw − Đây là cách bạn kích hoạt một ngoại lệ. Mỗi "throw" phải có ít nhất một "catch".

  • Catch − Một khối "catch" lấy một ngoại lệ và tạo ra một đối tượng chứa thông tin về ngoại lệ đó.

Khi một ngoại lệ được ném ra, mã sau câu lệnh sẽ không được thực thi, và PHP sẽ cố gắng tìm khối catch đầu tiên phù hợp. Nếu một ngoại lệ không được bắt, một lỗi nghiêm trọng của PHP sẽ được phát sinh với thông báo "Uncaught Exception ...".

  • Một ngoại lệ có thể được ném ra và bị bắt ("catch") trong PHP. Mã có thể được bao quanh trong một khối try.

  • Mỗi khối try phải có ít nhất một khối catch tương ứng. Nhiều khối catch có thể được sử dụng để xử lý các lớp ngoại lệ khác nhau.

  • Các ngoại lệ có thể được ném (hoặc ném lại) trong một khối catch.

Example

Dưới đây là đoạn mã, hãy sao chép và dán đoạn mã này vào một tệp và xác minh kết quả.

<?php
   try {
      $error = 'Always throw this error';
      throw new Exception($error);
      
      // Code following an exception is not executed.
      echo 'Never executed';
   }catch (Exception $e) {
      echo 'Caught exception: ',  $e->getMessage(), "";
   }
   
   // Continue execution
   echo 'Hello World';
?>

Trong ví dụ trên, hàm $e->getMessage được sử dụng để lấy thông báo lỗi. Có các hàm sau có thể được sử dụng từ lớp Exception .

  • getMessage() − thông điệp của ngoại lệ

  • getCode() − mã ngoại lệ

  • getFile() − tên tệp nguồn

  • getLine() − dòng nguồn

  • getTrace() − một mảng của backtrace()

  • getTraceAsString() − chuỗi định dạng của bản theo dõi

Creating Custom Exception Handler

Bạn có thể định nghĩa trình xử lý ngoại lệ tùy chỉnh của riêng mình. Sử dụng hàm sau để đặt một hàm xử lý ngoại lệ do người dùng định nghĩa.

string set_exception_handler ( callback $exception_handler )

Ở đây exception_handler là tên của hàm sẽ được gọi khi có một ngoại lệ không được bắt. Hàm này phải được định nghĩa trước khi gọi set_exception_handler().

Example

Hãy xem xét ví dụ sau −

<?php
   function exception_handler($exception) {
      echo "Uncaught exception: " , $exception->getMessage(), "\n";
   }
	
   set_exception_handler('exception_handler');
   throw new Exception('Uncaught Exception');
   
   echo "Not Executed";
?>

Kiểm tra bộ đầy đủ các hàm xử lý lỗi tại PHP Error Handling Functions