part2-errorhandling.pkg
来自「视频监控网络部分的协议ddns,的模块的实现代码,请大家大胆指正.」· PKG 代码 · 共 548 行 · 第 1/2 页
PKG
548 行
<refentry id="{@id}">
<refnamediv>
<refname>Advanced Error Handling</refname>
<refpurpose>introduction to a new error-handling system</refpurpose>
</refnamediv>
<refsynopsisdiv>
<refsynopsisdivinfo>
<authorgroup>
<author>
<firstname>Laurent</firstname>
<surname>Laville</surname>
</author>
<othercredit>
<firstname>Gregory</firstname>
<surname>Beaver</surname>
<contrib>
Special thanks to Gregory Beaver, for his works on
{@link http://pear.php.net/package/PEAR PEAR_ErrorStack} (part of PEAR core >= 1.3.1) and
{@link http://pear.php.net/manual/en/core.pear.pear-errorstack.php its manual},
source of inspiration for the new HTML_Progress error handling system.
</contrib>
</othercredit>
</authorgroup>
</refsynopsisdivinfo>
</refsynopsisdiv>
{@toc}
<refsect1 id="{@id eh-intro}">
<title>Introduction</title>
<para>
Why write a new error-handling routine when
{@link http://pear.php.net/manual/en/core.pear.pear-error.php PEAR_Error} already exists ?
There are several problems with <emphasis>PEAR_Error</emphasis>.
Although an error message is present in an error class, processing this error message
automatically is excessively difficult for computers. In addition, the error message
cannot easily be translated once it has been placed into the <emphasis>PEAR_Error</emphasis> object.
There is also no standard facility for storing error-related data in the error class.
On top of error message-related issues, there is no way to automatically determine
which package a <emphasis>PEAR_Error</emphasis> object comes from, or the severity of an error.
Fatal errors look exactly the same as non-fatal errors.
</para>
<para>
<emphasis>HTML_Progress</emphasis> implements error raising and handling using a stack pattern
like {@link http://pear.php.net/manual/en/core.pear.pear-errorstack.php PEAR_ErrorStack}.
So why don't just use <emphasis>PEAR_ErrorStack</emphasis> rather than rewrite the same concept.
<emphasis>HTML_Progress</emphasis> is not a copy of features of <emphasis>PEAR_ErrorStack</emphasis>,
even it allows to plug-in any error-handler routine you might want to have.
</para>
<para>
Features of <emphasis>HTML_Progress</emphasis> error handling system include :
<itemizedlist>
<listitem>Error levels (notice/warning/error/exception) </listitem>
<listitem>Error context data is saved separate from error message </listitem>
<listitem>Dynamic error message generation </listitem>
<listitem>Sophisticated callbacks are available for error message generation, error context generation, and error handling functionality </listitem>
<listitem>Use your own error-handler </listitem>
</itemizedlist>
</para>
<para>
Default error handling system of <emphasis>HTML_Progress</emphasis> allow to :
<itemizedlist>
<listitem>Display or not any error message with control of PHP INI <emphasis>display_errors</emphasis> value </listitem>
<listitem>Display error message as the default PHP error handler (Error level and File, Line context in bold face) </listitem>
</itemizedlist>
</para>
<refsect2 id="{@id intro-basic}">
<title>Basic example</title>
<para>
Now with this example, we will demonstrate the basic use and result
of <emphasis>HTML_Progress</emphasis> error handler.
<example>
{@example eh_basic_display.php}
</example>
</para>
<para>
We will get the message below only if PHP INI <emphasis>display_errors</emphasis>
is enable ('on' | '1' ).
</para>
<screen>
<emphasis>Error</emphasis>: invalid input, parameter #1 "$model" was expecting "dm_class_model class defined", instead got "class does not exists"
in <emphasis>html_progress->setdm</emphasis>
(file <emphasis>d:\php\pear\html_progress\tutorials\html_progress\examples\eh_basic_display.php</emphasis> at line <emphasis>6</emphasis>)
</screen>
<para>
For basic use, this is all you have to know to use <emphasis>HTML_Progress</emphasis> package
to raise <emphasis>PEAR_Error</emphasis> object without its disadvantages.
</para>
</refsect2>
</refsect1>
<refsect1 id="{@id eh-advanced}">
<title>Advanced features</title>
<refsect2 id="{@id advanced-context-display}">
<title>Error Context Display</title>
<para>
In some cases, you may want to customize error generation. For instance, for many exceptions,
it is useful to include file, line number, and class/function context information
in order to trace an error. A default option is available (<emphasis>context_callback</emphasis>)
which will be sufficient for most cases.
</para>
<para>
Let's have a look on the default context callback routine :
<emphasis>HTML_Progress::_getBacktrace</emphasis>
<para>
<programlisting role="php">
<![CDATA[
<?php
function _getBacktrace()
{
if (function_exists('debug_backtrace')) {
$backtrace = debug_backtrace(); // PHP 4.3+
$backtrace = $backtrace[count($backtrace)-1];
} else {
$backtrace = false; // PHP 4.1.x, 4.2.x (no context info available)
}
return $backtrace;
}
?>
]]>
</programlisting>
</para>
This function generates a PHP backtrace and returns this information as an associative array.
See {@link http://www.php.net/debug_backtrace} for details.
</para>
<para>
If you wish context information to be in the error message, the error handler callback
(option <emphasis>error_handler</emphasis>)
should add the information in a human-readable format to the error message.
</para>
<para>
Let's have a look on part of the default error callback routine :
<emphasis>HTML_Progress::_errorHandler</emphasis>
<para>
<programlisting role="php">
<![CDATA[
<?php
function _errorHandler($err)
{
include_once 'PEAR.php';
$e = PEAR::raiseError($err['message'], $err['code'], PEAR_ERROR_RETURN, E_USER_ERROR,
$err['context']);
if (isset($err['context'])) {
$file = $err['context']['file'];
$line = $err['context']['line'];
$func = $err['context']['class'];
$func .= $err['context']['type'];
$func .= $err['context']['function'];
}
$display_errors = ini_get('display_errors');
$log_errors = ini_get('log_errors');
$display = $GLOBALS['_HTML_PROGRESS_ERRORHANDLER_OPTIONS']['display'];
if ($display_errors) {
$lineFormat = $display['conf']['lineFormat'];
$contextFormat = $display['conf']['contextFormat'];
$context = sprintf($contextFormat, $file, $line, $func);
printf($lineFormat."<br />\n", ucfirst($err['level']), $err['message'], $context);
}
if ($log_errors) {
// more code here ... but hidden
}
return $e;
}
?>
]]>
</programlisting>
</para>
Context data are merged into error message with help of <emphasis>lineFormat</emphasis>
and <emphasis>contextFormat</emphasis> configuration options
(see {@tutorial part2-errorhandling.pkg#eh-control-logging.control-default-display Default Display Handler})
</para>
</refsect2>
<refsect2 id="{@id advanced-error-message}">
<title>Custom Error Message Generation</title>
<para>
Let's have a look on the default message callback routine :
<emphasis>HTML_Progress::_msgCallback</emphasis>
<programlisting role="php">
<![CDATA[
<?php
function _msgCallback($err)
{
$messages = HTML_Progress::_getErrorMessage();
$mainmsg = $messages[$err['code']];
if (count($err['params'])) {
foreach ($err['params'] as $name => $val) {
if (is_array($val)) {
$val = implode(', ', $val);
}
$mainmsg = str_replace('%' . $name . '%', $val, $mainmsg);
}
}
return $mainmsg;
}
function _getErrorMessage()
{
$messages = array(
HTML_PROGRESS_ERROR_INVALID_INPUT =>
'invalid input, parameter #%paramnum% '
. '"%var%" was expecting '
. '"%expected%", instead got "%was%"',
HTML_PROGRESS_ERROR_INVALID_CALLBACK =>
'invalid callback, parameter #%paramnum% '
. '"%var%" expecting %element%,'
. ' instead got "%was%" does not exists',
HTML_PROGRESS_DEPRECATED =>
'method is deprecated '
. 'use %newmethod% instead of %oldmethod%'
);
return $messages;
}
?>
]]>
</programlisting>
</para>
<para>
<emphasis>HTML_Progress::_getErrorMessage</emphasis> set and return an array mapping error codes
to error message templates.
</para>
<para>
Substitution is done (<emphasis>line 12</emphasis>) using {@link http://www.php.net/str_replace}.
Basically, if a variable name is enclosed in percent sign (%), it will be replaced
with the value passed in the associative array (<emphasis>line 8</emphasis>).
</para>
</refsect2>
<refsect2 id="{@id advanced-control-generation}">
<title>Controlling error generation</title>
<para>
There are many scenarios in which fine-grained control over error raising is absolutely necessary.
</para>
<para>
We can influence the error management through the use of five constants:
<itemizedlist>
<listitem><emphasis>HTML_PROGRESS_ERRORSTACK_PUSHANDLOG</emphasis>
informs the stack to push the error onto the error stack, and also to log the error.
</listitem>
<listitem><emphasis>HTML_PROGRESS_ERRORSTACK_PUSH</emphasis>
informs the stack to push the error onto the error stack, but not to log the error.
</listitem>
<listitem><emphasis>HTML_PROGRESS_ERRORSTACK_LOG</emphasis>
informs the stack not to push the error onto the error stack, but only to log the error.
</listitem>
<listitem><emphasis>HTML_PROGRESS_ERRORSTACK_IGNORE</emphasis>
informs the stack to ignore the error, as if it never occured. The error will be
neither logged, nor push on the stack. However, a PEAR_Error object will be returned
from {@tutorial progress.raiseerror.pkg}.
</listitem>
<listitem><emphasis>HTML_PROGRESS_ERRORSTACK_LOGANDDIE</emphasis>
informs the stack not to push the error onto the error stack, but only to log the error
and stop the script.
</listitem>
</itemizedlist>
</para>
<para>
For example, in HTML_Progress Unit Tests: we don't want that processes stop when
an exception is raised.
</para>
<para>
Let's have a look on the script <emphasis>HTML_Progress_TestCase_setIndeterminate.php</emphasis>
into the tests directory of this package:
<example>
{@example eh_push_callback.php}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?