Php_study Diary: Exception handling
December 21, 2011
# #异常处理
Although we have written a neat, well-designed to it, but in the program can still have a variety of unexpected occurrences, when a program in the course of an accident, such as the exception of 0 overflow, array out of bounds, the file is not found, and other unusual events will prevent the normal operation of the program, so in the design process, to fully consider fault tolerance Estimate the various anomalies that may occur and handle them accordingly so that the program can run robustly.
> Previous Exception handling methods
The type of error that 1.php.ini will be able to display.
2.php.ini error_reporting Control the kind of messages that are output to the client. The following are some of the recommended configurations in php.ini.
error_reporting = E_all; Represents the output of all information
error_reporting = e_all&~e_notice; Represents the output of all errors except the prompt.
Error_reportin = e_compile_error| e_recoverable_error| e_error| E_core _error: Indicates the output of all ERROR messages.
3. In php.ini, the display_errors can set whether to output the error information of the above settings to the client
Display_errors=on output to the client (when debugging the code, open this very convenient)
Display_errors=off messages will not be output to the client (remember to change to OFF when they are finally released to the user)
Attention:
In PHP, the requirements for error handling are very loose. The PHP system will try to keep the program running unless a fatal error is encountered.
In addition to adjusting the display level of error messages in the php.ini file, you can also customize the display level of messages in your PHP code. PHP provides function error_reporting () to implement the ability to customize the display level of messages in this program.
function syntax: int error_reporting ([int level])
Function Description: Use this function to define the display level of error messages in the current PHP page. The parameter level uses a binary mask combination of the anti-pattern, the specific combination of the table look.
> Use Die () to terminate program operation
In the previous process of program development, the most common exception handling method is that the program is abnormal to stop execution, using Die () to terminate, so that the current program exits.
The Daxin program project typically stores the underlying classes separately in a single folder, each of which is stored as a php file named after the class name PHP file.
Suppose you store a file for the base Class library under the Mail_class directory of the Web site, where a stmp.php file is a base class or interface program that provides SMTP functionality, and there are other subclass files that use the class name as the file name: normal.php (normal mail is sent via the mail () function) , auth.php (send mail to a third-party SMTP server that needs to verify the sender's identity), mime.php (sending complex text messages), and so on.
Dir. "/" . $smtp. ". PHP";
if (!file_exists ($path))
{
Die ("Cannot find". $path. ". \ n");
}
Require_once $path;
if (!class_exists ($SMTP))
{
Die ("Class". $smtp. "does not exist. \ n");
}
$ret = new $smtp ();
if (! ( $ret instanceof SMTP))
{
Die ($SMTP. "Is not a SMTP class. \ n");
}
return $ret;
}
}
$SMTP = new Smtpmanager ();
$SMTP->getobject ("normal");
?>
In the example, if we attempt to find a class that fails, the execution of the script terminates, which demonstrates the security of the code. But this code is not flexible, not enough elasticity, in fact sometimes we do not want to find the desired class file immediately stop executing the program, perhaps we have a default command to let the program continue to execute.
> Use Trigger_error () to display a custom warning message.
Trigger_error functions are available in PHP versions above 4.01 to provide custom warnings that are better for handling errors and easier for client programmers to handle errors.
function syntax: bool Trigger_error (string $error _msg[,int $error _type])
Function Description: This function is used to provide a user-defined level of warning, prompt, error message, Trigger_error () accept an error message $error_msg and a constant $error_type as a parameter, you can use the $error_type constant has 3: e_ User_error (fatal error), e_user_warning (Warning level non-fatal error), E_user_notice (informational).
Dir. "/" . $smtp. ". PHP";
if (!file_exists ($path))
{
Trigger_error ("Cannot find". $path. ". \ n", e_user_error);
}
Require_once $path;
if (!class_exists ($SMTP))
{
Trigger_error ("Class". $smtp. "does not exist. \ n", e_user_error);
}
$ret = new $smtp ();
if (! ( $ret instanceof SMTP))
{
Trigger_error ($SMTP. "Is not a SMTP class. \ n", e_user_error);
}
return $ret;
}
}
Function ErrorHandler ($errnum, $errmsg, $file, $line)
{
if ($errnum = = E_user_error)
{
echo "ERROR: $errmsg \ n
";
echo "FILE: $file \ n
";
echo "line: $line \ n
";
Exit ();
}
}
$handler = Set_error_handler (' ErrorHandler ');
$SMTP = new Smtpmanager ();
$smtp->getobject ("auth");
?>
In this case, in order to handle the exception, the Set_error_handler () custom handler is used to receive the error thrown by the Trigger_error () function. Set_error_handler () takes a function name as a parameter. If an error is set, the function used as a parameter is called to handle the error. This function needs to pass in 4 parameters: Error flag, error message, error file, number of rows that have failed. We can also pass a set of arrays to Set_error_handler (), the first element in the array must be the name of the object that the error handler will call, and the second element when the error-handling function is called. Our error processor design is simple and can be improved, such as adding error messages to record, output debug data and so on. But still a very coarse error-handling approach, limited to what has been considered error, such as catching a e_user_error error, perhaps we do not want to use Exit () and Die () to abort the execution of the script, but if you do so, may cause some very subtle bugs, The program that should have been aborted is still in execution.
> at any time to determine the error ID
# #通过返回值进行处理的方法确实有效 means that we can handle multiple errors based on the environment, and not necessarily stop the execution of the program immediately when the first error occurs, but there are many shortcomings:
#程序复杂
#可靠性差
#返回信息有限
#返回代码标准化困难
The advantage of using the "false" error flag is intuitive, but the amount of information that is clearly given is not enough, and we cannot tell which part of the error is causing the return to false, so we add a Error_str property, which produces a more verbose error message.
Error_str = Get_class ($this). ":: {$method} (): $msg";
}
Public Function GetError ()
{
return $this->error_str;
}
Public Function GetObject ($SMTP)
{
$path = $this->dir. "/" . $smtp. ". PHP";
if (!file_exists ($path))
{
$this->seterror (__function__, "Cannot find". $path. ". \ n");
return false;
}
Require_once $path;
if (!class_exists ($SMTP))
{
$this->seterror (__function__, "Class". $smtp. "Does not exist.\n");
return false;
}
$ret = new $smtp ();
if (! ( $ret instanceof SMTP))
{
$this->seterror (__function__, $smtp. "Is not a SMTP class. \n|");
return false;
}
return false;
}
}
$SMTP = new Smtpmanager ();
if ($smtp->getobject ("MIME"))
{
Write normal process code here
}
Else
{
echo $smtp->geterror (). "
";
Die ("GetObject error!");
}
?>
This simple mechanism allows seterror () to record the error message, and the other code to get information about the script error by GetError (). We can extract this functionality into one of the most basic classes, all the other classes inherit from this class, so that we can handle the error uniformly, otherwise there may be confusion. However, it is difficult to make all the classes in the program inherit from the same class in the actual development, but it is possible to pass the interface (interface), otherwise it is not possible to implement some of the subclasses ' own functions.
Handling exceptions using the Pear Extension class Library
Finally, the most important way to handle an exception with the Pear base Class library that is extended in PHP4 is RaiseError (), which can return a Pear_error object in the case of an error, using:
Pear::raiseerror (string $message [, int $code [, int $mode [, int |array $options [, Mixed $userinfo [, String $error _class[, Boolean $skipmsg]])
Parameter description
String $message: Error message, if left blank, the default error message is "Unknown error"
Integer $code: Error code
Integer $mode: Error mode. (Some constants need to check the table settings themselves)
Mixed$options: Error code. (Remember call mode)
Mixed $userinfo: Store additional user information.
String $error _class: The wrong class name for the Error object.
Boolean $skipmsg: Use this parameter if the constructor for the custom class cannot accept an error message. If you do not have the $error_class parameter, do not use the $skipmsg parameter, it will not work.
After executing a piece of code that could produce an error, we need to use Pear's IsError () method to detect if there is an error, and we can use Pear_error's getmessage () to get the most recent error message. It is important to note that Pear::iserror () must be used in the critical area.
The IsError () method detects whether a variable is a Pear_error object and optionally contains an explicit error message or code. Its usage is as follows:
Boolean pear::iserror (mixed $data [, mixed $msgcode])
Parameter description:
Mixed $data: Check the value
Mixed $msgcode: Additional error messages or code to prepare for detection.
Error_str = Get_class ($this). ":: {$method} (): $msg";
}
Public Function GetError ()
{
return $this->error_str;
}
Public Function GetObject ($SMTP)
{
$path = $this->dir. "/" . $smtp. ". PHP";
if (!file_exists ($path))
{
Return Pear::raiseerror ("Cannot find". $path. ". \ n ");
}
Require_once $path;
if (!class_exists ($SMTP))
{
Return Pear::raiseerror ("Class". $stmp. " does not exist.\n ");
}
$ret = new $smtp ();
if (! ( $ret instanceof SMTP))
{
Return Pear::raiseerror ($SMTP. "Is not a SMTP class. \ n"); A possible return
}
return $ret; Another possible return.
}
}
$SMTP = new Smtpmanager ();
if (Pear::iserror ($SMTP))
{
echo $cmd->getmessage (). "\ n
";
Exit
}
Else
{
The normal process code is written here.
}
?>
Pear_error is both an error flag and an error related specific information, which is very useful for customer code. Although returning an object value gives us the flexibility to reflect on a problem in the program, its GetObject () method has two possible exits, and all are objects, sometimes confusing, with side effects of the "contaminated interface."
Exception Handling in >PHP5
The exception-handling mechanism we need in the past
#允许一个方法给出一个出错标记给客户代码
#提供程序错误的详细信息
#让你同时判断多个出错条件, separate the error reporting from the program processing process.
#返回值必须是独立的类型, will not be confused with the type of normal return, causing contamination of the interface.
PHP5 provides an object-oriented exception handling mechanism to achieve these goals.
> Exception Class exception
Definitions of properties and methods in the Exception class exception:
message = $message;
}
$this->code = $code; The default error code is 0
$this->file = __file__; Filename
$this->line = __line__; Line number
$this->trace = Debug_backtrace ();
$this->string = StringFormat ($this);
}
Get error message
Final public Function getMessage ()
{
return $this->message;
}
Code with Error
Final public Function GetCode ()
{
return $this->code;
}
file where the exception occurred
Final public Function GetFile ()
{
return $this->file;
}
Number of rows where the exception occurred
Final public Function GetLine ()
{
return $this->line;
}
Track exceptions each step passes the route, depositing the array, returning the array
Final public Function gettrace ()
{
return $this->trace;
}
As with the Gettrace () function, but you can convert the elements in the array to a string and output in a certain format
Final public Function gettraceasstring ()
{
}
//
Public Function __tostring ()
{
return $this->string;
}
}
?>
When our script encounters an exception, we can instantiate the object:
$ex = new Exception ("Could not open $this->file");
In PHP5, it is not necessary to write the above code to define the exception class, which is already built into PHP5, and it is recommended to throw an exception with the keyword throw when the exception is triggered instead of directly generating an object instance of exception.
> Exception thrown keyword throw
This process of generating an exception object and submitting it to the runtime system is called throwing (throw) an exception. The runtime system looks in the call stack of the method, starting with the method that generated the exception, until it finds a method that contains the appropriate exception handling, a process known as a catch (catch) exception.
The use of throw is:
throw new Exception ("Exception Message", 2);
> Exception Capture Try-catch statement
Any program code that calls a potentially thrown exception should use a try statement. Once the throw throws an exception, the program terminates immediately after the throw statement, and the statement after it is no longer executed, but in all the try blocks that contain it (possibly in the upper call function) looks for a try block containing its matching catch clause from inside out.
The catch statement is used to handle the exceptions that may be thrown. The parameters of a catch statement are similar to the declaration of a method, including an exception type and an exception object. The exception type must be a subclass of the exception class, which indicates the type of exception the catch statement handles, and the exception object is generated and captured by the runtime system in the code block specified by the try, which contains the processing of the object, where the object's methods can be called.
The syntax for the Try-catch statement is:
Try
{
Statements that may occur with exceptions
}
catch (Exception type exception instance)
{
Exception Handling Statements
}
Intercept:
Try
{
$SMTP = new Smtpmanager ();
$mail = $smtp->getobject (' MIME ');
}
catch (Exception $e)
{
Print $e->getmessage ();
Exit ();
}
If the try block does not produce any exceptions, the try block will run correctly and the catch block contents will not be executed.
If the try block throws an exception, it immediately looks for the catch block in the catch that can catch the exception, runs the corresponding Catch block code, and then jumps out of the Try-catch block to continue running. The code that follows the throw exception in the try block is skipped.
If an exception in a try block cannot be caught by a catch block, it is thrown into the system, causing a system fatal error and the code terminates running.
In a catch, the exception type is followed by a variable that points to the instance of the exception that was caught in memory.
If a statement in a try block can throw more than two exceptions, when you use the throw new Exception ($message, $code), you can specify the exception code with the second parameter $code, and then in the catch block, judge the different exception codes, respectively, for exception handling.
A catch statement can have more than one exception that handles different types of exceptions, with multiple extended exception-handling classes that match a common catch statement, and the run system detects the exception type handled by each catch statement from top to bottom until a catch statement of the type match is found. The arguments for each catch statement are like a matching test condition, and the first catch statement that matches will execute without executing the other catch statement. Here, a type match means that the exception type handled by the catch is exactly the same as the type of the generated exception object or its parent class, so the order of the catch statement should be from special to generic, and the catch statement for the particular exception will be unloaded earlier, The catch statement for the generic exception is written later.
It is also possible to handle multiple exception types with a catch statement, when its exception type parameter should be the parent of these multiple exception types, such as exception, which is designed to select the exception handling type of the catch statement according to the specific situation.
> Exception handling Function Settings Set_exception_handler
In general, we are all using try-catch to catch and handle the exception thrown by throw, in order to maintain backward compatibility, most of PHP built-in functions will not throw an exception. However, in order to use these features, new extensions are being customized, similar to the previous set_error_handler (), PHP also provides a less common way to specify a custom function to automatically catch and handle exceptions without using Try-catch. This feature is provided by the Set_exception_handler ()
When using Set_exception_handler (), the function definition code to be specified as the catch exception must be placed before Set_exception_handler () and the function name as a parameter to the Set_exception_handler ().
GetMessage (). "
Exception Code: ". $e->getcode ()
. "
FileName: ". $e->getfile (). "
Line: ". $e->getline (). "
Exception Trace: ". $e->gettraceasstring ();
}
Processing is not captured (try: Catch operation) exception
Custom exception handling functions test_error_except Be sure to Set_exception_handler () before
Set_exception_handler (' test_error_excepts ');
function File_open ()
{
if (!file_exists ($f))
{
throw new Exception ("File not found!", 1);
}
if (!fopen ($f, "R"))
{
throw new Exception ("File open error!", 2);
}
}
File_open ("test.htm");
?>
> Complete exception information
The exception class and its subclasses have a gettraceasstring () method that returns each layer of detail that causes an exception to occur in the law of the Parties; the Gettrace () method returns a multidimensional array that provides more detailed exception information. The first element of this array contains the location where the exception occurred, and the second element contains the details of the external method call, up to the highest level of invocation. Each element of this array is itself an array containing the following key-name elements.
KEY:
File: Files that produce an exception
Line: The number of rows in which the class method that generated the exception
Functions: The function/method of generating an exception
Class: The method in which the call is called
Type: Called: "::" means the call to the static class member "-" represents the instantiation call (the build object is instantiated before it is called)
Args: Class method receives parameters
> Extended Exception Handling classes
PHP5 also includes some subclasses of the exception class, with two direct subclasses logicexception and RuntimeException, respectively, representing logical exceptions and execution exceptions.
The Logicexception subclass also derives many logical exception subclasses.
The RuntimeException subclass derives many running exception subclasses.
We can also add other custom exception classes that must inherit from the exception class or its subclasses.
In a formal project, when an exception is thrown, several different catch blocks are used to detect the match. In addition, whether the program runs in debug mode and different processing mechanism and the same catch block according to the different exception code to handle the exception mechanism separately.
Dir. "/" . $smtp. ". PHP";
if (!file_exists ($path))
{
throw new Smtpexception ("Cannot find". $path. ". \ n");
}
Require_once $path;
if (!class_exists ($SMTP))
{
throw New Illegalexception ("Class". $smtp. "does not exist. \ n", 101);
}
$ret = new $smtp ();
if (! ( $ret instanceof SMTP))
{
throw new Illegalexception ($SMTP. "Is not a SMTP class. \ n", 102);
}
return $ret;
}
}
Try
{
$SMTP = new Smtpmanager ();
$mail = $smtp->getobject (' normal ');
}
catch (Smtpexception $e)//First Catch block
{
if ($debug)
{//debug mode
echo $e->getmessage ();
Exit ();
}
Else
{//Web site run mode, no debug information output
Exit ();
}
}
catch (Illegalexception $e)//second Catch block
{
if ($debug)
{//debug mode
Switch ($e->getcode ())
{
Case 101:
Process code if the file exists but the class does not exist
echo $e->getmessage (); Output information only, no exit () required
Break
Case 102:
Processing code when an object instance cannot be generated
Break
echo $e->getmessage (); No object instance available, exit () required
Exit ();
Default
Other default conditions
Break
}
}
}
catch (Exception $e)//Third Catch block
{
if ($debug)
{//debug mode
echo $e->getmessage ();
Exit ();
}
Else
{
Exit ();
}
}
?>
The smtpexception exception will be thrown when there is no similar name file under the Smtp_class folder, and a Illegalexception exception will be thrown when the file exists in the two class, or the class cannot generate an object instance, although this program may only throw 2 exceptions to the custom class , but finally provides a 3rd catch block to match the exception exception, and the exception class is the base class for all exception classes, which can match all exceptions, so if the catch block is placed before the first and second catch block, Only executes the contents of the catch block, and the exception handling code for the remaining two catch blocks will never be able to execute.
> Exception transfer and re-throw
What if we have triggered some exceptions that the calling program cannot handle immediately when it occurs? Similarly, the responsibility for handling this exception is given back to the previous level of code that invokes the current method, which in turn throws an exception again in the catch statement and is called a re-throw exception, which allows the exception to be passed up and down the chain of call layers of the method.
> Correct use of exception handling
1. It is not advocated to catch all exceptions with a catch statement, the most common scenario being a catch (Exception $e) statement.
To understand why, we must review the purpose of the catch statement. The catch statement indicates that we expect an exception to occur and that we want to be able to handle it. The purpose of the exception class is to tell PHP what kind of exception we want to handle. Since most exceptions are inherited directly or indirectly from Exception, catch (Exception ex) is tantamount to saying that we want to handle all exceptions, but it is not appropriate to handle several distinct exceptions in the same catch block. The catch statement should specify the specific exception type as much as possible, and should not specify a exception class that covers too wide a range. Use multiple catch, if necessary, and do not attempt to handle any exceptions that may occur.
2. Try to avoid putting a lot of code into a single try block, which is not a good habit. This makes it difficult for the parser to throw an exception because there are too many places in a large piece of code that can throw exception
# #本章小结
Anomaly is a new and important feature in PHP5, and the anomaly mechanism provides several very key benefits.
1. By centralizing error handling in catch statements, we can separate error handling from the application process. This also makes the code more readable and looks delightful. By taking a very strict strategy to catch all exceptions and abort the execution of the script, you get the additional elasticity you need, while achieving a safe and easy-to-use exception management.
2. To throw an exception, you can propagate the error message in the catch, passing the exception traffic from the lower layer to the upper layer, which means that the exception is passed back to the best place to decide what to do with the exception. This may seem a bit strange, but in practice it is often impossible to decide immediately what to do with an exception.
3. The throw/catch provided by the exception mechanism avoids the direct return of the error ID, and the return value of the method can be determined by the class. When other programmers use our code, it is possible to specify the form of return I as one he wants, without the need for a tiring, nonstop test to conveniently locate errors and maintain them.
The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion;
products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the
content of the page makes you feel confusing, please write us an email, we will handle the problem
within 5 days after receiving your email.
If you find any instances of plagiarism from the community, please send an email to:
info-contact@alibabacloud.com
and provide relevant evidence. A staff member will contact you within 5 working days.