導入
煽りタイトルすいません.PHP 7 のエラーや標準例外について,違いを整理し,使い分けを考察する記事です.
【引用】 PHP 7.0.0α2 の例外の例外の継承関係を可視化してみた by @ngyuki
すべてを捕捉対象にする [Throwable
]
[Throwable
] は, PHP 7 の throw
文でスロー可能なあらゆるオブジェクトが実装する基底インターフェイスです. [Error
] および [Exception
] はこれを実装しています.但し,PHPコードとして書かれるクラスが [Throwable
] インターフェイスを直接実装することはできません.
とりあえず catch
句に [Throwable
] と書いておけば,そのブロック内でスローされた [Error
] と [Exception
] を捕捉できることが保証されます.
try {
...
} catch (\Throwable $e) {
...
}
但し, [Error
] を捕捉する必要性があるのは,「フレームワークを自作していて,エラー時にもHTMLレンダリングを可能な限り行いたい」など,極めて限定的な場合です.もしリソースの解放などを確実に行いたい場合には finally
句を使うのが正解です.
try {
...
} catch (\Throwable $e) {
unlink('/tmp/tmp.txt');
throw $e;
}
try {
...
} finally {
unlink('/tmp/tmp.txt');
}
エラー / [Exception
] / [Error
] / [ErrorException
]
以上4点の違いや使い分けについて言及します.
旧来のエラー
PHPには主に以下のようなエラーがあります. (これで全てではありません)
E_PARSE (別名: Parse Error, Syntax Error, 文法エラー)
コードが文法的に誤っているときに発生します.一切の処理を行いません.
E_ERROR (別名: Fatal Error, 致命的なエラー)
処理を継続することが不可能になってしまった場合に発生します.発生したところで処理を停止します.これが発生するリスクを持つコードを書いてはいけません.
E_WARNING (別名: Warning, 警告)
処理を継続することは可能ですが,想定外の問題が起こったときに発生します.これが発生するリスクを持つコードは可能な限り書かないでおくべきです.
E_NOTICE (別名: Notice, 通知)
処理を継続することは可能ですが,想定内の問題が起こったときに発生します.これは手を抜いて無視する人と丁寧に対応する人に二分されますが,対応の仕方を知らないまま手抜きをするようなプログラマになってはならないと私は考えるので,ここでは徹底的に対応することにします.
このようなエラーは,PHP処理系内部で発生します.困ったことに,後述する特殊な変換処理を設定しないかぎりは,catch 句で捕捉することができません.「旧来のエラー」は [Throwable
] ではありません.本来ならば全てのエラーは [Throwable
] のもとに体系化されるべきなのですが,これは例外が実装されていなかった時代の名残です.
PHP処理系が持つ標準関数との互換性を強く意識したPHPコードでは,「旧来のエラー」を [trigger_error
] 関数を用いてPHPレベルで能動的に発生させることもあります.
[Exception
]
[Error
] や [Throwable
] が実装される前の PHP 5 時代には, [Throwable
] の代わりにすべての頂点にいたクラスです. [Throwable
] の実装には [Error
] と [Exception
] の2種類がありますが,能動的にスローする際には,普通のPHPコードとして書かれるものはすべて [Exception
] あるいはその継承クラスを使うべきです.
[Error
]
PHP 7 から新設されたクラスです. [Error
] というクラス名になっていますが,「旧来のエラー」とは取り扱いが全く異なるものです. [Exception
] とは対極に, PHP処理系内部あるいはPHP処理系が持つ標準関数との互換性を強く意識したPHPコードで用いられます. PHP 7 以降は [trigger_error
] 関数との使い分けに悩む気もしますが, PHP 5 時代の実装のバックポートには [trigger_error
] 関数が, PHP 7 時代の実装のバックポートには [Error
] が使われるでしょう.
[ErrorException
]
[set_error_handler
] 関数と併用して,先述の「特殊な変換処理」で変換するためだけに存在するクラスです.非常に名前がややこしいですが, [ErrorException
] はあくまで [Exception
] の一部であって, PHP 7 から新設された [Error
] とは無関係です. [ErrorException
] は「旧来のエラーから変換される [Exception
] 」という意味です.
【引用】 set_error_handler
と ErrorException
を組み合わせると幸せになるかも
set_error_handler(function($severity, $message, $file, $line) { throw new ErrorException($message, 0, $severity, $file, $line); });
但し,ここで設定したハンドラは Fatal Error を受け取ることができず,どうしてもそれに対処したい場合は [register_shutdown_function
] を使って「最後の悪あがき」をする程度しか方法がありません.
register_shutdown_function(function () {
$error = error_get_last();
if (!$error || !($error['type'] & (E_ERROR | E_PARSE | E_USER_ERROR | E_RECOVERABLE_ERROR))) {
return;
}
/* 最後の悪あがきをする */
});
※ E_RECOVERABLE_ERROR
(別名 Catchable Fatal Error) は [ErrorException
] に変換可能な E_ERROR
相当のもので, [set_error_handler
] での設定が無い場合には E_ERROR
と同様の扱いになります.PHP 5.2 から一部の E_ERROR
が E_RECOVERABLE_ERROR
に変更されています.
※ PHP 7 では E_WARNING
E_ERROR
E_RECOVERABLE_ERROR
E_PARSE
の一部が [Error
] に変更されています.
要約すると…
[set_error_handler
] なしの場合
- そのまま続行可能な旧来のエラー
→E_NOTICE
E_WARNING
E_USER_NOTICE
E_USER_WARNING
- 実行が停止する旧来のエラー
→E_ERROR
E_PARSE
E_RECOVERABLE_ERROR
E_USER_ERROR
-
catch
句で捕捉できるもの
→ [Error
] [Exception
]
[set_error_handler
] ありの場合
- 実行が停止する旧来のエラー
→E_ERROR
E_PARSE
E_USER_ERROR
-
catch
句で捕捉できるもの
→ [Error
] [Exception
]
( [Exception
] にはE_NOTICE
E_WARNING
E_USER_NOTICE
E_RECOVERABLE_ERROR
変換後の [ErrorException
] が含まれる)
[LogicException
] / [RuntimeException
]
PHPプログラマ向けに提供されている [Exception
] の継承クラスとして, [LogicException
] と [RuntimeException
] があります.いろいろな記事で何回も言われていることですが,以下のような使い分けを行うべきです.
-
[
LogicException
] … 自身のコード,あるいはそれを利用している第三者のコードにバグがあることを示す例外. -
[
RuntimeException
] … 正しく取り扱っていても起こりうる例外.
以下では,これらを継承しているクラスの使い分けについて言及します.
[BadFunctionCallException
] / [BadMethodCallException
]
これは説明するほどでもないですね.
クラス名 | 継承元 | 利用シーン |
---|---|---|
[BadFunctionCallException ] |
[LogicException ] |
関数が未実装である場合, あるいは内部状態的に実行してはいけないタイミングで実行された場合の例外. |
[BadMethodCallException ] |
[LogicException ] |
メソッドが未実装である場合, あるいは内部状態的に実行してはいけないタイミングで実行された場合の例外. |
class Klass
{
public function __sleep()
{
throw new \BadMethodCallException('serialization is not supported');
}
}
serialize(new Klass); // BadMethodCallException
[OverflowException
] / [UnderflowException
]
マニュアルによれば,コンテナの「オーバーフロー」「アンダーフロー」にそのまま対応するようです.数値計算のオーバーフローがこれに当てはまるかは…どうだろう?
クラス名 | 継承元 | 利用シーン |
---|---|---|
[OverflowException ] |
[RuntimeException ] |
コンテナのオーバーフロー時の例外. |
[UnderflowException ] |
[RuntimeException ] |
コンテナのアンダーフロー時の例外. |
class Stack
{
private $elements = [];
private $size;
public function __construct(int $size)
{
if ($size < 1) {
throw new \LengthException("\$size must be positive integer, $size given");
}
$this->size = $size;
}
public function push($value)
{
if (count($elements) >= $size) {
throw new \OverflowException('container is full');
}
$this->elements[] = $value;
}
public function pop()
{
if (empty($this->elements)) {
throw new \UnderflowException('container is empty');
}
return array_pop($this->elements);
}
}
[DomainException
] / [InvalidArgumentException
] / [LengthException
] / [OutOfRangeException
] / [OutOfBoundsException
] / [RangeException
] / [UnexpectedValueException
]
さぁ,見るからにここが一番混沌としています.正直なところ,今から書く説明があっているかどうかすら怪しいです…
[LogicException
] と [RuntimeException
] の分類ではなく,例外の内容で分類することにします.
引数や返り値のバリデーションを手広く行うもの
クラス名 | 継承元 | 利用シーン |
---|---|---|
[DomainException ] |
[LogicException ] |
型は合っているが,想定している いくつかの取りうる値のどれにも該当しなかった場合の例外. 自分を含め,[ InvalidArgumentException ]と一緒くたにされている気がするけど,もうちょっと使ってあげよう. |
[RangeException ] |
[RuntimeException ] |
型は合っているが,想定している いくつかの取りうる値のどれにも該当しなかった場合の例外. [ DomainException ]の実行時版. |
[InvalidArgumentException ] |
[LogicException ] |
引数の型が間違っている場合の例外. スカラータイプヒントおよび[ TypeError ]がPHP 7 から導入されたので,今後出番は減っていきそう… |
[UnexpectedValueException ] |
[RuntimeException ] |
返り値の型が想定外であった場合の例外. 引数はコンパイル時エラーでだいたい検出可能, 返り値は実行時でなければ検出できない …というスタンスで[ InvalidArgumentException ]と対になるのだろうか? |
コンテナへのアクセスのバリデーションを行うもの
クラス名 | 継承元 | 利用シーン |
---|---|---|
[OutOfRangeException ] |
[LogicException ] |
固定長であるコンテナのオフセットを無視したアクセスがあった場合の例外. 専ら[ SplFixedArray ],あるいはそれを踏襲した実装のために存在するようなもの. |
[OutOfBoundsException ] |
[RuntimeException ] |
可変長であるコンテナのオフセット, またはインデックスを無視したアクセスがあった場合の例外. マニュアルによると[ DomainException ]の実行時版であるらしいが,個人的には[ OutOfRangeException ]の実行時版のように思える. |
分類しづらいもの
クラス名 | 継承元 | 利用シーン |
---|---|---|
[LengthException ] |
[LogicException ] |
専ら「長さ」「大きさ」を表す自然数を バリデーションしたいときに使いそう. |
おまけ: バージョン別・エラーや例外の具体例
PHP 5.0 ~ 5.1 の検証は省略し,手元にある 5.5.34 および 7.0.9 で検証することにします.
<?php
function test($version, $code, $strict = false)
{
$trapped_code = ($strict ? 'declare(strict_types=1);' : '') . '
function preg_grep_keys($pattern, $input, $flags = 0) {
return array_intersect_key(
$input,
array_flip(preg_grep($pattern, array_keys($input), $flags))
);
}
set_error_handler(function ($errno, $errstr) use (&$cancel) {
$cancel = true;
$consts = array_flip(preg_grep_keys("/\AE_/", get_defined_constants()));
echo json_encode([
"type" => "`{$consts[$errno]}`",
"message" => $errstr,
]);
exit;
});
register_shutdown_function(function () use (&$cancel) {
if ($cancel || !$e = error_get_last()) return;
$consts = array_flip(preg_grep_keys("/\AE_/", get_defined_constants()));
echo json_encode([
"type" => "`{$consts[$e["type"]]}`",
"message" => $e["message"],
]);
});
try {
' . $code . '
} catch (\Exception $e) {
$cancel = true;
echo json_encode([
"type" => "[`" . get_class($e) ."`]",
"message" => $e->getMessage(),
]);
} catch (\Throwable $e) {
$cancel = true;
echo json_encode([
"type" => "[`" . get_class($e) ."`]",
"message" => $e->getMessage(),
]);
}
';
$error = json_decode(shell_exec(implode(' ', [
$version < 7 ? '/usr/bin/php' : '/usr/local/bin/php',
'-d error_reporting=-1',
'-d display_errors=0',
'-d log_errors=0',
'-r ' . escapeshellarg($trapped_code),
])));
return $error;
}
function escape_ascii($str)
{
return preg_replace_callback('/[\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]/', function ($m) {
return '&#' . ord($m[0]) . ';';
}, $str);
}
function build(array $items)
{
$tables = [
'|No.|概要|PHP 5.5.34|PHP 7.0.9| PHP 7.0.9 (strict)|',
'|:--|:--|:--|:--|:--|',
];
$codes = [];
$i = 0;
foreach ($items as $name => $code) {
$code = trim($code);
$err5 = test(5, $code);
$err7 = test(7, $code);
$err7s = test(7, $code, true);
$tables[] = sprintf('|%s|%s|%s|%s|%s|',
++$i,
$name,
$err5->type ?? '',
$err7->type ?? '',
$err7s->type ?? ''
);
$codes[] = implode("\n", [
'```php:' . escape_ascii("No.$i $name"),
$code,
'/*',
'PHP 5.5.34 : ' . ($err5->message ?? ''),
'PHP 7.0.9 : ' . ($err7->message ?? ''),
'PHP 7.0.9 (strict): ' . ($err7s->message ?? ''),
'*/',
'```'
]);
}
return implode("\n", $tables) . "\n\n" . implode("\n\n", $codes) . "\n";
}
echo build([
'未定義の変数の評価'
=> '
$undefined . "";
',
'未定義のグローバル定数の評価'
=> '
UNDEFINED . "";
',
'未定義の配列オフセットの評価'
=> '
$ary = [];
$ary[0] . "";
',
'未定義の連想配列インデックスの評価'
=> '
$asc = [];
$asc["undefined"] . "";
',
'未定義のインスタンスプロパティの評価'
=> '
$obj = new stdClass;
$obj->undefined . "";
',
'未定義の静的プロパティの評価'
=> '
$obj = new stdClass;
$obj::$undefined . "";
',
'未定義のクラス定数の評価'
=> '
$obj = new stdClass;
$obj::UNDEFINED . "";
',
'クラス経由でのインスタンスプロパティへのアクセス'
=> '
class Klass
{
public $prop;
}
Klass::$prop;
',
'アクセス権限のないプロパティへのアクセス'
=> '
class Klass
{
private static $prop;
}
Klass::$prop;
',
'ゼロ除算'
=> '
1 / 0;
',
'ゼロ剰余算'
=> '
1 % 0;
',
'マイナスのビットシフト'
=> '
1 << -1;
',
'配列と文字列の結合' => '
$ary = [];
$ary . ""; // PHP 7 のコンパイル時エラー回避
',
'配列変数と整数の加算' => '
$ary = [];
$ary + 1; // PHP 7 のコンパイル時エラー回避
',
'配列リテラルと整数の加算' => '
eval("[] + 1;"); // PHP 7 のコンパイル時エラー回避
',
'配列のオフセットの型間違い' =>'
$ary = [];
$ary[[]] . "";
',
'__toString()未実装時の文字列キャスト' =>'
$obj = new stdClass;
(string)$obj;
',
'__toString()の中でスローされる例外' =>'
class Klass
{
public function __toString()
{
throw new \Exception;
}
}
$obj = new Klass;
(string)$obj;
',
'__clone()の直接実行' =>'
class Klass
{
public function __clone()
{
return new self;
}
}
$obj = new Klass;
eval("\$obj->__clone();");// PHP 5 のコンパイル時エラー回避
',
'ArrayAccess未実装時の配列形式アクセス' =>'
$obj = new stdClass;
$obj[0] = 1;
',
'ユーザ定義関数のタイプヒンティングの無視' => '
function func(stdClass $obj) { }
func(1);
',
'ユーザ定義関数の引数不足' => '
function func($a) { }
func();
',
'組み込み関数のタイプ指定無視' => '
strlen([]);
',
'組み込み関数の引数不足' => '
strlen();
',
'組み込み関数の引数余剰' => '
strlen("", "");
',
'アサーションの失敗 (assert.exception=0)' => '
assert(false);
',
'アサーションの失敗 (assert.exception=1)' => '
ini_set("assert.exception", "1");
assert(false);
',
'foreachの型間違い' => '
$num = 1;
foreach ($num as $k => $v);
',
]);
No. | 概要 | PHP 5.5.34 | PHP 7.0.9 | PHP 7.0.9 (strict) |
---|---|---|---|---|
1 | 未定義の変数の評価 | E_NOTICE |
E_NOTICE |
E_NOTICE |
2 | 未定義のグローバル定数の評価 | E_NOTICE |
E_NOTICE |
E_NOTICE |
3 | 未定義の配列オフセットの評価 | E_NOTICE |
E_NOTICE |
E_NOTICE |
4 | 未定義の連想配列インデックスの評価 | E_NOTICE |
E_NOTICE |
E_NOTICE |
5 | 未定義のインスタンスプロパティの評価 | E_NOTICE |
E_NOTICE |
E_NOTICE |
6 | 未定義の静的プロパティの評価 | E_ERROR |
[Error ] |
[Error ] |
7 | 未定義のクラス定数の評価 | E_ERROR |
[Error ] |
[Error ] |
8 | クラス経由でのインスタンスプロパティへのアクセス | E_ERROR |
[Error ] |
[Error ] |
9 | アクセス権限のないプロパティへのアクセス | E_ERROR |
[Error ] |
[Error ] |
10 | ゼロ除算 | E_WARNING |
E_WARNING |
E_WARNING |
11 | ゼロ剰余算 | E_WARNING |
[DivisionByZeroError ] |
[DivisionByZeroError ] |
12 | マイナスのビットシフト | [ArithmeticError ] |
[ArithmeticError ] |
|
13 | 配列と文字列の結合 | E_NOTICE |
E_NOTICE |
E_NOTICE |
14 | 配列変数と整数の加算 | E_ERROR |
[Error ] |
[Error ] |
15 | 配列リテラルと整数の加算 | E_ERROR |
E_ERROR |
E_ERROR |
16 | 配列のオフセットの型間違い | E_WARNING |
E_WARNING |
E_WARNING |
17 | __toString()未実装時の文字列キャスト | E_RECOVERABLE_ERROR |
E_RECOVERABLE_ERROR |
E_RECOVERABLE_ERROR |
18 | __toString()の中でスローされる例外 | E_ERROR |
E_ERROR |
E_ERROR |
19 | __clone()の直接実行 | E_COMPILE_ERROR |
||
20 | ArrayAccess未実装時の配列形式アクセス | E_ERROR |
[Error ] |
[Error ] |
21 | ユーザ定義関数のタイプヒンティングの無視 | E_RECOVERABLE_ERROR |
[TypeError ] |
[TypeError ] |
22 | ユーザ定義関数の引数不足 | E_WARNING |
E_WARNING |
E_WARNING |
23 | 組み込み関数のタイプ指定無視 | E_WARNING |
E_WARNING |
[TypeError ] |
24 | 組み込み関数の引数不足 | E_WARNING |
E_WARNING |
[TypeError ] |
25 | 組み込み関数の引数余剰 | E_WARNING |
E_WARNING |
[TypeError ] |
26 | アサーションの失敗 (assert.exception=0) | E_WARNING |
E_WARNING |
E_WARNING |
27 | アサーションの失敗 (assert.exception=1) | E_WARNING |
[AssertionError ] |
[AssertionError ] |
28 | foreachの型間違い | E_WARNING |
E_WARNING |
E_WARNING |
$undefined . "";
/*
PHP 5.5.34 : Undefined variable: undefined
PHP 7.0.9 : Undefined variable: undefined
PHP 7.0.9 (strict): Undefined variable: undefined
*/
UNDEFINED . "";
/*
PHP 5.5.34 : Use of undefined constant UNDEFINED - assumed 'UNDEFINED'
PHP 7.0.9 : Use of undefined constant UNDEFINED - assumed 'UNDEFINED'
PHP 7.0.9 (strict): Use of undefined constant UNDEFINED - assumed 'UNDEFINED'
*/
$ary = [];
$ary[0] . "";
/*
PHP 5.5.34 : Undefined offset: 0
PHP 7.0.9 : Undefined offset: 0
PHP 7.0.9 (strict): Undefined offset: 0
*/
$asc = [];
$asc["undefined"] . "";
/*
PHP 5.5.34 : Undefined index: undefined
PHP 7.0.9 : Undefined index: undefined
PHP 7.0.9 (strict): Undefined index: undefined
*/
$obj = new stdClass;
$obj->undefined . "";
/*
PHP 5.5.34 : Undefined property: stdClass::$undefined
PHP 7.0.9 : Undefined property: stdClass::$undefined
PHP 7.0.9 (strict): Undefined property: stdClass::$undefined
*/
$obj = new stdClass;
$obj::$undefined . "";
/*
PHP 5.5.34 : Access to undeclared static property: stdClass::$undefined
PHP 7.0.9 : Access to undeclared static property: stdClass::$undefined
PHP 7.0.9 (strict): Access to undeclared static property: stdClass::$undefined
*/
$obj = new stdClass;
$obj::UNDEFINED . "";
/*
PHP 5.5.34 : Undefined class constant 'UNDEFINED'
PHP 7.0.9 : Undefined class constant 'UNDEFINED'
PHP 7.0.9 (strict): Undefined class constant 'UNDEFINED'
*/
class Klass
{
public $prop;
}
Klass::$prop;
/*
PHP 5.5.34 : Access to undeclared static property: Klass::$prop
PHP 7.0.9 : Access to undeclared static property: Klass::$prop
PHP 7.0.9 (strict): Access to undeclared static property: Klass::$prop
*/
class Klass
{
private static $prop;
}
Klass::$prop;
/*
PHP 5.5.34 : Cannot access private property Klass::$prop
PHP 7.0.9 : Cannot access private property Klass::$prop
PHP 7.0.9 (strict): Cannot access private property Klass::$prop
*/
1 / 0;
/*
PHP 5.5.34 : Division by zero
PHP 7.0.9 : Division by zero
PHP 7.0.9 (strict): Division by zero
*/
1 % 0;
/*
PHP 5.5.34 : Division by zero
PHP 7.0.9 : Modulo by zero
PHP 7.0.9 (strict): Modulo by zero
*/
1 << -1;
/*
PHP 5.5.34 :
PHP 7.0.9 : Bit shift by negative number
PHP 7.0.9 (strict): Bit shift by negative number
*/
$ary = [];
$ary . ""; // PHP 7 のコンパイル時エラー回避
/*
PHP 5.5.34 : Array to string conversion
PHP 7.0.9 : Array to string conversion
PHP 7.0.9 (strict): Array to string conversion
*/
$ary = [];
$ary + 1; // PHP 7 のコンパイル時エラー回避
/*
PHP 5.5.34 : Unsupported operand types
PHP 7.0.9 : Unsupported operand types
PHP 7.0.9 (strict): Unsupported operand types
*/
eval("[] + 1;"); // PHP 7 のコンパイル時エラー回避
/*
PHP 5.5.34 : Unsupported operand types
PHP 7.0.9 : Unsupported operand types
PHP 7.0.9 (strict): Unsupported operand types
*/
$ary = [];
$ary[[]] . "";
/*
PHP 5.5.34 : Illegal offset type
PHP 7.0.9 : Illegal offset type
PHP 7.0.9 (strict): Illegal offset type
*/
$obj = new stdClass;
(string)$obj;
/*
PHP 5.5.34 : Object of class stdClass could not be converted to string
PHP 7.0.9 : Object of class stdClass could not be converted to string
PHP 7.0.9 (strict): Object of class stdClass could not be converted to string
*/
class Klass
{
public function __toString()
{
throw new \Exception;
}
}
$obj = new Klass;
(string)$obj;
/*
PHP 5.5.34 : Method Klass::__toString() must not throw an exception
PHP 7.0.9 : Method Klass::__toString() must not throw an exception, caught Exception:
PHP 7.0.9 (strict): Method Klass::__toString() must not throw an exception, caught Exception:
*/
class Klass
{
public function __clone()
{
return new self;
}
}
$obj = new Klass;
eval("\$obj->__clone();");// PHP 5 のコンパイル時エラー回避
/*
PHP 5.5.34 : Cannot call __clone() method on objects - use 'clone $obj' instead
PHP 7.0.9 :
PHP 7.0.9 (strict):
*/
$obj = new stdClass;
$obj[0] = 1;
/*
PHP 5.5.34 : Cannot use object of type stdClass as array
PHP 7.0.9 : Cannot use object of type stdClass as array
PHP 7.0.9 (strict): Cannot use object of type stdClass as array
*/
function func(stdClass $obj) { }
func(1);
/*
PHP 5.5.34 : Argument 1 passed to func() must be an instance of stdClass, integer given, called in Command line code on line 27 and defined
PHP 7.0.9 : Argument 1 passed to func() must be an instance of stdClass, integer given, called in Command line code on line 27
PHP 7.0.9 (strict): Argument 1 passed to func() must be an instance of stdClass, integer given, called in Command line code on line 27
*/
function func($a) { }
func();
/*
PHP 5.5.34 : Missing argument 1 for func(), called in Command line code on line 27 and defined
PHP 7.0.9 : Missing argument 1 for func(), called in Command line code on line 27 and defined
PHP 7.0.9 (strict): Missing argument 1 for func(), called in Command line code on line 27 and defined
*/
strlen([]);
/*
PHP 5.5.34 : strlen() expects parameter 1 to be string, array given
PHP 7.0.9 : strlen() expects parameter 1 to be string, array given
PHP 7.0.9 (strict): strlen() expects parameter 1 to be string, array given
*/
strlen();
/*
PHP 5.5.34 : strlen() expects exactly 1 parameter, 0 given
PHP 7.0.9 : strlen() expects exactly 1 parameter, 0 given
PHP 7.0.9 (strict): strlen() expects exactly 1 parameter, 0 given
*/
strlen("", "");
/*
PHP 5.5.34 : strlen() expects exactly 1 parameter, 2 given
PHP 7.0.9 : strlen() expects exactly 1 parameter, 2 given
PHP 7.0.9 (strict): strlen() expects exactly 1 parameter, 2 given
*/
assert(false);
/*
PHP 5.5.34 : assert(): Assertion failed
PHP 7.0.9 : assert(): assert(false) failed
PHP 7.0.9 (strict): assert(): assert(false) failed
*/
ini_set("assert.exception", "1");
assert(false);
/*
PHP 5.5.34 : assert(): Assertion failed
PHP 7.0.9 : assert(false)
PHP 7.0.9 (strict): assert(false)
*/
$num = 1;
foreach ($num as $k => $v);
/*
PHP 5.5.34 : Invalid argument supplied for foreach()
PHP 7.0.9 : Invalid argument supplied for foreach()
PHP 7.0.9 (strict): Invalid argument supplied for foreach()
*/
[SplFixedArray
]: http://www.php.net/manual/ja/class.splfixedarray.php
[register_shutdown_function
]: http://php.net/manual/ja/function.register-shutdown-function.php
[set_error_handler
]: http://php.net/manual/ja/function.set-error-handler.php
[trigger_error
]: http://php.net/manual/ja/function.trigger-error.php
[Throwable
]: http://www.php.net/manual/ja/class.throwable.php
[Exception
]: http://www.php.net/manual/ja/class.exception.php
[ErrorException
]: http://www.php.net/manual/ja/class.errorexception.php
[Error
]: http://www.php.net/manual/ja/class.error.php
[ArithmeticError
]: http://www.php.net/manual/ja/class.arithmeticerror.php
[AssertionError
]: http://www.php.net/manual/ja/class.assertionerror.php
[DivisionByZeroError
]: http://www.php.net/manual/ja/class.divisionbyzeroerror.php
[ParseError
]: http://www.php.net/manual/ja/class.parseerror.php
[TypeError
]: http://www.php.net/manual/ja/class.typeerror.php
[BadFunctionCallException
]: http://www.php.net/manual/ja/class.badfunctioncallexception.php
[BadMethodCallException
]: http://www.php.net/manual/ja/class.badmethodcallexception.php
[DomainException
]: http://www.php.net/manual/ja/class.domainexception.php
[InvalidArgumentException
]: http://www.php.net/manual/ja/class.invalidargumentexception.php
[LengthException
]: http://www.php.net/manual/ja/class.lengthexception.php
[LogicException
]: http://www.php.net/manual/ja/class.logicexception.php
[OutOfBoundsException
]: http://www.php.net/manual/ja/class.outofboundsexception.php
[OutOfRangeException
]: http://www.php.net/manual/ja/class.outofrangeexception.php
[OverflowException
]: http://www.php.net/manual/ja/class.overflowexception.php
[RangeException
]: http://www.php.net/manual/ja/class.rangeexception.php
[RuntimeException
]: http://www.php.net/manual/ja/class.runtimeexception.php
[UnderflowException
]: http://www.php.net/manual/ja/class.underflowexception.php
[UnexpectedValueException
]: http://www.php.net/manual/ja/class.unexpectedvalueexception.php