Many programmers for some reason believe that exceptions and errors are one and the same. Someone constantly throwing exception, someone through errorHandler turns errors into exceptions. Some try to increase productivity using exceptions. But, in fact, exception and errors are completely different mechanisms. It is not necessary to replace one mechanism with another. They are created for different purposes.
When php5 appeared with exceptions, and then ZendFramework, which always throws exceptions - I could not understand: what is the exception better than my favorite trigger_error ()? Long thought, discussed with colleagues and understood this question. Now I clearly know where to use trigger_error (), and where throw is new Exception ().
What is the fundamental difference between them?
')
Errors
Errors are something that cannot be fixed, you can only report this: write to the log, send an email to the developer and apologize to the user. For example, if my engine cannot connect to the database, then this is a mistake. Everything. Point. Without a database, the site does not work, and I cannot do anything about it. Therefore, I call ales_kaput () and trigger_error (), and my errorHandler will send me an email and show the visitor the message "Sorry, the site is not working."
Exception
Exceptions are not errors, they are just special situations that need to be handled in some way. For example, if in the calculator you try to divide by zero, the calculator will not hang, will not send messages to the developer and will apologize to you. Such situations can be handled with the usual if-ohm. Strictly speaking,
exceptions are a language construct that allows you to control the flow of execution . This is a construction that is in the same row as if, for, and return. And that's all. This mechanism is nothing more. Only flow control.
Their main purpose: to
forward in a cascade . I will show it on an example: there are three functions that cause each other to cascade:
<?php a(); function a() { b(); } function b() { c(99); } function c($x) { if ($x === 0) {
This task could be solved without the exception mechanism. For example, you can force all functions to return a special type
(if you are a hard-haired pahapeshnik, you should remember PEAR_Error) . For simplicity, I’ll get by with null:
<?php a(); function a() { echo 'a-begin'; $result = b(); if ($result === null) { echo ' '; return; } echo 'a-stop'; } function b() { echo 'b-begin'; $result = c(0); if ($result === null) { return null; } echo 'b-stop'; return true; } function c($x) { echo 'c-begin'; if ($x === 0) { return null; } echo 'c-stop'; return 100 / $x; }
Result of work:
a-begin
b-begin
c-begin
Divide by zero is not good
The task is completed, but note that I had to modify the intermediate function b () so that it forward the result of the work of the subordinate function above in a cascade. And if I have a cascade of 5 or 10 functions? Then I would have to modify ALL intermediate functions. And if an exceptional situation in the designer? Then I would have to substitute
crutches .
And now the solution using Exception:
a(); function a() { echo 'a-begin'; try { b(); echo 'a-stop'; } catch (Exception $e) { echo $e->getMessage(); } } function b() { echo 'b-begin'; c(0); echo 'b-stop'; } function c($x) { echo 'c-begin'; if ($x === 0) { throw new Exception(' '); } echo 'c-stop'; return 100 / $x; }
The result of the execution will be identical. The function b () remained intact, untouched. This is especially true if you have long cascades. And the $ e object may contain additional information about the situation that occurred.
Thus, it turns out that errors and exceptions are completely different tools for solving completely different tasks:
an error is not a reversible situation;
exception - allows you to interrupt the execution of a cascade of functions and forward some information. Something like a global return operator. If you do not have a cascade, you only need to use if or return.
Errors are not always errors.
Some may object to me: “Look in the Zend Framework - they always throw exceptions. This is the best practics, and should be done as well. Even if you could not connect to the database, you need to throw an exception. ”
In this article, I just want to dispel this misconception. Zend really is best practics, but Zend programmers are on a different boat and doing other things. The principal difference between them and me is that they write a
universal library that will be used in many projects. And they, from their bell tower, cannot say what is a critical error and what is reparable.
For example, in your project there may be several MySQL servers and you can switch between them when one of them falls. Therefore, Zend_Db, as a universal library, throws an exception, and decide what to do with it. Exception is flexible - you decide at what level and what type of situations to catch. You can display an error message or try to correct the situation if you know how.
When writing universal libraries, you should always throw exceptions . This makes the library more flexible.
As a result, I can say that both mechanisms have their own characteristics and, most importantly, that they have their own purpose and these purposes do not overlap at all.
Errors! = Exceptions . Do not use exceptions to improve performance or error messages. It is not necessary in the class My_Custom_Exception to implement any logic to correct the situation. This class must be empty, it is created only to determine the
type of situation and catch only what is needed. The class name 'My_Custom_Exception' is such a tree-like analogue of the linear list of constants E _ *** (E_NOTICE, E_WARNING, ...).
In php, an error handling mechanism has long been developed, and it works fine. I use it perfectly where it is needed.