Cập nhật:
Kể từ PHP 7.1, điều này có sẵn.
Cú pháp là:
try
{
// Some code...
}
catch(AError | BError $e)
{
// Handle exceptions
}
catch(Exception $e)
{
// Handle the general case
}
Tài liệu: https://www.php.net/manual/en/lingu.exceptions.php#example-287
RFC: https://wiki.php.net/rfc/multipl-catch
Cam kết: https://github.com/php/php-src/commit/0aed2cc2a440e7be17552cc669d71fdd24d1204a
Đối với PHP trước 7.1:
Mặc dù những câu trả lời khác nói gì, bạn có thể nắm bắt AError
và BError
trong cùng một khối (sẽ dễ dàng hơn nếu bạn là người xác định ngoại lệ). Ngay cả khi có những trường hợp ngoại lệ bạn muốn "vượt qua", bạn vẫn có thể xác định thứ bậc để phù hợp với nhu cầu của mình.
abstract class MyExceptions extends Exception {}
abstract class LetterError extends MyExceptions {}
class AError extends LetterError {}
class BError extends LetterError {}
Sau đó:
catch(LetterError $e){
//voodoo
}
Như bạn có thể thấy ở đây và ở đây , ngay cả các SPL
ngoại lệ mặc định cũng có một hệ thống phân cấp mà bạn có thể tận dụng. Ngoài ra, như đã nêu trong Hướng dẫn PHP :
Khi một ngoại lệ được đưa ra, mã theo câu lệnh sẽ không được thực thi và PHP sẽ cố gắng tìm khối bắt phù hợp đầu tiên.
Điều này có nghĩa là bạn cũng có thể có
class CError extends LetterError {}
mà bạn cần xử lý khác với AError
hoặc BError
, vì vậy câu lệnh bắt của bạn sẽ giống như thế này:
catch(CError $e){
//voodoo
}
catch(LetterError $e){
//voodoo
}
Nếu bạn gặp trường hợp có hai mươi hoặc nhiều trường hợp ngoại lệ thuộc về cùng một siêu lớp và bạn cần xử lý năm (hoặc bất kỳ nhóm lớn nào) theo cách này và phần còn lại, bạn có thể VẪN làm điều này.
interface Group1 {}
class AError extends LetterError implements Group1 {}
class BError extends LetterError implements Group1 {}
Và sau đó:
catch (Group1 $e) {}
Sử dụng OOP khi có ngoại lệ là rất mạnh mẽ. Sử dụng những thứ như get_class
hoặc instanceof
là hack, và nên tránh nếu có thể.
Một giải pháp khác tôi muốn thêm là đưa chức năng xử lý ngoại lệ vào phương thức riêng của mình.
Bạn có thể có
function handleExceptionMethod1(Exception $e)
{
//voodoo
}
function handleExceptionMethod2(Exception $e)
{
//voodoo
}
Giả sử có hoàn toàn không có cách nào bạn có thể kiểm soát phân cấp lớp ngoại lệ hoặc giao diện (và hầu như lúc nào cũng sẽ là một chiều), bạn có thể làm những điều sau đây:
try
{
stuff()
}
catch(ExceptionA $e)
{
$this->handleExceptionMethod1($e);
}
catch(ExceptionB $e)
{
$this->handleExceptionMethod1($e);
}
catch(ExceptionC $e)
{
$this->handleExceptionMethod1($e);
}
catch(Exception $e)
{
$this->handleExceptionMethod2($e);
}
Theo cách này, bạn vẫn chỉ có một vị trí mã duy nhất bạn phải sửa đổi nếu cơ chế xử lý ngoại lệ của bạn cần thay đổi và bạn đang làm việc trong các cấu trúc chung của OOP.