It has been hard to understand exception handling. for example, my program uses a mysql database connection at the underlying layer, and all my upper-layer programs are built on this basis (without considering caching or other issues ), for example, if a page needs to retrieve the post content specified by the id in the current url, when the underlying database connection is called ,... it has been hard to understand exception handling. for example, my program uses a mysql database connection at the underlying layer, and all my upper-layer programs are built on this basis (without considering caching or other issues ), for example, if a page needs to retrieve the post content specified by the id in the current url and mysql_connect cannot be connected when the underlying database connection is called, the applications created on this basis are no longer necessary for execution, shouldn't I directly exit/die the program at mysql_connect? Even if a friendly error prompt is required, I can customize a function such as MyError ($ code). In this function, I will beautify my output and decide whether to exit/die.
If exception handling is used, do I have to add try/catch to all possible errors? Isn't there a bunch of try/catch... in a piece of my program? what is the difference between me directly using die/exit or calling custom MyError? If the Exception can be passed up, I should handle it immediately, for example, the database cannot be connected, or the file does not exist when I include the system configuration, shouldn't it be handled immediately?
For example, if I make a single entry, Router-> Controllers-> Services/Models-> ModelBase-> DbFactory-> MySQL-> Driver, is it okay if I add try/catch to the outside of the Router, and throw is all in it? For example, mysql_connect in MySQL has a problem. when I get an id in the Controller, the id in the url does not exist in the database, so I have to try/catch/throw both, and then try again in the catch outside the Router?
It is really confusing. I want to explain how to use the manual, why not teach the application scenario, and why? (Why can't you tell me why! It is best to point out specific application scenarios. thank you ~
Septem
Thank you for your answers. thank you! There are still some questions for you. it is not good to write the comments. I will write them here.
For example, if the configuration file is lost, the solution is as follows:
1. the original direct require. if the configuration file does not exist, an error is reported (an error is reported). This is obviously inappropriate, unfriendly, and the physical path is exposed.
2. I have realized that require may have problems in advance, so I decided to determine whether the file exists by is_file/file_exists before require, so:
$file = '/a/b/c.php';is_file($file) or die('config file not found');require($file);
Or
$file = '/a/b/c.php';try{ is_file($file) or throw new Exception('config file not found');}catch(Exception $e){ //todo}require($file);
The first code may be simple. not many die can be replaced with a custom error prompt function, or a friendly error message can be output.
So what are the benefits of the second code? Do I still throw this $ e at // todo, or do not try/catch it here? Suppose I am a single portal, and the Exception of the entire system is finally handed over to the top layer for processing?
1. according to the hierarchical processing concept, now we assume that the config code is "config layer ", first of all, it is certain that my "Dispatcher layer", "Controller layer", "DB layer", and "Model layer" depend on it, is it hard to say that I want these layers to handle this exception on their own? Or are these layers throw again? Or none of these layers (I don't care about it, who cares about it )? This "config layer" is mostly for other layer services. Shouldn't the "config layer" be replaced when the configuration file is lost? Does this mean that exceptions do not spread as much as possible?
2. if the "config layer" is used for processing, should I exit/die when processing the // todo? Otherwise, why not execute require again?
3. if it exits/die by itself, isn't the advantage of this exception only more trace information than my custom MyError?
Reply content:
It has been hard to understand exception handling. for example, my program uses a mysql database connection at the underlying layer, and all my upper-layer programs are built on this basis (without considering caching or other issues ), for example, if a page needs to retrieve the post content specified by the id in the current url and mysql_connect cannot be connected when the underlying database connection is called, the applications created on this basis are no longer necessary for execution, shouldn't I directly exit/die the program at mysql_connect? Even if a friendly error prompt is required, I can customize a function such as MyError ($ code). In this function, I will beautify my output and decide whether to exit/die.
If exception handling is used, do I have to add try/catch to all possible errors? Isn't there a bunch of try/catch... in a piece of my program? what is the difference between me directly using die/exit or calling custom MyError? If the Exception can be passed up, I should handle it immediately, for example, the database cannot be connected, or the file does not exist when I include the system configuration, shouldn't it be handled immediately?
For example, if I make a single entry, Router-> Controllers-> Services/Models-> ModelBase-> DbFactory-> MySQL-> Driver, is it okay if I add try/catch to the outside of the Router, and throw is all in it? For example, mysql_connect in MySQL has a problem. when I get an id in the Controller, the id in the url does not exist in the database, so I have to try/catch/throw both, and then try again in the catch outside the Router?
It is really confusing. I want to explain how to use the manual, why not teach the application scenario, and why? (Why can't you tell me why! It is best to point out specific application scenarios. thank you ~
2015-06-19
Thank you for your answers. thank you! There are still some questions for you. it is not good to write the comments. I will write them here.
For example, if the configuration file is lost, the solution is as follows:
1. the original direct require. if the configuration file does not exist, an error is reported (an error is reported). This is obviously inappropriate, unfriendly, and the physical path is exposed.
2. I have realized that require may have problems in advance, so I decided to determine whether the file exists by is_file/file_exists before require, so:
$file = '/a/b/c.php';is_file($file) or die('config file not found');require($file);
Or
$file = '/a/b/c.php';try{ is_file($file) or throw new Exception('config file not found');}catch(Exception $e){ //todo}require($file);
The first code may be simple. not many die can be replaced with a custom error prompt function, or a friendly error message can be output.
So what are the benefits of the second code? Do I still throw this $ e at // todo, or do not try/catch it here? Suppose I am a single portal, and the Exception of the entire system is finally handed over to the top layer for processing?
1. according to the hierarchical processing concept, now we assume that the config code is "config layer ", first of all, it is certain that my "Dispatcher layer", "Controller layer", "DB layer", and "Model layer" depend on it, is it hard to say that I want these layers to handle this exception on their own? Or are these layers throw again? Or none of these layers (I don't care about it, who cares about it )? This "config layer" is mostly for other layer services. Shouldn't the "config layer" be replaced when the configuration file is lost? Does this mean that exceptions do not spread as much as possible?
2. if the "config layer" is used for processing, should I exit/die when processing the // todo? Otherwise, why not execute require again?
3. if it exits/die by itself, isn't the advantage of this exception only more trace information than my custom MyError?
Based on your problem, you need to have a certain degree of abstraction and encapsulation. In fact, I prefer to call it layering, that is, we need to establish a concept similar to the following:
Upper Role ---------------- layer demarcation line ------------ Current Role of the Current Role ------------------ layer demarcation line ---------- Lower Role
Based on the above concepts, whether exit/die or Exception is divided into two situations:
A. Upper Role as the receiver, Current Role as the behavior party B. Current Role as the receiver, and Lower Role as the behavior party
For a, who is the receiver Upper Role of the behavior you want to consider? If Upper Role is the Top Role (the Top-level Role, generally based on our application, the Top-level Role refers to the person who uses the browser), then exit/die should be used, this requires Top Role to handle, that is, all Upper Role except Top Role has no right to interfere with, and when Upper Role is not Top Role, Exception should be used, in this way, all Upper Role except the Top Role have the right to perform some additional processing.
Based on a, mysql_connect is connected. (according to my design) when mysql_connect is used, Current Role refers to DB processing related mysql logic, the Upper Role is the unknown logic for calling the DB (think about why I want to use the "unknown" concept here). The Current Role only knows that the mysql_connect connection has failed, the Current Role does not know whether there are other DB or additional options for the Upper Role, so in order to make the Upper Role have certain options, here (I) chooses to use Exception, let the Upper Role decide whether to give the Top Role processing or the Upper-layer Upper Role processing.
In the case of B, the Current Role has the following options to determine whether the Lower Role has some situations that are not expected by the Current Role (that is, Exception ):
Is there any non-Current Role expectation? If not, the Current Role does not need try/catch. If yes, does the Current Role need to be processed? Current Role needs to be processed. can try/catch Current Role handle it? Yes. to process Upper Role, you need to process the Current Role's expectations. throw Current Role does not need to be processed and ignores
For mysql_connect connection based on B, the Current Role refers to the logic related to the database, and the Lower Role is the logic used by the DB to process the connection to mysql. when the Current Role is used, current Role expects that mysql can be connected normally, but this may occur in other cases. Therefore, Current Role should consider its own situation. for example, Current Role is a select operation, the Current Role can return null values. if the msyql connection fails or the data table is really empty, the Current Role can discard unexpected values (capture is not processed) the return value is blank. for an update, either processing or not processing can be selected. for a logic that can select n mysql connections, it must be processed.
In short, there are a bunch of arguments, that is, you need to make good use of exceptions, then you need to have the concept of the upper and lower layers, and in the upper and lower layer logic processing, you need to distinguish that the Current Role can terminate the program execution (exit) or by the Upper Role (throw sort ton)
Finally, throw is the Current Role that is fed back to the Upper Role, and try/catch is the Current Role that processes the Lower Role feedback. I hope you can use Exception better.
The landlord should have not understoodAbnormal execution mechanismFirst, read the PHP official manual and click here to describe the exception.
Let's take a look at how to use exceptions first.Exception execution process
Try {throw new Exception ('this is first exception. '); echo 'AAA';} catch (Exception $ e) {echo 'BBB';} // echo 'CCC 'is output here '; throw new Exception ('this is second exception. ');
What do you think is the output above? Below is the answer
BBBCCCFatal error: Uncaught exception 'Exception' with message 'This is second exception.' ...
From the above execution results, we can see some features of Exception:
- Try and catch must be paired. try {} contains code that may throw exceptions.
- Once an exception occurs in the code in try {}, the code after the exception stops execution.(The code in try {} is used here)
- After catch () {} is used to capture and handle exceptions, the code following try {} and catch () {} (for example
echo 'CCC'
) Will continue to execute.
- If the exception is not caught, a Fatal error is thrown.
Based on the above features, the questions raised by the Post owner are easier to solve.
Question 1: Do I have to try to catch every exception?
My answer: this is too troublesome and generally unnecessary,You can use a try catch to include all possible exceptions.. After an exception is caught, anyone who handles the exception can handle the exception.This also satisfies the development philosophy of a single portal and a single exit..
Problem 2: An error is thrown.Exception
Still usedie()/exit()
?
My answer:You can throw an exception at will, but you must have a place to handle it.. After processing (such as logging), you will eventually tell the front-end user about the error and the process is output. When an error occurs,I recommend that you use an exception.Exception
Because it conforms to the single exit development philosophyIn this way, you can monitor the output of all pages.If you usedie()/exit()
To directly output the output..
Furthermore,Exception
In fact, it actually contains more information, such as the number of lines, error code, and error stack information trace. So isn't it better?
Question 3: When is the application scenario used?
My answer: exceptions can be used in any situation.Exception
What role does it play.For example, when you write an API Service program, all errors (including program exceptions, business logic errors, field type errors, and so on) are thrown and handled in one place.. In fact, I feel that this development experience is very good, because I did not useException
~. But here is a question:API, which has no interface, is only responsible for returning some data, and the format of the returned data is generally unified and standardized..
If you are writing a front-end program and I want to write it, can you use it like this?Exception
:If any program error is thrown, use return/echo/die to return any business verification error.After all, exceptions can be expressed in a limited way. if some errors (common business errors) are returned in a very complex manner, and front-end applications have a high degree of freedom from API, exceptions may be inconvenient to use.
The above is my ignorance. if something is wrong, I hope to point out that we can make progress together! After work, leave...
If you want to globally capture errors or exceptions, see
Http://cn2.php.net/manual/zh/function.set-error-handler.php
Http://cn2.php.net/manual/zh/function.set-exception-handler.php
Both allow the use of a callable object to capture errors or exceptions
PHP calling exit to exit the script execution does not cause the PHP service to exit. this is essentially different from other languages. Therefore, other languages have to use try/catch to catch exceptions or determine return values for further processing, PHP is not required.
After reading this post, he halt is more secure and straightforward, although a little rough.