PHP: exceptions vs errors?

2019-01-01 10:04发布

Maybe I'm missing it somewhere in the PHP manual, but what exactly is the difference between an error and an exception? The only difference that I can see is that errors and exceptions are handled differently. But what causes an exception and what causes an error?

10条回答
呛了眼睛熬了心
2楼-- · 2019-01-01 10:27

Re: "but what exactly is the difference between an error and an exception?"

There are a lot of good answers about the differences here. I'll just add in something that hasn't yet been talked about - performance. Specifically, this is for the difference between throwing/handling exceptions and handling a return code (either success or some error). Usually, in php, this means returning false or null, but they can be more detailed such as with file uploading: http://php.net/manual/en/features.file-upload.errors.php You could even return an Exception object!

I've done a few performance runs in different languages/systems. Generally speaking, exception handling is about 10,000x slower than checking for an error return code.

So, if it absolutely, positively needs to finish executing before it even started - well, you're out of luck because time travel doesn't exist. Without time travel, return codes are the fastest option available.

Edit:

PHP is highly optimized for exception handling. Real world tests show that throwing an exception is only 2-10x slower than returning a value.

查看更多
浪荡孟婆
3楼-- · 2019-01-01 10:32

The answer deserves talking about the elephant in the room

Errors is the old way of handling an error condition at run-time. Typically the code would make a call to something like set_error_handler before executing some code. Following the tradition of assembly language interrupts. Here is how some BASIC code would look.

on error :divide_error

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

:divide_error

if errcode = X
   print "divide by zero error"

It was hard to make sure that set_error_handler would be called with the right value. And even worse, a call could be made to a separate procedure that would change the error handler. Plus many times calls were interspersed with set_error_handler calls and handlers. It was easy for code to quickly get out of control. Exception handling came to the rescue by formalizing syntax and semantics of what good code was really doing.

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

No separate function or risk of calling the wrong error handler. The code now is guaranteed to be in the same place. Plus we get better error messages.

PHP used to only have error handling, when many other languages already had evolved to the preferable exception handling model. Eventually the makers of PHP implemented exception handling. But likely to support old code, they kept error handling and provided a way to make error handling look like exception handling. Except that, there is no guarantee that some code may not reset the error handler which was precisely what exception handling was meant to provide.

Final answer

Errors that were coded before exception handling was implemented, are likely still errors. New errors are likely exceptions. But there is no design or logic to which are errors and which are exceptions. It's just based in what was available at the time it was coded, and the preference of the programmer coding it.

查看更多
爱死公子算了
4楼-- · 2019-01-01 10:33

As stated in other answers, setting error handler to exception thrower is the best way to handle errors in PHP. I use a bit simpler setup:

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

Please note the error_reporting() check to keep @ operator working. Also, there is no need to define custom exception, PHP has one nice class for that.

Great benefit of throwing exceptions is that exception has stack trace associated with them, so it is easy to find where is the problem.

查看更多
君临天下
5楼-- · 2019-01-01 10:41

Exceptions are thrown - they are intended to be caught. Errors are generally unrecoverable. Lets say for instance - you have a block of code that will insert a row into a database. It is possible that this call fails (duplicate ID) - you will want to have a "Error" which in this case is an "Exception". When you are inserting these rows, you can do something like this

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

echo "Some more stuff";

Program execution will continue - because you 'caught' the exception. An exception will be treated as an error unless it is caught. It will allow you to continue program execution after it fails as well.

查看更多
何处买醉
6楼-- · 2019-01-01 10:44

One thing to add here is about handling exceptions and errors. For the purpose of the application developer, both errors and exceptions are "bad things" that you want to record to learn about the problems that your application has - so that your customers have a better experience in the long run.

So it makes sense to write an error handler that does the same thing as what you do for exceptions.

查看更多
看淡一切
7楼-- · 2019-01-01 10:46

I think the anwser you're looking for is that;

Errors are the standard stuff you're used to, like echoing a $variable that doesnt exist.
Exceptions are only from PHP 5 onwards and come when dealing with objects.

To keep it simple:

Exceptions are the errors you get when dealing with objects. The try/catch statement lets you do something about them though, and is used much like the if/else statement. Try to do this, if problem, doesnt matter, do this.

If you dont "catch" an exception, then it turns into a standard error.

Errors are the php fundemental errors which usually halt your script.

Try/catch is often used for establishing database connections like PDO, which is fine if you want to redirect the script or do something else if the connection doesnt work. But if you just want to display the error message and stop the script then you dont need it, the uncaught exception turns into a fatal error. Or you can use a site-wide error handling setting as well.

Hope that helps

查看更多
登录 后发表回答