PHP Exception exception exception handling and exit/die

  ios, question

It has always been difficult to understand exception handling, for example, mysql database connection is used in the bottom layer of my program, and all programs in the top layer of my program are built on this basis (cache and other things are not considered). For example, if a page needs to retrieve the post content specified by id in the current url, mysql_connect cannot be connected as a result when the bottom layer database connection is called, then the application built on this basis is no longer necessary to execute. Shouldn’t my mysql_connect directly exit/die the program? Even if I want friendly error prompt, I can customize a function such as MyError($code), beautify my output in this function and then decide whether to exit/die in it.

If exception handling is used, then I must add try/catch wherever I think it may be incorrect? Is it not a bunch of try/catch after one of my programs … how is this different from me directly using die/exit or calling custom MyError ()? If the Exception can be passed up, but I should deal with it immediately many times, for example, the database cannot be connected, or the file does not exist when I include system configuration, shouldn’t I deal with it immediately at this time?

For example, I made a single entry, Router-> controllers-> services/models-> modelbase-> dbfactory-> MySQL-> driver. is it ok for me to add a try/catch outside the router and throw all inside? For example, there is a problem with mysql_connect in my MySQL. When getting the id in my Controller, the id in the url does not exist in the database. Do I have to try/catch/throw both of them and then handle them in the catch outside the Router?

It is really very confusing, asking for answers, the manual is to teach how to use, not to teach application scenarios, and why? (that why really can’t see why), ask for advice! It is best to point out the specific application scenario, thank you ~


Thank you very much for your detailed answer, thank you! There are still some questions that I would like to trouble you with. It is not very good to comment on inside, so I will bring them here.

For example, the problem of missing configuration files can be solved by:

1, the most original direct require, so the configuration file does not exist and then directly report an error (report an error to open), which is obviously inappropriate, unfriendly and will expose the physical path.

2. I have realized in advance that there may be a problem with require, so I decided to judge whether is_file/file_exists before require, so:

$file = '/a/b/c.php';
 is_file($file) or die('config file not found');

Or ..

$file = '/a/b/c.php';
 is_file($file) or throw new Exception('config file not found');
 }catch(Exception $e){

The first code may be a bit crude. Not many die can be replaced by a custom error prompt function or can output friendly error messages.

What are the benefits of the second code? Is it because I still throw this $e at //todo, or just don’t try/catch here? Suppose I am a single entry, and the Exception of the whole system is finally handled at the highest level?

1. According to the concept of hierarchical processing, let’s assume that the code of config is “config layer”. First of all, it is certain that my “Dispatcher layer”, “Controller layer”, “DB layer” and “Model layer” all depend on it. Do I want these layers to handle this exception by themselves? Or do you mean that all these floors are throw out separately? Or do all these layers not matter (I don’t care, who cares in the end)? This one-to-many “config layer” serves other layers. shouldn’t the “config layer” dispose of itself when the configuration file is lost? Isn’t this also in line with the exception of non-proliferation?

2. If “config layer” handles it itself, shouldn’t //todo handle it with exit/die? Otherwise, wouldn’t it be another require?

3. If it loses its exit/die, isn’t the benefit of this exception just more trace information than my custom MyError?

Based on your question, you need to have a certain abstracting power and the concept of encapsulation. In fact, I prefer to call it layering, which means we should establish a concept similar to the following:

Upper Role
 -layer boundary line-
 Current Role
 -layer boundary line-
 Lower Role lower role

Based on the above concepts, whether exit/die or Exception can be divided into two situations:

A. Upper Role as recipient and Current Role as actor
 B. Current Role as recipient and Lower Role as actor

For A, who is the recipient of the behavior you want to consider? If the Upper Role is the Top Role (the Top Role generally refers to the person using the browser based on our application), then exit/die should be used. this is to be handled by the Top Role, i.e. all the Upper Roles except the Top Role have no right to interfere, while when the upper role is not the Top Role, then an Exception should be used, so that all the upper roles except the top role have the right to carry out some additional processing.

For mysql_connect connection based on A, (according to my design), when mysql_connect is used, Current Role refers to DB processing mysql-related logic, while Upper Role refers to unknown logic calling DB (think about why I use the concept of “unknown” here). Current Role only knows that mysql_connect connection has failed and does not know whether Upper Role has other DB or additional options. In order to give Upper Role a certain option, Current Role (I) choose to use Exception here and let Upper Role decide whether to hand it over to TOPPROLE or the upper Upper Role.

For the case of b, the Current Role has the following options to determine whether the Lower Role will have some unexpected situations (i.e. an Exception)

Is there anything other than what Current Role expects?
 If not, Current Role does not require try/catch.
 If so, does Current Role need to be handled?
 Current Role needs to be processed.
 Can Current Role handle it?
 Can handle
 Upper Role needs to handle the unexpected of Current Role.
 Current Role does not need to be handled and ignored.

For mysql_connect connection based on B, Current Role refers to the relevant logic that requires DB, while Lower Role refers to the logic that DB handles mysql connection. When Current Role is used, Current Role expects mysql to connect normally, but additional situations will also occur. Then Current Role should consider its own situation to choose, for example, Current Role is a select operation, then Current Role can be returned to null, then for msyql connection failure or data table is really null, with the same nature, Current Role can discard the unexpected (capture is not processed) and return to null. For an update, it can be processed or not, while for a logic that can select n mysql connections, it must be processed, and so on

In short, a lot of verbose, that is to say, if you want to use the exception well, then you must have the concept of upper and lower levels, and in the upper and lower level logic processing, you must distinguish whether the Current Role can terminate the program execution (exit) or be handled by the Upper Role (throw Excepton)

Finally, throw is Current Role feedback to Upper Role, try/catch is Current Role processing Lower Role feedback, I hope you can better use Exception.