2009-07-31 20 views
15

Mọi người ở đây nên biết 'hoặc' statemens, thường dán mắt vào một die() lệnh:PHP: 'hoặc' tuyên bố về hướng dẫn thất bại: làm thế nào để ném một ngoại lệ mới?

$foo = bar() or die('Error: bar function return false.'); 

Các hầu hết các lần chúng ta thấy một cái gì đó như:

mysql_query('SELECT ...') or die('Error in during the query'); 

Tuy nhiên, tôi không thể hiểu chính xác câu lệnh 'hoặc' đó hoạt động như thế nào.

Tôi muốn ném một ngoại lệ mới thay vì chết(), nhưng:

try{ 
    $foo = bar() or throw new Exception('We have a problem here'); 

doesnt làm việc, và không phải

$foo = bar() or function(){ throw new Exception('We have a problem here'); } 

Cách duy nhất tôi tìm thấy để làm điều đó là khủng khiếp này nghĩ:

function ThrowMe($mess, $code){ 
    throw new Exception($mess, $code); 
} 
try{ 
    $foo = bar() or ThrowMe('We have a problem in here', 666); 
}catch(Exception $e){ 
    echo $e->getMessage(); 
} 

Nhưng có cách nào để ném ngoại lệ mới trực tiếp sau câu lệnh 'hoặc'?

Hoặc loại cấu trúc này là bắt buộc (tôi không liek chức năng ThrowMe tại tất cả):

try{ 
    $foo = bar(); 
    if(!$foo){ 
     throw new Exception('We have a problem in here'); 
    } 
}catch(Exception $e){ 
    echo $e->getMessage(); 
} 

Sửa: những gì tôi muốn thực sự là để tránh việc sử dụng một if() kiểm tra tất cả các tiềm năng hoạt động nguy hiểm tôi làm, ví dụ:

#The echo $e->getMessage(); is just an example, in real life this have no sense! 
try{ 
    $foo = bar(); 
    if(!$foo){ 
     throw new Exception('Problems with bar()'); 
    } 
    $aa = bb($foo); 
    if(!$aa){ 
     throw new Exception('Problems with bb()'); 
    } 
    //...and so on! 
}catch(Exception $e){ 
    echo $e->getMessage(); 
} 

#But i relly prefer to use something like: 

try{ 
    $foo = bar() or throw new Exception('Problems with bar()'); 
    $aa = bb($foo) or throw new Exception('Problems with bb()'); 
    //...and so on! 
}catch(Exception $e){ 
    echo $e->getMessage(); 
} 

#Actually, the only way i figured out is: 

try{ 
    $foo = bar() or throw new ThrowMe('Problems with bar()', 1); 
    $aa = bb($foo) or throw new ThrowMe('Problems with bb()', 2); 
    //...and so on! 
}catch(Exception $e){ 
    echo $e->getMessage(); 
} 

#But i'll love to thro the exception directly instead of trick it with ThrowMe function. 
+0

Ý của bạn là '! $ Foo' trong khối mã cuối cùng? –

+0

Xin lỗi, có .. xấu của tôi – Strae

Trả lời

27

or chỉ là một logical operator, và nó tương tự như ||.

Bí quyết chung của

mysql_query() or die(); 

chỉ cũng có thể được viết

mysql_query() || die(); 

gì xảy ra ở đây là "logic hoặc" điều hành (tùy bạn chọn) đang cố gắng để xác định nếu một trong hai toán hạng đánh giá thành TRUE. Điều này có nghĩa là toán hạng phải là các biểu thức có thể được tạo thành boolean.

Vì vậy, lý do

bar() or throw new Exception(); 

là bất hợp pháp, là vì

(boolean)throw new Exception(); 

cũng là bất hợp pháp. Về bản chất, quá trình ném một ngoại lệ không tạo ra giá trị trả về cho toán tử để kiểm tra.

Nhưng gọi một hàm không tạo ra một giá trị trả về cho các nhà điều hành để kiểm tra (không có giá trị lợi nhuận rõ ràng sẽ dẫn đến int chức năng trở NULL mà phôi như FALSE) đó là lý do tại sao nó hoạt động cho bạn khi bạn quấn ngoại lệ ném trong một hàm.

Hy vọng điều đó sẽ hữu ích.

+0

Chắc chắn nó giúp tôi - giải thích lý do tại sao mà không làm việc;) – Strae

+1

'hoặc' là không tương tự như' || '. Cái cũ có ưu tiên thấp hơn so với gán và so sánh. Sau này có cao hơn. Đây là một sự khác biệt rất quan trọng bởi vì '$ f = một() hoặc hai()' hoạt động rất khác với '$ f = một() || hai() '. http://us3.php.net/manual/en/language.operators.precedence.php –

+1

Vâng. "Tương tự" không có nghĩa là "giống hệt". Điều đó đang được nói, làm rõ của bạn được chào đón: D –

1

tôi nghĩ rằng bạn muốn sử dụng một cái gì đó giống như cấu trúc cuối cùng, mặc dù có thực sự không có điểm trong việc sử dụng ngoại lệ cho rằng:

$foo = bar(); 
if(!$foo){ 
    echo 'We have a problem in here'; 
} 

Mỗi nhận xét - Tôi không nghĩ rằng bạn có thể làm điều đó trong một dòng (tức là mà không có kiểm tra if(!$foo)), và tôi đồng ý rằng phương pháp ném ngoại lệ là khá khủng khiếp. Cá nhân, tôi thích sự giải thích của:

$foo = bar(); 
if(!$foo){ 
    throw new Exception('We have a problem in here'); 
} 

nhưng đó là sở thích cá nhân. Nếu bạn muốn điều duy nhất, tôi nghĩ bạn sẽ phải đi với tùy chọn chức năng ném ngoại lệ của bạn.

Tôi đoán giới hạn này có thể là do công cụ gõ động của PHP, nó có thể truyền kết quả của cuộc gọi hàm tới điều kiện, chứ không phải kết quả của throw.

+0

Không, tôi không muốn. Tiếng vang chỉ là ví dụ, trong cuộc sống thực không bao giờ lặp lại thông báo lỗi hoặc mã nhưng xử lý chúng một cách khác nhau. Điều tôi muốn chính xác là tránh kiểm tra if (! $ Foo) mỗi lần. – Strae

+0

OK, tôi đã cập nhật câu trả lời của mình. –

2

Tại sao không bar()bb() ném ngoại lệ? Trong trường hợp ngoại lệ PHP bong bóng lên, vì vậy không cần phải ném ngoại lệ trong hàm/phương thức mà bạn gọi bar()/bb(). Các ngoại lệ này có thể được ném bởi bar()/bb(). Trong trường hợp bạn muốn ném ngoại lệ khác, bạn chỉ có thể làm:

function foo() { 
    try { 
     $bar = bar(); 
    } catch (BarException) { 
     throw new FooException; 
    } 
} 
+0

Có người đàn ông, bạn đúng, nhưng những gì về, ví dụ, các chức năng cơ sở dữ liệu? mysql_query()/pg_query()? Đối với những tôi phải sử dụng hoặc if() kiểm tra, hoặc các chức năng khủng khiếp ThrowMe .. tôi chỉ muốn biết nếu có thể làm direclty id mà không ThrowMe() – Strae

+1

@DaNieL: Bạn có thể sử dụng PDO cho DB truy cập mà có thể ném ngoại lệ chính nó . –

+1

Vâng, điều đó là không thể. Tôi đã thử nó một thời gian trước đây và không có cơ hội. PHP là một công cụ hữu ích, nhưng nó cũng có một trong những trình phân tích cú pháp và trình thông dịch ngu ngốc nhất trên thế giới. –

1

Dưới đây là một giải pháp đơn dòng không có chức năng bổ sung:

if (!($foo = bar())) throw new Exception('We have a problem here'); 
0

Bạn cũng có thể tạo ra một lớp ngoại lệ tùy chỉnh và sử dụng nó là phương pháp constructor tĩnh thay vì throw new Exception() xây dựng. lớp

Ngoại lệ:

class CustomException extends Exception { 
    static public function doThrow($message = "", $code = 0, Exception $previous = null) { 
    throw new Exception($message, $code, $previous); 
    } 
} 

Cách sử dụng:

try { 

    $foo = bar() or CustomException::doThrow('Problems with bar()'); 
    $aa = bb($foo) or CustomException::doThrow('Problems with bb()'); 

} catch(Exception $e){ 
    echo $e->getMessage(); 
} 

Note

If you are using PHP 7 and higher - you can rename static method doThrow() to simply throw() , since in PHP 7 and higher it's allowed to use reserved keywords as method names.

1

Một giải pháp tôi thấy rằng có thể thay thế "or die()" ở khắp mọi nơi là để quấn ném với một chức năng vô danh mà được gọi ngay lập tức bằng call_user_func:

call_user_func(function(){ 
    throw new Exception("ERROR"); 
}); 

Bạn có thể thấy rằng nó hoạt động bằng cách thực hiện điều này trên một kịch bản giả:

false or call_user_func(function(){throw new Exception("ERROR");}); 
Các vấn đề liên quan