reference/info/functions/assert.xml
27dcb487a7e9c0f04559522a6d2aacf860d622cd
...
...
@@ -3,7 +3,7 @@
3
3
<refentry xml:id="function.assert" xmlns="http://docbook.org/ns/docbook">
4
4
<refnamediv>
5
5
<refname>assert</refname>
6
-
<refpurpose>Checks if assertion is &false;</refpurpose>
6
+
<refpurpose>Checks an assertion</refpurpose>
7
7
</refnamediv>
8
8

9
9
<refsect1 role="description">
...
...
@@ -11,67 +11,150 @@
11
11
<methodsynopsis>
12
12
<type>bool</type><methodname>assert</methodname>
13
13
<methodparam><type>mixed</type><parameter>assertion</parameter></methodparam>
14
-
<methodparam choice="opt"><type>string</type><parameter>description</parameter></methodparam>
14
+
<methodparam choice="opt"><type class="union"><type>Throwable</type><type>string</type><type>null</type></type><parameter>description</parameter><initializer>&null;</initializer></methodparam>
15
15
</methodsynopsis>
16
16
<para>
17
-
<function>assert</function> will check the given
18
-
<parameter>assertion</parameter> and take appropriate action if
19
-
its result is &false;.
17
+
<function>assert</function>
18
+
allows for the definition of expectations: assertions that take effect
19
+
in development and testing environments, but are optimised away to have
20
+
zero cost in production.
20
21
</para>
21
22
<para>
22
-
If the <parameter>assertion</parameter> is given as a string it
23
-
will be evaluated as PHP code by <function>assert</function>.
24
-
The advantages of a string <parameter>assertion</parameter> are
25
-
less overhead when assertion checking is off and messages
26
-
containing the <parameter>assertion</parameter> expression when
27
-
an assertion fails. This means that if you pass a boolean condition
28
-
as <parameter>assertion</parameter> this condition will not show up as
29
-
parameter to the assertion function which you may have defined with the
30
-
<function>assert_options</function> function, the condition is converted
31
-
to a string before calling that handler function, and the boolean &false;
32
-
is converted as the empty string.
23
+
Assertions should be used as a debugging feature only.
24
+
One use case for them is to act as sanity-checks for preconditions
25
+
that should always be &true; and that if they aren't upheld this indicates
26
+
some programming errors.
27
+
Another use case is to ensure the presence of certain features like
28
+
extension functions or certain system limits and features.
33
29
</para>
34
30
<para>
35
-
Assertions should be used as a debugging feature only. You may
36
-
use them for sanity-checks that test for conditions that should
37
-
always be &true; and that indicate some programming errors if not
38
-
or to check for the presence of certain features like extension
39
-
functions or certain system limits and features.
31
+
As assertions can be configured to be eliminated, they should
32
+
<emphasis>not</emphasis> be used for normal runtime operations like
33
+
input parameter checks. As a rule of thumb code should behave as expected
34
+
even if assertion checking is deactivated.
40
35
</para>
41
36
<para>
42
-
Assertions should not be used for normal runtime operations like
43
-
input parameter checks. As a rule of thumb your code should
44
-
always be able to work correctly if assertion checking is not
45
-
activated.
46
-
</para>
47
-
<para>
48
-
The behavior of <function>assert</function> may be configured by
49
-
<function>assert_options</function> or by .ini-settings described
50
-
in that functions manual page.
51
-
</para>
52
-
<para>
53
-
The <function>assert_options</function> function and/or
54
-
<constant>ASSERT_CALLBACK</constant> configuration directive allow a
55
-
callback function to be set to handle failed assertions.
56
-
</para>
57
-
<para>
58
-
<function>assert</function> callbacks are particularly useful for
59
-
building automated test suites because they allow you to easily
60
-
capture the code passed to the assertion, along with information
61
-
on where the assertion was made. While this information can be
62
-
captured via other methods, using assertions makes it much faster
63
-
and easier!
37
+
<function>assert</function> will check that the expectation given in
38
+
<parameter>assertion</parameter> holds.
39
+
If not, and thus the result is &false;, it will take the appropriate action
40
+
depending on how <function>assert</function> was configured.
64
41
</para>
42
+

65
43
<para>
66
-
The callback function should accept three arguments. The first
67
-
argument will contain the file the assertion failed in. The
68
-
second argument will contain the line the assertion failed on and
69
-
the third argument will contain the expression that failed (if
70
-
any &#x2014; literal values such as 1 or "two" will not be passed via
71
-
this argument). Users of PHP 5.4.8 and later may also provide a fourth
72
-
optional argument, which will contain the
73
-
<parameter>description</parameter> given to <function>assert</function>, if
74
-
it was set.
44
+
The behaviour of <function>assert</function> is dictated by the
45
+
following INI settings:
46
+
<table>
47
+
<title>Assert &ConfigureOptions;</title>
48
+
<tgroup cols="4">
49
+
<thead>
50
+
<row>
51
+
<entry>&Name;</entry>
52
+
<entry>&Default;</entry>
53
+
<entry>&Description;</entry>
54
+
<entry>&Changelog;</entry>
55
+
</row>
56
+
</thead>
57
+
<tbody>
58
+
<row>
59
+
<entry><link linkend="ini.zend.assertions">zend.assertions</link></entry>
60
+
<entry><literal>1</literal></entry>
61
+
<entry>
62
+
<simplelist>
63
+
<member>
64
+
<literal>1</literal>: generate and execute code (development mode)
65
+
</member>
66
+
<member>
67
+
<!-- TODO: look up the RFC to figure out why you'd want this -->
68
+
<literal>0</literal>: generate code but jump around it at runtime
69
+
</member>
70
+
<member>
71
+
<literal>-1</literal>: do not generate code (production mode)
72
+
</member>
73
+
</simplelist>
74
+
</entry>
75
+
<entry/>
76
+
</row>
77
+
<row>
78
+
<entry><link linkend="ini.assert.active">assert.active</link></entry>
79
+
<entry>&true;</entry>
80
+
<entry>
81
+
If &false;, <function>assert</function> does not check the expectation
82
+
and returns &true;, unconditionally.
83
+
</entry>
84
+
<entry>
85
+
Deprecated as of PHP 8.3.0.
86
+
</entry>
87
+
</row>
88
+
<row>
89
+
<entry><link linkend="ini.assert.callback">assert.callback</link></entry>
90
+
<entry>&null;</entry>
91
+
<entry>
92
+
<para>
93
+
A user defined function to call when an assertion fails.
94
+
It's signature should be:
95
+
<methodsynopsis role="procedural">
96
+
<type>void</type><methodname>assert_callback</methodname>
97
+
<methodparam><type>string</type><parameter>file</parameter></methodparam>
98
+
<methodparam><type>int</type><parameter>line</parameter></methodparam>
99
+
<methodparam><type>null</type><parameter>assertion</parameter></methodparam>
100
+
<methodparam choice="opt"><type>string</type><parameter>description</parameter></methodparam>
101
+
</methodsynopsis>
102
+
</para>
103
+
</entry>
104
+
<entry>
105
+
<para>
106
+
Prior to PHP 8.0.0, the signature of the callback should be:
107
+
<methodsynopsis role="procedural">
108
+
<type>void</type><methodname>assert_callback</methodname>
109
+
<methodparam><type>string</type><parameter>file</parameter></methodparam>
110
+
<methodparam><type>int</type><parameter>line</parameter></methodparam>
111
+
<methodparam><type>string</type><parameter>assertion</parameter></methodparam>
112
+
<methodparam choice="opt"><type>string</type><parameter>description</parameter></methodparam>
113
+
</methodsynopsis>
114
+
</para>
115
+
<simpara>
116
+
Deprecated as of PHP 8.3.0.
117
+
</simpara>
118
+
</entry>
119
+
</row>
120
+
<row>
121
+
<entry><link linkend="ini.assert.exception">assert.exception</link></entry>
122
+
<entry>&true;</entry>
123
+
<entry>
124
+
If &true; will throw an <classname>AssertionError</classname> if the
125
+
expectation isn't upheld.
126
+
</entry>
127
+
<entry>
128
+
Deprecated as of PHP 8.3.0.
129
+
</entry>
130
+
</row>
131
+
<row>
132
+
<entry><link linkend="ini.assert.bail">assert.bail</link></entry>
133
+
<entry>&false;</entry>
134
+
<entry>
135
+
If &true; will abort execution of the PHP script if the
136
+
expectation isn't upheld.
137
+
</entry>
138
+
<entry>
139
+
Deprecated as of PHP 8.3.0.
140
+
</entry>
141
+
</row>
142
+
<row>
143
+
<entry><link linkend="ini.assert.warning">assert.warning</link></entry>
144
+
<entry>&true;</entry>
145
+
<entry>
146
+
If &true;, will emit an <constant>E_WARNING</constant> if the
147
+
expectation isn't upheld. This INI setting is ineffective if
148
+
<link linkend="ini.assert.exception">assert.exception</link>
149
+
is enabled.
150
+
</entry>
151
+
<entry>
152
+
Deprecated as of PHP 8.3.0.
153
+
</entry>
154
+
</row>
155
+
</tbody>
156
+
</tgroup>
157
+
</table>
75
158
</para>
76
159
</refsect1>
77
160

...
...
@@ -83,17 +166,61 @@
83
166
<term><parameter>assertion</parameter></term>
84
167
<listitem>
85
168
<para>
86
-
The assertion.
169
+
This is any expression that returns a value, which will be executed
170
+
and the result is used to indicate whether the assertion succeeded or failed.
87
171
</para>
172
+

173
+
<warning>
174
+
<para>
175
+
Prior to PHP 8.0.0, if <parameter>assertion</parameter> was a
176
+
<type>string</type> it was interpreted as PHP code and executed via
177
+
<function>eval</function>.
178
+
This string would be passed to the callback as the third argument.
179
+
This behaviour was <emphasis>DEPRECATED</emphasis> in PHP 7.2.0,
180
+
and <emphasis>REMOVED</emphasis> in PHP 8.0.0.
181
+
</para>
182
+
</warning>
88
183
</listitem>
89
184
</varlistentry>
90
185
<varlistentry>
91
186
<term><parameter>description</parameter></term>
92
187
<listitem>
93
188
<para>
189
+
If <parameter>description</parameter> is an instance of
190
+
<classname>Throwable</classname>, it will be thrown only if the
191
+
<parameter>assertion</parameter> is executed and fails.
192
+
<note>
193
+
<para>
194
+
As of PHP 8.0.0, this is done <emphasis>prior</emphasis> to calling
195
+
the potentially defined assertion callback.
196
+
</para>
197
+
</note>
198
+
<note>
199
+
<para>
200
+
As of PHP 8.0.0, the &object; will be thrown regardless of the configuration of
201
+
<link linkend="ini.assert.exception">assert.exception</link>.
202
+
</para>
203
+
</note>
204
+
<note>
205
+
<para>
206
+
As of PHP 8.0.0, the
207
+
<link linkend="ini.assert.bail">assert.bail</link>
208
+
setting has no effect in this case.
209
+
</para>
210
+
</note>
211
+
</para>
212
+
<para>
213
+
If <parameter>description</parameter> is a &string; this message
214
+
will be used if an exception or a warning is emitted.
94
215
An optional description that will be included in the failure message if
95
216
the <parameter>assertion</parameter> fails.
96
217
</para>
218
+
<para>
219
+
If <parameter>description</parameter> is omitted.
220
+
<!-- This does not happen if &null; is passed ... -->
221
+
A default description equal to the source code for the invocation of
222
+
<function>assert</function> is created at compile time.
223
+
</para>
97
224
</listitem>
98
225
</varlistentry>
99
226
</variablelist>
...
...
@@ -103,7 +230,18 @@
103
230
<refsect1 role="returnvalues">
104
231
&reftitle.returnvalues;
105
232
<para>
106
-
&false; if the assertion is false, &true; otherwise.
233
+
<function>assert</function> will always return &true; if at least one of the following is true:
234
+
</para>
235
+
<simplelist>
236
+
<member><literal>zend.assertions=0</literal></member>
237
+
<member><literal>zend.assertions=-1</literal></member>
238
+
<member><literal>assert.exception=1</literal></member>
239
+
<member><literal>assert.bail=1</literal></member>
240
+
<member>A custom exception object is passed to <parameter>description</parameter>.</member>
241
+
</simplelist>
242
+
<para>
243
+
If none of the conditions are true <function>assert</function> will return &true; if
244
+
<parameter>assertion</parameter> is truthy and &false; otherwise.
107
245
</para>
108
246
</refsect1>
109
247

...
...
@@ -120,12 +258,60 @@
120
258
</thead>
121
259
<tbody>
122
260
<row>
123
-
<entry>5.4.8</entry>
261
+
<entry>8.3.0</entry>
124
262
<entry>
125
-
The <parameter>description</parameter> parameter was added. The
126
-
<parameter>description</parameter> is also now provided to a callback
127
-
function in <constant>ASSERT_CALLBACK</constant> mode as the fourth
128
-
argument.
263
+
All <literal>assert.</literal> INI settings have been deprecated.
264
+
</entry>
265
+
</row>
266
+
<row>
267
+
<entry>8.0.0</entry>
268
+
<entry>
269
+
<function>assert</function> will no longer evaluate string arguments, instead they will be
270
+
treated like any other argument. <code>assert($a == $b)</code> should be used instead of
271
+
<code>assert('$a == $b')</code>. The <literal>assert.quiet_eval</literal> &php.ini; directive and
272
+
the <constant>ASSERT_QUIET_EVAL</constant> constant have also been removed, as they would no longer
273
+
have any effect.
274
+
</entry>
275
+
</row>
276
+
<row>
277
+
<entry>8.0.0</entry>
278
+
<entry>
279
+
If <parameter>description</parameter> is an instance of
280
+
<classname>Throwable</classname>, the object is thrown if the assertion
281
+
fails, regardless of the value of
282
+
<link linkend="ini.assert.exception">assert.exception</link>.
283
+
</entry>
284
+
</row>
285
+
<row>
286
+
<entry>8.0.0</entry>
287
+
<entry>
288
+
If <parameter>description</parameter> is an instance of
289
+
<classname>Throwable</classname>, no user callback is called even
290
+
if it set.
291
+
</entry>
292
+
</row>
293
+
<row>
294
+
<entry>8.0.0</entry>
295
+
<entry>
296
+
Declaring a function called <literal>assert()</literal> inside a namespace is
297
+
no longer allowed, and issues <constant>E_COMPILE_ERROR</constant>.
298
+
</entry>
299
+
</row>
300
+
<row>
301
+
<entry>7.3.0</entry>
302
+
<entry>
303
+
Declaring a function called <literal>assert()</literal> inside a namespace
304
+
became deprecated. Such declaration now emits an <constant>E_DEPRECATED</constant>.
305
+
</entry>
306
+
</row>
307
+
<row>
308
+
<entry>7.2.0</entry>
309
+
<entry>
310
+
Usage of a <type>string</type> as the <parameter>assertion</parameter>
311
+
became deprecated. It now emits an <constant>E_DEPRECATED</constant>
312
+
notice when both <link linkend="ini.assert.active">assert.active</link>
313
+
and <link linkend="ini.zend.assertions">zend.assertions</link> are set
314
+
to <literal>1</literal>.
129
315
</entry>
130
316
</row>
131
317
</tbody>
...
...
@@ -136,75 +322,99 @@
136
322

137
323
<refsect1 role="examples">
138
324
&reftitle.examples;
139
-
<para>
140
325
<example>
141
-
<title>Handle a failed assertion with a custom handler</title>
326
+
<title><function>assert</function> example</title>
142
327
<programlisting role="php">
143
328
<![CDATA[
144
329
<?php
145
-
// Active assert and make it quiet
146
-
assert_options(ASSERT_ACTIVE, 1);
147
-
assert_options(ASSERT_WARNING, 0);
148
-
assert_options(ASSERT_QUIET_EVAL, 1);
149
-

150
-
// Create a handler function
151
-
function my_assert_handler($file, $line, $code)
152
-
{
153
-
echo "<hr>Assertion Failed:
154
-
File '$file'<br />
155
-
Line '$line'<br />
156
-
Code '$code'<br /><hr />";
157
-
}
158
-

159
-
// Set up the callback
160
-
assert_options(ASSERT_CALLBACK, 'my_assert_handler');
161
-

162
-
// Make an assertion that should fail
163
-
assert('mysql_query("")');
164
-
?>
330
+
assert(1 > 2);
331
+
echo 'Hi!';
332
+
]]>
333
+
</programlisting>
334
+
<para>
335
+
If assertions are enabled (<link linkend="ini.zend.assertions"><literal>zend.assertions=1</literal></link>)
336
+
the above example will output:
337
+
</para>
338
+
<screen>
339
+
<![CDATA[
340
+
Fatal error: Uncaught AssertionError: assert(1 > 2) in example.php:2
341
+
Stack trace:
342
+
#0 example.php(2): assert(false, 'assert(1 > 2)')
343
+
#1 {main}
344
+
thrown in example.php on line 2
345
+
]]>
346
+
</screen>
347
+
<para>
348
+
If assertions are disabled (<literal>zend.assertions=0</literal> or <literal>zend.assertions=-1</literal>)
349
+
the above example will output:
350
+
</para>
351
+
<screen>
352
+
<![CDATA[
353
+
Hi!
354
+
]]>
355
+
</screen>
356
+
</example>
357
+
<example>
358
+
<title>Using a custom message</title>
359
+
<programlisting role="php">
360
+
<![CDATA[
361
+
<?php
362
+
assert(1 > 2, "Expected one to be greater than two");
363
+
echo 'Hi!';
165
364
]]>
166
365
</programlisting>
366
+
<para>
367
+
If assertions are enabled the above example will output:
368
+
</para>
369
+
<screen>
370
+
<![CDATA[
371
+
Fatal error: Uncaught AssertionError: Expected one to be greater than two in example.php:2
372
+
Stack trace:
373
+
#0 example.php(2): assert(false, 'Expected one to...')
374
+
#1 {main}
375
+
thrown in example.php on line 2
376
+
]]>
377
+
</screen>
378
+
<para>
379
+
If assertions are disabled the above example will output:
380
+
</para>
381
+
<screen>
382
+
<![CDATA[
383
+
Hi!
384
+
]]>
385
+
</screen>
167
386
</example>
168
-
</para>
169
-
<para>
170
387
<example>
171
-
<title>Using a custom handler to print a description</title>
388
+
<title>Using a custom exception class</title>
172
389
<programlisting role="php">
173
390
<![CDATA[
174
391
<?php
175
-
// Active assert and make it quiet
176
-
assert_options(ASSERT_ACTIVE, 1);
177
-
assert_options(ASSERT_WARNING, 0);
178
-
assert_options(ASSERT_QUIET_EVAL, 1);
179
-

180
-
// Create a handler function
181
-
function my_assert_handler($file, $line, $code, $desc = null)
182
-
{
183
-
echo "Assertion failed at $file:$line: $code";
184
-
if ($desc) {
185
-
echo ": $desc";
186
-
}
187
-
echo "\n";
188
-
}
392
+
class ArithmeticAssertionError extends AssertionError {}
189
393

190
-
// Set up the callback
191
-
assert_options(ASSERT_CALLBACK, 'my_assert_handler');
192
-

193
-
// Make an assertion that should fail
194
-
assert('2 < 1');
195
-
assert('2 < 1', 'Two is less than one');
196
-
?>
394
+
assert(1 > 2, new ArithmeticAssertionError("Expected one to be greater than two"));
395
+
echo 'Hi!';
197
396
]]>
198
397
</programlisting>
199
-
&example.outputs;
398
+
<para>
399
+
If assertions are enabled the above example will output:
400
+
</para>
200
401
<screen>
201
402
<![CDATA[
202
-
Assertion failed at test.php:21: 2 < 1
203
-
Assertion failed at test.php:22: 2 < 1: Two is less than one
403
+
Fatal error: Uncaught ArithmeticAssertionError: Expected one to be greater than two in example.php:4
404
+
Stack trace:
405
+
#0 {main}
406
+
thrown in example.php on line 4
407
+
]]>
408
+
</screen>
409
+
<para>
410
+
If assertions are disabled the above example will output:
411
+
</para>
412
+
<screen>
413
+
<![CDATA[
414
+
Hi!
204
415
]]>
205
416
</screen>
206
417
</example>
207
-
</para>
208
418
</refsect1>
209
419

210
420
<refsect1 role="seealso">
...
...
@@ -217,7 +427,6 @@ Assertion failed at test.php:22: 2 < 1: Two is less than one
217
427
</refsect1>
218
428

219
429
</refentry>
220
-

221
430
<!-- Keep this comment at the end of the file
222
431
Local variables:
223
432
mode: sgml
224
433