reference/info/functions/assert.xml
b2cbcaea5b0e967d2b2cc6bbfa631343e49a7c28
...
...
@@ -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,144 @@
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
+
A user defined function to call when an assertion fails.
93
+
It's signature should be:
94
+
<methodsynopsis role="procedural">
95
+
<type>void</type><methodname>assert_callback</methodname>
96
+
<methodparam><type>string</type><parameter>file</parameter></methodparam>
97
+
<methodparam><type>int</type><parameter>line</parameter></methodparam>
98
+
<methodparam><type>null</type><parameter>assertion</parameter></methodparam>
99
+
<methodparam choice="opt"><type>string</type><parameter>description</parameter></methodparam>
100
+
</methodsynopsis>
101
+
</entry>
102
+
<entry>
103
+
Prior to PHP 8.0.0, the signature of the callback should be:
104
+
<methodsynopsis role="procedural">
105
+
<type>void</type><methodname>assert_callback</methodname>
106
+
<methodparam><type>string</type><parameter>file</parameter></methodparam>
107
+
<methodparam><type>int</type><parameter>line</parameter></methodparam>
108
+
<methodparam><type>string</type><parameter>assertion</parameter></methodparam>
109
+
<methodparam choice="opt"><type>string</type><parameter>description</parameter></methodparam>
110
+
</methodsynopsis>
111
+
Deprecated as of PHP 8.3.0.
112
+
</entry>
113
+
</row>
114
+
<row>
115
+
<entry><link linkend="ini.assert.exception">assert.exception</link></entry>
116
+
<entry>&true;</entry>
117
+
<entry>
118
+
If &true; will throw an <classname>AssertionError</classname> if the
119
+
expectation isn't upheld.
120
+
</entry>
121
+
<entry>
122
+
Deprecated as of PHP 8.3.0.
123
+
</entry>
124
+
</row>
125
+
<row>
126
+
<entry><link linkend="ini.assert.bail">assert.bail</link></entry>
127
+
<entry>&false;</entry>
128
+
<entry>
129
+
If &true; will abort execution of the PHP script if the
130
+
expectation isn't upheld.
131
+
</entry>
132
+
<entry>
133
+
Deprecated as of PHP 8.3.0.
134
+
</entry>
135
+
</row>
136
+
<row>
137
+
<entry><link linkend="ini.assert.warning">assert.warning</link></entry>
138
+
<entry>&true;</entry>
139
+
<entry>
140
+
If &true;, will emit an <constant>E_WARNING</constant> if the
141
+
expectation isn't upheld. This INI setting is ineffective if
142
+
<link linkend="ini.assert.exception">assert.exception</link>
143
+
is enabled.
144
+
</entry>
145
+
<entry>
146
+
Deprecated as of PHP 8.3.0.
147
+
</entry>
148
+
</row>
149
+
</tbody>
150
+
</tgroup>
151
+
</table>
75
152
</para>
76
153
</refsect1>
77
154

...
...
@@ -83,17 +160,61 @@
83
160
<term><parameter>assertion</parameter></term>
84
161
<listitem>
85
162
<para>
86
-
The assertion.
163
+
This is any expression that returns a value, which will be executed
164
+
and the result is used to indicate whether the assertion succeeded or failed.
87
165
</para>
166
+

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

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

137
317
<refsect1 role="examples">
138
318
&reftitle.examples;
139
-
<para>
140
319
<example>
141
-
<title>Handle a failed assertion with a custom handler</title>
320
+
<title><function>assert</function> example</title>
142
321
<programlisting role="php">
143
322
<![CDATA[
144
323
<?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
-
?>
324
+
assert(1 > 2);
325
+
echo 'Hi!';
326
+
]]>
327
+
</programlisting>
328
+
<para>
329
+
If assertions are enabled (<link linkend="ini.zend.assertions"><literal>zend.assertions=1</literal></link>)
330
+
the above example will output:
331
+
</para>
332
+
<screen>
333
+
<![CDATA[
334
+
Fatal error: Uncaught AssertionError: assert(1 > 2) in example.php:2
335
+
Stack trace:
336
+
#0 example.php(2): assert(false, 'assert(1 > 2)')
337
+
#1 {main}
338
+
thrown in example.php on line 2
339
+
]]>
340
+
</screen>
341
+
<para>
342
+
If assertions are disabled (<literal>zend.assertions=0</literal> or <literal>zend.assertions=-1</literal>)
343
+
the above example will output:
344
+
</para>
345
+
<screen>
346
+
<![CDATA[
347
+
Hi!
348
+
]]>
349
+
</screen>
350
+
</example>
351
+
<example>
352
+
<title>Using a custom message</title>
353
+
<programlisting role="php">
354
+
<![CDATA[
355
+
<?php
356
+
assert(1 > 2, "Expected one to be greater than two");
357
+
echo 'Hi!';
165
358
]]>
166
359
</programlisting>
360
+
<para>
361
+
If assertions are enabled the above example will output:
362
+
</para>
363
+
<screen>
364
+
<![CDATA[
365
+
Fatal error: Uncaught AssertionError: Expected one to be greater than two in example.php:2
366
+
Stack trace:
367
+
#0 example.php(2): assert(false, 'Expected one to...')
368
+
#1 {main}
369
+
thrown in example.php on line 2
370
+
]]>
371
+
</screen>
372
+
<para>
373
+
If assertions are disabled the above example will output:
374
+
</para>
375
+
<screen>
376
+
<![CDATA[
377
+
Hi!
378
+
]]>
379
+
</screen>
167
380
</example>
168
-
</para>
169
-
<para>
170
381
<example>
171
-
<title>Using a custom handler to print a description</title>
382
+
<title>Using a custom exception class</title>
172
383
<programlisting role="php">
173
384
<![CDATA[
174
385
<?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
-
}
386
+
class ArithmeticAssertionError extends AssertionError {}
189
387

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
-
?>
388
+
assert(1 > 2, new ArithmeticAssertionError("Expected one to be greater than two"));
389
+
echo 'Hi!';
197
390
]]>
198
391
</programlisting>
199
-
&example.outputs;
392
+
<para>
393
+
If assertions are enabled the above example will output:
394
+
</para>
200
395
<screen>
201
396
<![CDATA[
202
-
Assertion failed at test.php:21: 2 < 1
203
-
Assertion failed at test.php:22: 2 < 1: Two is less than one
397
+
Fatal error: Uncaught ArithmeticAssertionError: Expected one to be greater than two in example.php:4
398
+
Stack trace:
399
+
#0 {main}
400
+
thrown in example.php on line 4
401
+
]]>
402
+
</screen>
403
+
<para>
404
+
If assertions are disabled the above example will output:
405
+
</para>
406
+
<screen>
407
+
<![CDATA[
408
+
Hi!
204
409
]]>
205
410
</screen>
206
411
</example>
207
-
</para>
208
412
</refsect1>
209
413

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

219
423
</refentry>
220
-

221
424
<!-- Keep this comment at the end of the file
222
425
Local variables:
223
426
mode: sgml
224
427