(PHP 4, PHP 5, PHP 7, PHP 8)
assert — アサーションの値を調べる
assert() は expectation の定義を満たします。すなわち、 開発環境やテスト環境では有効であるが、 運用環境では除去されて、まったくコストのかからないアサーションということです。
アサーションは、デバッグを支援する目的に使用するべきです。
アサーションを常に true
となる条件を調べる不具合診断に使用し、
true でない場合に何らかのプログラミングエラーを示したり、
extension 関数または特定のシステム制限や機能といった、
特定の機能の存在をチェックするために使用することが可能です。
アサーションは削除するように設定できるため、 入力パラメータのチェックのような通常の実行動作に使用するべきでは ありません。 一般的には、アサーションのチェックを無効にしてもそのコードが正常に動作しなければなりません。
assert() は
assertion
で指定された
expectation をチェックします。
それを満たさない場合、この関数の結果は false
になり、
assert() の設定に応じて適切な動作をします。
assert() の振る舞いは、以下のINI設定によって制御できます:
名前 | デフォルト | 説明 | 変更履歴 |
---|---|---|---|
zend.assertions | 1 |
|
|
assert.active | true |
false を指定すると、
assert() は expectation をチェックせず、
無条件に true を返します。
|
PHP 8.3.0 以降は非推奨 |
assert.callback | null |
アサーションが失敗した時にコールされるユーザー定義の関数。 シグネチャは以下の形であるべきです: |
PHP 8.0.0 より前のバージョンでは、 コールバックのシグネチャは以下の形であるべきでした: PHP 8.3.0 以降は非推奨 |
assert.exception | true |
true を指定すると、expectation を満たさない場合に
AssertionError がスローされます。
|
PHP 8.3.0 以降は非推奨 |
assert.bail | false |
true を指定すると、expectation を満たさない場合に
PHP スクリプトの実行を停止します。
|
PHP 8.3.0 以降は非推奨 |
assert.warning | true |
true を指定すると、expectation を満たさない場合に
E_WARNING が発生します。
このINI設定は
assert.exception
が有効な場合は意味がありません。
|
PHP 8.3.0 以降は非推奨 |
assertion
値を返すあらゆる式を指定できます。 この式を実行した結果を用いて、アサーションに成功したか否かを判断します。
PHP 8.0.0 より前のバージョンでは、
assertion
に文字列を指定すると、
PHP コードとして解釈され、
eval() 経由で実行されていました。
この文字列はコールバックの3番目の引数として渡されていました。
この振る舞いは PHP 7.2.0 以降では
非推奨 になり、
PHP 8.0.0 で 削除されました。
description
description
が
Throwable のインスタンスの場合、
assertion
が実行され、
かつ失敗した場合にスローされます。
注意:
PHP 8.0.0 以降では、 定義済みのアサーションのコールバックがコールされる 前 に上の処理は行われます。
注意:
PHP 8.0.0 以降では、 assert.exception の設定に関わらず、object がスローされます。
注意:
例外がスローされる場合、 PHP 8.0.0 以降では、 assert.bail は意味がありません。
description
が文字列の場合、
例外や警告が発生した場合にここで指定したメッセージを使います。
assertion
が失敗したときのオプションのメッセージを指定します。
description
は省略できます。
デフォルトの値は、assert()
を呼び出したソースコードと同じです。この値はコンパイル時に生成されます。
assert() は、以下のうちのひとつが当てはまる場合、常に true
を返します:
zend.assertions=0
zend.assertions=-1
assert.active=0
assert.exception=1
assert.bail=1
description
に渡された場合
上記の条件がすべて当てはまらない場合でも、
assertion
が真と評価できる値であれば true
を返します。
そうでない場合、false
を返します。
バージョン | 説明 |
---|---|
8.3.0 |
すべての assert. INI 設定は、推奨されなくなりました。
|
8.0.0 |
assert() は、文字列の引数を評価しなくなりました。
代わりに、他の引数と同じ扱いをされるようになっています。
assert('$a == $b') ではなく、assert($a == $b)
を使うべきです。 php.ini ディレクティブ
assert.quiet_eval と定数
ASSERT_QUIET_EVAL も削除されており、
それらを使っても何も起きなくなっています。
|
8.0.0 |
description が
Throwable のインスタンスの場合、
assertion が失敗した場合、
assert.exception
の値に関わらず、object がスローされるようになりました。
|
8.0.0 |
description が
Throwable のインスタンスの場合、
たとえ設定されていてもコールバックは呼び出されません。
|
8.0.0 |
名前空間の内部で、assert()
という名前の関数を宣言することはできなくなりました。
宣言した場合、E_COMPILE_ERROR が発生します。
|
7.3.0 |
名前空間の内部で、assert()
という名前の関数を宣言することは推奨されなくなりました。
宣言した場合、 E_DEPRECATED が発生するようになっています。
|
7.2.0 |
assertion に string
を使うことは推奨されなくなりました。
assert.active
と zend.assertions
が両方 1 に設定されると
E_DEPRECATED
レベルの警告が発生するようになりました。
|
例1 assert() の例
<?php
assert(1 > 2);
echo 'Hi!';
アサーションが有効になっている (zend.assertions=1
) 場合は、上の例の結果は次のようになります:
Fatal error: Uncaught AssertionError: assert(1 > 2) in example.php:2 Stack trace: #0 example.php(2): assert(false, 'assert(1 > 2)') #1 {main} thrown in example.php on line 2
アサーションが無効になっている (zend.assertions=0
または zend.assertions=-1
) 場合は、上の例の結果は次のようになります:
Hi!
例2 カスタムのメッセージを使う
<?php
assert(1 > 2, "Expected one to be greater than two");
echo 'Hi!';
アサーションが有効になっている場合は、上の例の結果は次のようになります:
Fatal error: Uncaught AssertionError: Expected one to be greater than two in example.php:2 Stack trace: #0 example.php(2): assert(false, 'Expected one to...') #1 {main} thrown in example.php on line 2
アサーションが無効になっている場合は、上の例の結果は次のようになります:
Hi!
例3 カスタムの例外クラスを使う
<?php
class ArithmeticAssertionError extends AssertionError {}
assert(1 > 2, new ArithmeticAssertionError("Expected one to be greater than two"));
echo 'Hi!';
アサーションが有効になっている場合は、上の例の結果は次のようになります:
Fatal error: Uncaught ArithmeticAssertionError: Expected one to be greater than two in example.php:4 Stack trace: #0 {main} thrown in example.php on line 4
アサーションが無効になっている場合は、上の例の結果は次のようになります:
Hi!
As noted on Wikipedia - "assertions are primarily a development tool, they are often disabled when a program is released to the public." and "Assertions should be used to document logically impossible situations and discover programming errors— if the 'impossible' occurs, then something fundamental is clearly wrong. This is distinct from error handling: most error conditions are possible, although some may be extremely unlikely to occur in practice. Using assertions as a general-purpose error handling mechanism is usually unwise: assertions do not allow for graceful recovery from errors, and an assertion failure will often halt the program's execution abruptly. Assertions also do not display a user-friendly error message."
This means that the advice given by "gk at proliberty dot com" to force assertions to be enabled, even when they have been disabled manually, goes against best practices of only using them as a development tool.
With the current changes made in PHP 8.3 (deprecating the INI settings affecting assertions) and the increasing amount of open source libraries utilizing `assert()` as an easy means to ensure obscure return cases of PHP core function calls are in fact not triggered (e.g. no NULL or FALSE has been returned, but the useful value), the comment made about assertions only being a tool used during development should be considered invalid.
In addition, static code analysis tools use the knowledge gained from `assert($x instanceof MyClass)` to know the type or types that are possible.
Assertions are actively being used in production code, they are useful, and disabling them would only gain minimal performance benefits because the asserted expression usually is very small.
Use this tool where applicable!