-
Notifications
You must be signed in to change notification settings - Fork 105
/
Copy pathset-error-handler.xml
351 lines (330 loc) · 11.8 KB
/
set-error-handler.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<!-- EN-Revision: 21ce7d7f4f9f6f241f3e09e7f0a5be5c504d90d2 Maintainer: daijie Status: ready -->
<!-- CREDITS: mowangjuanzi, Luffy -->
<refentry xml:id="function.set-error-handler" xmlns="http://docbook.org/ns/docbook">
<refnamediv>
<refname>set_error_handler</refname>
<refpurpose>设置用户自定义的错误处理函数</refpurpose>
</refnamediv>
<refsect1 role="description">
&reftitle.description;
<methodsynopsis>
<type class="union"><type>callable</type><type>null</type></type><methodname>set_error_handler</methodname>
<methodparam><type class="union"><type>callable</type><type>null</type></type><parameter>callback</parameter></methodparam>
<methodparam choice="opt"><type>int</type><parameter>error_levels</parameter><initializer><constant>E_ALL</constant></initializer></methodparam>
</methodsynopsis>
<para>
设置用户的函数 (<parameter>callback</parameter>) 来处理脚本中出现的错误。
</para>
<para>
本函数可用于在运行时定义自定义错误处理程序,例如,在应用程序中发生严重错误,或者在特定条件下触发了错误(使用
<function>trigger_error</function>),应用程序需要执行文件/数据清理。
</para>
<para>
重要的是要记住 <parameter>error_levels</parameter> 里指定的错误类型都会绕过 PHP 标准错误处理程序,
除非回调函数返回了 &false;。
<function>error_reporting</function> 设置将不会起到作用而继续会调用错误处理函数
—— 不过仍然可以获取 <link linkend="ini.error-reporting">error_reporting</link> 的当前值,并做适当处理。
</para>
<para>
同时注意,处理程序有责任在必要时使用 <function>exit</function> 停止脚本执行。
如果错误处理程序返回了,脚本将会在发生错误的后一行继续执行。
</para>
<para>
以下级别的错误不能由用户定义的函数来处理,独立于发生错误的地方:
<constant>E_ERROR</constant>、 <constant>E_PARSE</constant>、
<constant>E_CORE_ERROR</constant>、 <constant>E_CORE_WARNING</constant>、
<constant>E_COMPILE_ERROR</constant>、
<constant>E_COMPILE_WARNING</constant>,和在
调用 <function>set_error_handler</function> 函数所在文件中产生的大多数
<constant>E_STRICT</constant>。
</para>
<para>
如果错误发生在脚本执行之前(比如文件上传时),将不会
调用自定义的错误处理程序因为它尚未在那时注册。
</para>
</refsect1>
<refsect1 role="parameters">
&reftitle.parameters;
<para>
<variablelist>
<varlistentry>
<term><parameter>callback</parameter></term>
<listitem>
<para>
如果传递 &null;,则处理程序重置为默认状态。否则,处理程序是具有以下签名的回调。
</para>
<para>
<methodsynopsis>
<type>bool</type><methodname><replaceable>handler</replaceable></methodname>
<methodparam><type>int</type><parameter>errno</parameter></methodparam>
<methodparam><type>string</type><parameter>errstr</parameter></methodparam>
<methodparam choice="opt"><type>string</type><parameter>errfile</parameter></methodparam>
<methodparam choice="opt"><type>int</type><parameter>errline</parameter></methodparam>
<methodparam choice="opt"><type>array</type><parameter>errcontext</parameter></methodparam>
</methodsynopsis>
<variablelist>
<varlistentry>
<term><parameter>errno</parameter></term>
<listitem>
<simpara>
第一个参数 <parameter>errno</parameter>,将会以 int 形式传递错误的级别。
</simpara>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>errstr</parameter></term>
<listitem>
<simpara>
第二个参数 <parameter>errstr</parameter>,将会以 string 形式传递错误的信息。
</simpara>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>errfile</parameter></term>
<listitem>
<simpara>
如果回调接受第三个参数,<parameter>errfile</parameter>,将会以 string 形式传递错误的文件名。
</simpara>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>errline</parameter></term>
<listitem>
<simpara>
如果回调接受第四个参数,<parameter>errline</parameter>,将会以 int 形式传递错误发生的行号。
</simpara>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>errcontext</parameter></term>
<listitem>
<simpara>
如果回调接受第五个参数,<parameter>errcontext</parameter>
将会传递数组,该数组指向错误发生时活动符号表。也就是说,<parameter>errcontext</parameter>
会包含错误触发处作用域内所有变量的数组。用户的错误处理程序不应该修改错误上下文(context)。
</simpara>
<warning xmlns="http://docbook.org/ns/docbook">
<simpara>
此参数自 PHP 7.2.0 后<emphasis>弃用</emphasis>并自 PHP 8.0.0
<emphasis>移除</emphasis>。如果函数没有为该参数定义默认值,那么在调用时会出现“too few arguments”的错误。
</simpara>
</warning>
</listitem>
</varlistentry>
</variablelist>
</para>
<para>
如果函数返回 &false;,标准错误处理处理程序将会继续调用。
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>error_levels</parameter></term>
<listitem>
<para>
就像 <link linkend="ini.error-reporting">error_reporting</link>
的 ini 设置能够控制错误的显示一样,此参数能够用于屏蔽
<parameter>callback</parameter> 的触发。如果没有该掩码,无论 <link
linkend="ini.error-reporting">error_reporting</link> 是如何设置的,<parameter>callback</parameter>
都会在每个错误发生时被调用。
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect1>
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
Returns the previously defined error handler (if any) as a <type>callable</type>.
If the built-in error handler is used &null; is returned.
</para>
</refsect1>
<refsect1 role="changelog">
&reftitle.changelog;
<para>
<informaltable>
<tgroup cols="2">
<thead>
<row>
<entry>&Version;</entry>
<entry>&Description;</entry>
</row>
</thead>
<tbody>
<row>
<entry>8.0.0</entry>
<entry>
删除 <parameter>errcontext</parameter> 并不再传递给用户回调。
</entry>
</row>
<row>
<entry>7.2.0</entry>
<entry>
<parameter>errcontext</parameter> 被废弃。使用此参数时会导致 <constant>E_DEPRECATED</constant> 提醒。
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</para>
</refsect1>
<refsect1 role="examples">
&reftitle.examples;
<para>
<example>
<title>用 <function>set_error_handler</function> 和 <function>trigger_error</function> 进行错误处理</title>
<para>
以下示例展示了通过触发错误并以用户自定义的程序来进行内部异常的处理。
</para>
<programlisting role="php">
<![CDATA[
<?php
// error handler function
function myErrorHandler($errno, $errstr, $errfile, $errline)
{
if (!(error_reporting() & $errno)) {
// This error code is not included in error_reporting, so let it fall
// through to the standard PHP error handler
return false;
}
// $errstr may need to be escaped:
$errstr = htmlspecialchars($errstr);
switch ($errno) {
case E_USER_ERROR:
echo "<b>My ERROR</b> [$errno] $errstr<br />\n";
echo " Fatal error on line $errline in file $errfile";
echo ", PHP " . PHP_VERSION . " (" . PHP_OS . ")<br />\n";
echo "Aborting...<br />\n";
exit(1);
case E_USER_WARNING:
echo "<b>My WARNING</b> [$errno] $errstr<br />\n";
break;
case E_USER_NOTICE:
echo "<b>My NOTICE</b> [$errno] $errstr<br />\n";
break;
default:
echo "Unknown error type: [$errno] $errstr<br />\n";
break;
}
/* Don't execute PHP internal error handler */
return true;
}
// function to test the error handling
function scale_by_log($vect, $scale)
{
if (!is_numeric($scale) || $scale <= 0) {
trigger_error("log(x) for x <= 0 is undefined, you used: scale = $scale", E_USER_ERROR);
}
if (!is_array($vect)) {
trigger_error("Incorrect input vector, array of values expected", E_USER_WARNING);
return null;
}
$temp = array();
foreach($vect as $pos => $value) {
if (!is_numeric($value)) {
trigger_error("Value at position $pos is not a number, using 0 (zero)", E_USER_NOTICE);
$value = 0;
}
$temp[$pos] = log($scale) * $value;
}
return $temp;
}
// set to the user defined error handler
$old_error_handler = set_error_handler("myErrorHandler");
// trigger some errors, first define a mixed array with a non-numeric item
echo "vector a\n";
$a = array(2, 3, "foo", 5.5, 43.3, 21.11);
print_r($a);
// now generate second array
echo "----\nvector b - a notice (b = log(PI) * a)\n";
/* Value at position $pos is not a number, using 0 (zero) */
$b = scale_by_log($a, M_PI);
print_r($b);
// this is trouble, we pass a string instead of an array
echo "----\nvector c - a warning\n";
/* Incorrect input vector, array of values expected */
$c = scale_by_log("not array", 2.3);
var_dump($c); // NULL
// this is a critical error, log of zero or negative number is undefined
echo "----\nvector d - fatal error\n";
/* log(x) for x <= 0 is undefined, you used: scale = $scale" */
$d = scale_by_log($a, -2.5);
var_dump($d); // Never reached
?>
]]>
</programlisting>
&example.outputs.similar;
<screen>
<![CDATA[
vector a
Array
(
[0] => 2
[1] => 3
[2] => foo
[3] => 5.5
[4] => 43.3
[5] => 21.11
)
----
vector b - a notice (b = log(PI) * a)
<b>My NOTICE</b> [1024] Value at position 2 is not a number, using 0 (zero)<br />
Array
(
[0] => 2.2894597716988
[1] => 3.4341896575482
[2] => 0
[3] => 6.2960143721717
[4] => 49.566804057279
[5] => 24.165247890281
)
----
vector c - a warning
<b>My WARNING</b> [512] Incorrect input vector, array of values expected<br />
NULL
----
vector d - fatal error
<b>My ERROR</b> [256] log(x) for x <= 0 is undefined, you used: scale = -2.5<br />
Fatal error on line 35 in file trigger_error.php, PHP 5.2.1 (FreeBSD)<br />
Aborting...<br />
]]>
</screen>
</example>
</para>
</refsect1>
<refsect1 role="seealso">
&reftitle.seealso;
<para>
<simplelist>
<member><classname>ErrorException</classname></member>
<member><function>error_reporting</function></member>
<member><function>get_error_handler</function></member>
<member><function>trigger_error</function></member>
<member><link linkend="errorfunc.constants">error level constants</link></member>
</simplelist>
</para>
</refsect1>
</refentry>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->