CakeFest 2024: The Official CakePHP Conference

assert

(PHP 4, PHP 5, PHP 7, PHP 8)

assertアサーションの値を調べる

説明

assert(mixed $assertion, Throwable|string|null $description = null): bool

assert() は expectation の定義を満たします。すなわち、 開発環境やテスト環境では有効であるが、 運用環境では除去されて、まったくコストのかからないアサーションということです。

アサーションは、デバッグ目的にのみ使用するべきです。 アサーションを常に true となる条件を調べる不具合診断に使用し、 true でない場合に何らかのプログラミングエラーを示したり、 extension 関数または特定のシステム制限や機能といった、 特定の機能の存在をチェックするために使用することが可能です。

アサーションは削除するように設定できるため、 入力パラメータのチェックのような通常の実行動作に使用するべきでは ありません。 一般的には、アサーションのチェックを無効にしてもそのコードが正常に動作しなければなりません。

assert()assertion で指定された expectation をチェックします。 それを満たさない場合、この関数の結果は false になり、 assert() の設定に応じて適切な動作をします。

assert() の振る舞いは、以下のINI設定によって制御できます:

Assert 設定オプション
名前 デフォルト 説明 変更履歴
zend.assertions 1
  • 1: コードを生成して実行する (開発モード)
  • 0: コードを生成するが、実行時には読み飛ばす
  • -1: コードを生成しない (運用モード)
 
assert.active true false を指定すると、 assert() は expectation をチェックせず、 無条件に true を返します。 PHP 8.3.0 以降は非推奨
assert.callback null アサーションが失敗した時にコールされるユーザー定義の関数。 シグネチャは以下の形であるべきです:
assert_callback(
    string $file,
    int $line,
    null $assertion,
    string $description = ?
): void
PHP 8.0.0 より前のバージョンでは、 コールバックのシグネチャは以下の形であるべきでした:
assert_callback(
    string $file,
    int $line,
    string $assertion,
    string $description = ?
): void
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

descriptionThrowable のインスタンスの場合、 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.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 descriptionThrowable のインスタンスの場合、 assertion が失敗した場合、 assert.exception の値に関わらず、object がスローされるようになりました。
8.0.0 descriptionThrowable のインスタンスの場合、 たとえ設定されていてもコールバックは呼び出されません。
8.0.0 名前空間の内部で、assert() という名前の関数を宣言することはできなくなりました。 宣言した場合、E_COMPILE_ERROR が発生します。
7.3.0 名前空間の内部で、assert() という名前の関数を宣言することは推奨されなくなりました。 宣言した場合、 E_DEPRECATED が発生するようになっています。
7.2.0 assertionstring を使うことは推奨されなくなりました。 assert.activezend.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!

参考

add a note

User Contributed Notes 2 notes

up
30
hodgman at ali dot com dot au
15 years ago
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.
up
1
sven at rtbg dot de
1 month ago
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!
To Top