PHP: ngoại lệ và lỗi?


116

Có thể tôi đang thiếu nó ở đâu đó trong hướng dẫn sử dụng PHP, nhưng chính xác thì sự khác biệt giữa lỗi và ngoại lệ là gì? Sự khác biệt duy nhất mà tôi có thể thấy là lỗi và ngoại lệ được xử lý khác nhau. Nhưng điều gì gây ra ngoại lệ và điều gì gây ra lỗi?

Câu trả lời:


87

Các trường hợp ngoại lệ được ném ra - chúng nhằm mục đích bị bắt. Các lỗi thường không thể sửa chữa được. Ví dụ: bạn có một khối mã sẽ chèn một hàng vào cơ sở dữ liệu. Có thể cuộc gọi này không thành công (ID trùng lặp) - bạn sẽ muốn có "Lỗi" mà trong trường hợp này là "Ngoại lệ". Khi bạn đang chèn những hàng này, bạn có thể làm như thế này

try {
  $row->insert();
  $inserted = true;
} catch (Exception $e) {
  echo "There was an error inserting the row - ".$e->getMessage();
  $inserted = false;
}

echo "Some more stuff";

Việc thực thi chương trình sẽ tiếp tục - bởi vì bạn đã 'bắt gặp' ngoại lệ. Một ngoại lệ sẽ được coi là một lỗi trừ khi nó bị bắt. Nó sẽ cho phép bạn tiếp tục thực thi chương trình sau khi nó bị lỗi.


29
Errors are generally unrecoverable<- thực ra, điều này không thực sự đúng. E_ERRORE_PARSElà hai lỗi không thể khôi phục phổ biến nhất (có một vài lỗi khác) nhưng phần lớn các lỗi bạn sẽ thấy trong nhà phát triển là có thể khôi phục được ( E_NOTICE, E_WARNINGet al). Thật không may, việc xử lý lỗi của PHP là một mớ hỗn độn - tất cả mọi thứ đều kích hoạt lỗi một cách không cần thiết (ví dụ như phần lớn các chức năng của hệ thống tệp). Trong trường hợp ngoại lệ chung là "cách OOP", nhưng tiếc là một số các API OOP mẹ đẻ của PHP sử dụng lỗi thay vì ngoại lệ :-(
DaveRandom

1
@DaveRandom E_NOTICE, E_WARNING không phải là "lỗi" theo định nghĩa phải không? Tôi luôn nghĩ chúng là 'thông báo' mà PHP hiển thị để thông báo cho lập trình viên rằng có thể có điều gì đó không ổn với đoạn mã mà anh ấy đã viết.
slhsen

2
@slhsen vấn đề thực sự là thuật ngữ khó hiểu, tất cả các dạng thông báo này đều đi qua "hệ thống xử lý lỗi" trong PHP, về mặt ngữ nghĩa tất cả các sự kiện này đều là "lỗi", mặc dù thông báo / cảnh báo về mặt ngữ nghĩa chắc chắn không giống như " lỗi ”trong ngữ cảnh đó. Rất may, PHP7 sắp tới ít nhất đã mở đường để phân loại mớ hỗn độn này bằng cách biến hầu hết những thứ này thành các ngoại lệ có thể bắt được (bằng Throwablegiao diện mới ), mang lại một cách tuyệt đối và rõ ràng hơn nhiều để phân biệt và xử lý đúng cả thực tế. vấn đề và tư vấn thông điệp
DaveRandom

"Chương trình sẽ tiếp tục thực hiện" có thay đổi không? Kể từ PHP nói "Khi một ngoại lệ được ném ra, đoạn mã sau tuyên bố sẽ không được thực hiện" ( php.net/manual/en/language.exceptions.php )
Robert Sinclair

1
Tôi nghĩ ý của OP là về sự khác biệt giữa con cháu của ErrorVS con cháu của Exception.
XedinUnknown

55

Tôi thường set_error_handlersử dụng một hàm nhận lỗi và ném một ngoại lệ để bất cứ điều gì xảy ra tôi sẽ chỉ có ngoại lệ để giải quyết. Không còn @file_get_contentschỉ thử / bắt đẹp và gọn gàng.

Trong các tình huống gỡ lỗi, tôi cũng có một trình xử lý ngoại lệ xuất ra một trang giống như asp.net. Tôi đang đăng bài này trên đường nhưng nếu được yêu cầu, tôi sẽ đăng nguồn ví dụ sau.

biên tập:

Ngoài ra như đã hứa, tôi đã cắt và dán một số đoạn mã của mình lại với nhau để làm mẫu. Tôi đã lưu thông tin bên dưới vào tệp trên máy trạm của mình, bạn KHÔNG CÒN CÓ THỂ xem kết quả ở đây (vì liên kết bị hỏng).

<?php

define( 'DEBUG', true );

class ErrorOrWarningException extends Exception
{
    protected $_Context = null;
    public function getContext()
    {
        return $this->_Context;
    }
    public function setContext( $value )
    {
        $this->_Context = $value;
    }

    public function __construct( $code, $message, $file, $line, $context )
    {
        parent::__construct( $message, $code );

        $this->file = $file;
        $this->line = $line;
        $this->setContext( $context );
    }
}

/**
 * Inspire to write perfect code. everything is an exception, even minor warnings.
 **/
function error_to_exception( $code, $message, $file, $line, $context )
{
    throw new ErrorOrWarningException( $code, $message, $file, $line, $context );
}
set_error_handler( 'error_to_exception' );

function global_exception_handler( $ex )
{
    ob_start();
    dump_exception( $ex );
    $dump = ob_get_clean();
    // send email of dump to administrator?...

    // if we are in debug mode we are allowed to dump exceptions to the browser.
    if ( defined( 'DEBUG' ) && DEBUG == true )
    {
        echo $dump;
    }
    else // if we are in production we give our visitor a nice message without all the details.
    {
        echo file_get_contents( 'static/errors/fatalexception.html' );
    }
    exit;
}

function dump_exception( Exception $ex )
{
    $file = $ex->getFile();
    $line = $ex->getLine();

    if ( file_exists( $file ) )
    {
        $lines = file( $file );
    }

?><html>
    <head>
        <title><?= $ex->getMessage(); ?></title>
        <style type="text/css">
            body {
                width : 800px;
                margin : auto;
            }

            ul.code {
                border : inset 1px;
            }
            ul.code li {
                white-space: pre ;
                list-style-type : none;
                font-family : monospace;
            }
            ul.code li.line {
                color : red;
            }

            table.trace {
                width : 100%;
                border-collapse : collapse;
                border : solid 1px black;
            }
            table.thead tr {
                background : rgb(240,240,240);
            }
            table.trace tr.odd {
                background : white;
            }
            table.trace tr.even {
                background : rgb(250,250,250);
            }
            table.trace td {
                padding : 2px 4px 2px 4px;
            }
        </style>
    </head>
    <body>
        <h1>Uncaught <?= get_class( $ex ); ?></h1>
        <h2><?= $ex->getMessage(); ?></h2>
        <p>
            An uncaught <?= get_class( $ex ); ?> was thrown on line <?= $line; ?> of file <?= basename( $file ); ?> that prevented further execution of this request.
        </p>
        <h2>Where it happened:</h2>
        <? if ( isset($lines) ) : ?>
        <code><?= $file; ?></code>
        <ul class="code">
            <? for( $i = $line - 3; $i < $line + 3; $i ++ ) : ?>
                <? if ( $i > 0 && $i < count( $lines ) ) : ?>
                    <? if ( $i == $line-1 ) : ?>
                        <li class="line"><?= str_replace( "\n", "", $lines[$i] ); ?></li>
                    <? else : ?>
                        <li><?= str_replace( "\n", "", $lines[$i] ); ?></li>
                    <? endif; ?>
                <? endif; ?>
            <? endfor; ?>
        </ul>
        <? endif; ?>

        <? if ( is_array( $ex->getTrace() ) ) : ?>
        <h2>Stack trace:</h2>
            <table class="trace">
                <thead>
                    <tr>
                        <td>File</td>
                        <td>Line</td>
                        <td>Class</td>
                        <td>Function</td>
                        <td>Arguments</td>
                    </tr>
                </thead>
                <tbody>
                <? foreach ( $ex->getTrace() as $i => $trace ) : ?>
                    <tr class="<?= $i % 2 == 0 ? 'even' : 'odd'; ?>">
                        <td><?= isset($trace[ 'file' ]) ? basename($trace[ 'file' ]) : ''; ?></td>
                        <td><?= isset($trace[ 'line' ]) ? $trace[ 'line' ] : ''; ?></td>
                        <td><?= isset($trace[ 'class' ]) ? $trace[ 'class' ] : ''; ?></td>
                        <td><?= isset($trace[ 'function' ]) ? $trace[ 'function' ] : ''; ?></td>
                        <td>
                            <? if( isset($trace[ 'args' ]) ) : ?>
                                <? foreach ( $trace[ 'args' ] as $i => $arg ) : ?>
                                    <span title="<?= var_export( $arg, true ); ?>"><?= gettype( $arg ); ?></span>
                                    <?= $i < count( $trace['args'] ) -1 ? ',' : ''; ?> 
                                <? endforeach; ?>
                            <? else : ?>
                            NULL
                            <? endif; ?>
                        </td>
                    </tr>
                <? endforeach;?>
                </tbody>
            </table>
        <? else : ?>
            <pre><?= $ex->getTraceAsString(); ?></pre>
        <? endif; ?>
    </body>
</html><? // back in php
}
set_exception_handler( 'global_exception_handler' );

class X
{
    function __construct()
    {
        trigger_error( 'Whoops!', E_USER_NOTICE );      
    }
}

$x = new X();

throw new Exception( 'Execution will never get here' );

?>

Điều đó sẽ hữu ích. Bất cứ điều gì để giảm bớt thời gian tôi phải đối phó với PHP sẽ hữu ích. :-)
Jason Baker

Mã đẹp, cảm ơn. Mặc dù vậy, tôi không hiểu lớp X đến từ đâu và mục đích của nó là gì?
Alec

mọi thứ bên dưới "set_exception_handler ('global_exception_handler');" chỉ là bản demo, bạn sẽ không cần nó, nó chỉ để hiển thị những gì sẽ xảy ra trong một tình huống lỗi thông thường không ngoại lệ.
Kris

PHP tiêu chuẩn định nghĩa ErrorException cụ thể để được ném ra từ một trình xử lý lỗi chung. Bạn có cho phép tôi chỉnh sửa và cập nhật bài đăng của bạn không?
Tiberiu-Ionuț Stan

@ Tiberiu-IonuțStan: chắc chắn, nhưng ví dụ làm việc sẽ không đồng bộ. Ngoài ra, ngày nay tôi có thể hướng mọi người đến github.com/theredhead/red.web/blob/master/src/lib/bootstrap.php từ private-void.com thay thế.
Kris

21

Câu trả lời xứng đáng nói về con voi trong phòng

Lỗi là cách cũ để xử lý tình trạng lỗi trong thời gian chạy. Thông thường, mã sẽ thực hiện một cuộc gọi đến một cái gì đó giống như set_error_handlertrước khi thực thi một số mã. Theo truyền thống của hợp ngữ ngắt. Đây là cách một số mã CƠ BẢN sẽ trông như thế nào.

on error :divide_error

print 1/0
print "this won't print"

:divide_error

if errcode = X
   print "divide by zero error"

Thật khó để đảm bảo rằng nó set_error_handlersẽ được gọi với giá trị phù hợp. Và thậm chí tệ hơn, một cuộc gọi có thể được thực hiện đến một thủ tục riêng biệt sẽ thay đổi trình xử lý lỗi. Cộng với nhiều lần các cuộc gọi được xen kẽ với set_error_handlercác cuộc gọi và xử lý. Rất dễ để mã nhanh chóng vượt khỏi tầm kiểm soát. Xử lý ngoại lệ đã được giải cứu bằng cách chính thức hóa cú pháp và ngữ nghĩa của những gì mã tốt đang thực sự làm.

try {
   print 1/0;
   print "this won't print";
} catch (DivideByZeroException $e) {
   print "divide by zero error";
}

Không có chức năng riêng biệt hoặc có nguy cơ gọi sai trình xử lý lỗi. Mã bây giờ được đảm bảo ở cùng một nơi. Thêm vào đó, chúng tôi nhận được thông báo lỗi tốt hơn.

PHP trước đây chỉ có khả năng xử lý lỗi, khi nhiều ngôn ngữ khác đã phát triển thành mô hình xử lý ngoại lệ thích hợp hơn. Cuối cùng, các nhà sản xuất PHP đã thực hiện xử lý ngoại lệ. Nhưng có khả năng hỗ trợ mã cũ, họ tiếp tục xử lý lỗi và cung cấp cách xử lý lỗi giống như xử lý ngoại lệ. Ngoại trừ điều đó, không có gì đảm bảo rằng một số mã có thể không đặt lại trình xử lý lỗi, chính xác là cách xử lý ngoại lệ nhằm cung cấp.

Câu trả lời cuối cùng

Các lỗi đã được mã hóa trước khi thực hiện xử lý ngoại lệ, vẫn có thể là lỗi. Các lỗi mới có thể là ngoại lệ. Nhưng không có thiết kế hay logic nào là lỗi và đâu là ngoại lệ. Nó chỉ dựa trên những gì có sẵn tại thời điểm nó được mã hóa và sở thích của lập trình viên mã hóa nó.


3
Đây là lý do thực sự tại sao các ngoại lệ và lỗi cùng tồn tại. Nếu được thiết kế từ đầu, php chỉ nên bao gồm cái này hoặc cái kia.
Tomas Zubiri

1
Đó là câu trả lời tốt nhất theo ý kiến ​​của tôi, vì nó là chi tiết và giải thích nhất.
Robert Kusznier

8

Một điều cần thêm ở đây là về việc xử lý các ngoại lệ và lỗi. Đối với mục đích của nhà phát triển ứng dụng, cả lỗi và ngoại lệ đều là "những điều tồi tệ" mà bạn muốn ghi lại để tìm hiểu về các vấn đề mà ứng dụng của bạn gặp phải - để khách hàng của bạn có trải nghiệm tốt hơn về lâu dài.

Vì vậy, sẽ hợp lý khi viết một trình xử lý lỗi thực hiện điều tương tự như những gì bạn làm cho các trường hợp ngoại lệ.


Cảm ơn bạn đã cung cấp liên kết!
Mike Moore

@Alex Weinstein: liên kết bị hỏng
Marco Demaio 29/12/12

7

Như đã nêu trong các câu trả lời khác, đặt trình xử lý lỗi thành trình ném ngoại lệ là cách tốt nhất để xử lý lỗi trong PHP. Tôi sử dụng thiết lập đơn giản hơn một chút:

set_error_handler(function ($errno, $errstr, $errfile, $errline ) {
        if (error_reporting()) {
                throw new \ErrorException($errstr, 0, $errno, $errfile, $errline);
        }
});

Hãy lưu ý error_reporting()kiểm tra để giữ@ nhà điều hành hoạt động. Ngoài ra, không cần phải xác định ngoại lệ tùy chỉnh, PHP có một lớp tốt cho điều đó.

Lợi ích tuyệt vời của việc ném các ngoại lệ là ngoại lệ có dấu vết ngăn xếp được liên kết với chúng, vì vậy dễ dàng tìm ra vấn đề ở đâu.


5

Re: "nhưng chính xác thì sự khác biệt giữa lỗi và ngoại lệ là gì?"

Có rất nhiều câu trả lời hay về sự khác biệt ở đây. Tôi sẽ chỉ thêm vào một cái gì đó vẫn chưa được nói đến - hiệu suất. Cụ thể, đây là sự khác biệt giữa ném / xử lý ngoại lệ và xử lý mã trả về (thành công hoặc một số lỗi). Thông thường, trong php, điều này có nghĩa là trả về falsehoặc null, nhưng chúng có thể chi tiết hơn, chẳng hạn như khi tải tệp lên: http://php.net/manual/en/features.file-upload.errors.php Bạn thậm chí có thể trả về một đối tượng Exception !

Tôi đã thực hiện một vài lần chạy hiệu suất bằng các ngôn ngữ / hệ thống khác nhau. Nói chung, xử lý ngoại lệ chậm hơn khoảng 10.000 lần so với việc kiểm tra mã trả về lỗi.

Vì vậy, nếu nó hoàn toàn, tích cực cần phải hoàn thành việc thực thi trước khi nó bắt đầu - tốt, bạn không gặp may vì du hành thời gian không tồn tại. Không mất thời gian, mã trả lại là lựa chọn nhanh nhất hiện có.

Biên tập:

PHP được tối ưu hóa cao để xử lý ngoại lệ. Các thử nghiệm trong thế giới thực cho thấy rằng việc ném một ngoại lệ chỉ chậm hơn 2-10 lần so với việc trả về một giá trị.


3
Chắc chắn, nhưng số lượng chu kỳ bị mất khi ném Ngoại lệ nhiều hơn được bù đắp bởi sức mạnh mô tả bổ sung mà bạn nhận được với Ngoại lệ. Bạn có thể ném các loại ngoại lệ cụ thể, thậm chí thêm dữ liệu vào ngoại lệ để chứa mã lỗi. Tôi thực sự nghi ngờ yêu cầu 10.000 * của bạn. Ngay cả khi bạn nói đúng về sự khác biệt thời gian, thời gian dành cho việc quay lại & nếu so với Thực hiện mới, ném, bắt trong bất kỳ tình huống nào của thế giới thực có thể rất nhỏ so với mã đã thực thi nên đây chắc chắn là một sự tối ưu hóa quá sớm. Hãy ném các trường hợp ngoại lệ, chúng dễ xử lý hơn trong 90% thời gian.
gnarf

1
1. 10.000x là chính xác - với một số phương sai dựa trên tùy chọn ngôn ngữ và trình biên dịch. 2. Bạn không cần phải trả về null / false. Bạn có thể trả lại một số - tối đa MAX_ULONG mã trả lại ngay tại đó. Ngoài ra, bạn có thể trả về một chuỗi không thành công và chỉ cần kiểm tra một chuỗi thành công hoặc int hoặc null. 3. Trong các tình huống thế giới thực, mọi chu kỳ đồng hồ đều được tính. Facebook có 552 triệu người dùng hoạt động hàng ngày. Giả sử các trường hợp ngoại lệ chỉ là 2 lần và việc kiểm tra người dùng / thẻ mất 0,001 giây, nghĩa là tiết kiệm 153 giờ thời gian xử lý mỗi ngày. Ở mức 10.000x, nó tiết kiệm được 175 năm. Chỉ để kiểm tra các lần đăng nhập - mỗi ngày.
evan

@evan: FYI, ở đây họ đã thử nghiệm mã với các ngoại lệ và nó không có vẻ chậm hơn: stackoverflow.com/a/445094/260080
Marco Demaio 29/12/12

@MarcoDemaio Câu hỏi đó chỉ bao gồm khối try / catch mà không đưa ra ngoại lệ. Một thử nghiệm tốt hơn sẽ là trả về một giá trị trong noexcept () và đưa ra một ngoại lệ trong exception (). Ngoài ra, nó sẽ bong bóng thông qua nhiều chức năng. stackoverflow.com/a/104375/505172 nói rằng sự khác biệt trong PHP thực sự là 54x. Tôi đã chạy thử nghiệm của riêng mình theo thời gian thực và nó có vẻ chậm hơn 2-10 lần. Điều này là tất cả các cách tốt hơn mong đợi.
evan

@evan: Tôi sẽ không lo lắng khi đó, tôi chỉ sử dụng các ngoại lệ để theo dõi các lỗi không mong muốn / không thể khôi phục nên ngay cả khi nó có chậm hơn 100 lần tôi cũng không quan tâm. Những lo lắng của tôi là làm cho mã chậm hơn bằng cách thêm các khối try / catch.
Marco Demaio

4

Tôi nghĩ nhà cảm xạ mà bạn đang tìm kiếm chính là;

Lỗi là những thứ tiêu chuẩn mà bạn đã từng làm, như lặp lại một biến $ không tồn tại.
Ngoại lệ chỉ có từ PHP 5 trở đi và đến khi xử lý các đối tượng.

Để giữ cho nó đơn giản:

Ngoại lệ là những lỗi bạn mắc phải khi xử lý các đối tượng. Tuy nhiên, câu lệnh try / catch cho phép bạn làm điều gì đó với chúng và được sử dụng giống như câu lệnh if / else. Cố gắng làm điều này, nếu vấn đề, không thành vấn đề, hãy làm điều này.

Nếu bạn không "bắt" một ngoại lệ, thì nó sẽ chuyển thành lỗi chuẩn.

Lỗi là các lỗi php fundemental thường làm ngưng tập lệnh của bạn.

Try / catch thường được sử dụng để thiết lập các kết nối cơ sở dữ liệu như PDO, điều này rất tốt nếu bạn muốn chuyển hướng tập lệnh hoặc làm điều gì đó khác nếu kết nối không hoạt động. Nhưng nếu bạn chỉ muốn hiển thị thông báo lỗi và dừng tập lệnh thì bạn không cần nó, ngoại lệ không cần thiết sẽ biến thành lỗi nghiêm trọng. Hoặc bạn cũng có thể sử dụng cài đặt xử lý lỗi trên toàn trang web.

Hy vọng rằng sẽ giúp


3
Các ngoại lệ cũng có thể được sử dụng với mã thủ tục trong PHP.
Tiberiu-Ionuț Stan

2

Trong PHP 7.1 trở lên, một khối catch có thể chỉ định nhiều ngoại lệ bằng cách sử dụng ký tự pipe (|). Điều này rất hữu ích khi các ngoại lệ khác nhau từ các cấu trúc phân cấp lớp khác nhau được xử lý giống nhau.

try {
  // do something
} catch (Error | Exception $e) {
  echo $e->getMessage();
}

1

Các trường hợp ngoại lệ được ném có chủ đích bởi mã sử dụng một cú ném, lỗi ... không nhiều lắm.

Lỗi xảy ra do một cái gì đó thường không được xử lý. (Lỗi IO, lỗi TCP / IP, lỗi tham chiếu rỗng)


1
Điều này không thực sự đúng. Trong nhiều trường hợp, lỗi được kiểm tra và mã trả lại được cố tình gửi lại nếu thích hợp. Trên thực tế, đó là trường hợp của mọi ngôn ngữ không hướng đối tượng. Ngoại lệ chỉ là ngoại lệ đối với quy tắc. Trong cả hai trường hợp, có sự cố xảy ra, được nhận thấy và cần được xử lý. Tải lên tệp PHP là một ví dụ về xử lý lỗi cố ý thông qua mã trả lại - php.net/manual/en/features.file-upload.errors.php
evan

1

Tôi định cung cấp cho bạn một cuộc thảo luận bất thường nhất về kiểm soát lỗi.

Tôi đã xây dựng một trình xử lý lỗi rất tốt cho một ngôn ngữ cách đây nhiều năm và mặc dù một số tên đã thay đổi, nhưng nguyên tắc xử lý lỗi vẫn như ngày nay. Tôi đã có một hệ điều hành đa tác vụ được xây dựng tùy chỉnh và phải có khả năng khôi phục khỏi lỗi dữ liệu ở mọi cấp độ mà không bị rò rỉ bộ nhớ, tăng trưởng ngăn xếp hoặc sự cố. Vì vậy, những gì sau đây là hiểu biết của tôi về cách các lỗi và ngoại lệ phải hoạt động và chúng khác nhau như thế nào. Tôi sẽ chỉ nói rằng tôi không hiểu về cách thức hoạt động bên trong của try catch, vì vậy tôi đoán một số biện pháp.

Điều đầu tiên xảy ra trong quá trình xử lý lỗi là chuyển từ trạng thái chương trình này sang trạng thái chương trình khác. Điều đó được thực hiện như thế nào? Tôi sẽ làm điều đó.

Về mặt lịch sử, các lỗi cũ hơn và đơn giản hơn, và các ngoại lệ là mới hơn, phức tạp hơn một chút và có khả năng. Các lỗi vẫn có hiệu quả cho đến khi bạn cần giải quyết chúng, tương đương với việc giao một vấn đề khó cho cấp trên của bạn.

Lỗi có thể là số, như số lỗi và đôi khi với một hoặc nhiều chuỗi liên kết. Ví dụ: nếu xảy ra lỗi đọc tệp, bạn có thể báo cáo lỗi đó là gì và có thể bị lỗi. (Hay, đó là một bước tiến so với việc chỉ bị rơi như ngày xưa.)

Điều không thường được nói về các ngoại lệ là ngoại lệ là các đối tượng được xếp lớp trên một ngăn xếp ngoại lệ đặc biệt. Nó giống như một ngăn xếp trả về cho luồng chương trình, nhưng nó giữ trạng thái trả về chỉ dành cho các trys và bắt lỗi. (Tôi thường gọi chúng là ePush và ePop, và? Abort là một lần ném có điều kiện sẽ ePop và phục hồi đến mức đó, trong khi Abort là một lần chết hoặc thoát hoàn toàn.)

Ở dưới cùng của ngăn xếp là thông tin về người gọi ban đầu, đối tượng biết về trạng thái khi lần thử bên ngoài được bắt đầu, thường là khi chương trình của bạn được bắt đầu. Trên cùng, hoặc lớp tiếp theo trên ngăn xếp, với phần trên là con và phần dưới là cha, là đối tượng ngoại lệ của khối try / catch bên trong tiếp theo.

Nếu bạn đặt miếng thử bên trong, bạn đang xếp miếng thử bên trong lên trên miếng thử bên ngoài. Khi lỗi xảy ra trong lần thử bên trong và phần bắt bên trong không thể xử lý được hoặc lỗi được chuyển sang phần thử bên ngoài, thì quyền điều khiển được chuyển cho khối bắt bên ngoài (đối tượng) để xem nó có thể xử lý lỗi hay không, tức là Người giám sát của bạn.

Vì vậy, những gì ngăn xếp lỗi này thực sự làm là có thể đánh dấu và khôi phục luồng chương trình và trạng thái hệ thống, nói cách khác, nó cho phép một chương trình không làm sập ngăn xếp trả về và làm rối tung mọi thứ cho người khác (dữ liệu) khi có sự cố. Vì vậy, nó cũng lưu trạng thái của bất kỳ tài nguyên nào khác như các vùng cấp phát bộ nhớ và do đó nó có thể dọn dẹp chúng khi bắt xong. Nói chung, đây có thể là một điều rất phức tạp, và đó là lý do tại sao việc xử lý ngoại lệ thường chậm. Nói chung, khá nhiều trạng thái cần phải đi vào các khối ngoại lệ này.

Vì vậy, một loại khối try / catch thiết lập một trạng thái để có thể quay trở lại nếu tất cả những thứ khác bị rối. Nó giống như cha mẹ. Khi cuộc sống của chúng ta rối tung lên, chúng ta có thể ngã vào lòng cha mẹ và họ sẽ ổn định trở lại.

Hy vọng tôi đã không làm bạn thất vọng.


1

Bạn có thể thêm nhận xét này

function doSomething()
{
   /** @noinspection PhpUnhandledExceptionInspection */
   throw new Exception();
}

0

Sau khi set_error_handler () được xác định, trình xử lý lỗi tương tự như Exception. Xem mã bên dưới:

 <?php
 function handleErrors( $e_code ) {
   echo "error code: " . $e_code . "<br>";
 }

 set_error_handler( "handleErrors" ); 

 trigger_error( "trigger a fatal error", E_USER_ERROR);
 echo "after error."; //it would run if set_error_handler is defined, otherwise, it wouldn't show
?>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.