trigger_error
(PHP 4 >= 4.0.1, PHP 5, PHP 7, PHP 8)
trigger_error — ユーザーレベルのエラー/警告/通知メッセージを生成する
説明
ユーザーエラーを発生させるために使います。組み込みのエラーハンドラまたは新しいエラーハンドラ (set_error_handler()) として設定済みのユーザー定義関数と組み合わせて使うこともできます。
この関数は、実行時の例外に特定の応答を生成する必要がある場合に便利です。
パラメータ
message
-
このエラーに割り当てられたメッセージ。長さは最大 1024 バイトまでです。1024 バイトを超える部分は切り捨てられます。
error_level
-
このエラーに割り当てられたエラー型です。
E_USER_*
の定数のみが指定可能で、デフォルトはE_USER_NOTICE
です。警告error_level
としてE_USER_ERROR
を指定するのは非推奨となりました。 かわりに、Exception をスローするか、 exit() を呼び出してください。
戻り値
常に true
を返します。
エラー / 例外
error_level
が
E_USER_ERROR
, E_USER_WARNING
,
E_USER_NOTICE
, E_USER_DEPRECATED
のいずれかでない場合、この関数は ValueError
をスローします。
変更履歴
バージョン | 説明 |
---|---|
8.4.0 |
error_level として
E_USER_ERROR を指定するのは非推奨となりました。
かわりに、Exception をスローするか、
exit() を呼び出してください。
|
8.4.0 | 戻り値の型が、bool ではなく true に変更されました。 |
8.0.0 |
不正な error_level
を指定すると、ValueError をスローするようになりました。
これより前のバージョンでは、false を返していました。
|
例
例1 trigger_error() の例
より拡張した例については set_error_handler() を参照ください。
<?php
$password = $_POST['password'] ?? '';
if ($password === '') {
trigger_error("空のパスワードを使用することは安全ではありません", E_USER_WARNING);
}
$hash = password_hash($password, PASSWORD_DEFAULT);
?>
注意
message
の HTML エンティティはエスケープされません。エラーをブラウザに表示するのであれば、メッセージに htmlentities() を使います。
参考
- error_reporting() - 出力する PHP エラーの種類を設定する
- set_error_handler() - ユーザー定義のエラーハンドラ関数を設定する
- restore_error_handler() - 以前のエラーハンドラ関数を回復する
- エラーレベル定数
- Deprecated アトリビュート
User Contributed Notes 6 notes
the idea is never to give out file names, line numbers, and cryptic codes to the user. Use trigger_error() after you used set_error_handler() to register your own callback function which either logs or emails the error codes to you, and echo a simple friendly message to the user.
And turn on a more verbose error handler function when you need to debug your scripts. In my init.php scripts I always have:
if (_DEBUG_) {
set_error_handler ('debug_error_handler');
}
else {
set_error_handler ('nice_error_handler');
}
Beware, trigger_error() is absolutely useless for transporting your own function's error messages in $php_errormsg:
ini_set('track_errors', TRUE);
function x() { trigger_error('MY ERROR'); }
@x();
echo "Error 1: \\"$php_errormsg\\"\\n";
@file_get_contents('/nonexisting');
echo "Error 2: \\"$php_errormsg\\"\\n";
This outputs:
Error 1: ""
Error 2: "failed to open stream: No such file or directory"
This behaviour is consistent with the description of $php_errormsg, which says that the variable will only be available within the scope in which the error occurred. The problem can be worked around with a custom error handler like the one below. However, I'm undecided whether changing the language in this way is good:
function errHandler($errno, $errstr, $errfile, $errline) {
global $php_errormsg; $php_errormsg = $errstr;
}
set_error_handler('errHandler');
trigger_error always reports the line and file that trigger_error was called on. Which isn't very useful.
eg:
main.php:
<?php
include('functions.php');
$x = 'test';
doFunction($x);
?>
functions.php:
<?php
function doFunction($var) {
if(is_numeric($var)) {
/* do some stuff*/
} else {
trigger_error('var must be numeric');
}
}
?>
will output "Notice: var must be numeric in functions.php on line 6"
whereas "Notice: var must be numeric in main.php on line 4" would be more useful
here's a function to do that:
<?php
function error($message, $level=E_USER_NOTICE) {
$caller = next(debug_backtrace());
trigger_error($message.' in <strong>'.$caller['function'].'</strong> called from <strong>'.$caller['file'].'</strong> on line <strong>'.$caller['line'].'</strong>'."\n<br />error handler", $level);
}
?>
So now in our example:
main.php:
<?php
include('functions.php');
$x = 'test';
doFunction($x);
?>
functions.php:
<?php
function doFunction($var) {
if(is_numeric($var)) {
/* do some stuff*/
} else {
error('var must be numeric');
}
}
function error($message, $level=E_USER_NOTICE) {
$caller = next(debug_backtrace());
trigger_error($message.' in <strong>'.$caller['function'].'</strong> called from <strong>'.$caller['file'].'</strong> on line <strong>'.$caller['line'].'</strong>'."\n<br />error handler", $level);
}
?>
now outputs:
"Notice: var must be numeric in doFunction called from main.php on line 4"
For those of you looking to use your own file or line number in the error (possibly using debug_backtrace()) instead of the ones created by trigger_error(), here is a solution:
Create a custom function to handle E_USER_ERRORs that simply outputs the error type and message, while excluding the line number and file trigger_error() reports. You may also configure it to handle user warnings and notices if necessary (I did in the example below).
<?php
function error_handler($level, $message, $file, $line, $context) {
//Handle user errors, warnings, and notices ourself
if($level === E_USER_ERROR || $level === E_USER_WARNING || $level === E_USER_NOTICE) {
echo '<strong>Error:</strong> '.$message;
return(true); //And prevent the PHP error handler from continuing
}
return(false); //Otherwise, use PHP's error handler
}
function trigger_my_error($message, $level) {
//Get the caller of the calling function and details about it
$callee = next(debug_backtrace());
//Trigger appropriate error
trigger_error($message.' in <strong>'.$callee['file'].'</strong> on line <strong>'.$callee['line'].'</strong>', $level);
}
//Use our custom handler
set_error_handler('error_handler');
//-------------------------------
//Demo usage:
//-------------------------------
function abc($str) {
if(!is_string($str)) {
trigger_my_error('abc() expects parameter 1 to be a string', E_USER_ERROR);
}
}
abc('Hello world!'); //Works
abc(18); //Error: abc() expects parameter 1 to be a string in [FILE].php on line 31
?>
This is a pretty simple concept and I'm sure most of you know this, but for those that don't, let it serve as a good example!
If error_type is E_USER_ERROR then trigger_error throw FATAL ERROR and script stopped after this line.
<?php
$msg = 'This is the test message for echo';
trigger_error('Error message', E_USER_ERROR); // Script stopped after this line...
echo $msg; // This line does not appear...
?>
The function trigger_error will terminate the script if $error_level is equal or higher than E_USER_ERROR.
If you write your own error handler you will have to do these yourself.
Example in which we assume the global LOG constant points to a PSR2 logging interface.
<?php
set_error_handler( function ($errno, $errstr, $errfile, $errline) {
// error was suppressed with the @-operator
if( 0 === error_reporting() ) {
return false;
}
switch($errno) {
default:
LOG->error( "Unknown error type: [$errno] $errstr", [ 'file' => $errfile, '@' => $errline ] );
exit(1);
case E_USER_ERROR: // fall through
case E_WARNING: // treat PHP warnings are errors
LOG->error( $errstr, [ 'file' => $errfile, '@' => $errline ] );
exit(1);
case E_USER_DEPRECATED:
case E_DEPRECATED:
LOG->error( "DEPRECATED $errstr", [ 'file' => $errfile, '@' => $errline ] );
break;
case E_USER_WARNING: // fall through
case E_NOTICE: // treat PHP notices are warnings
LOG->warning( $errstr, [ 'file' => $errfile, '@' => $errline ] );
break;
case E_USER_NOTICE:
LOG->notice( $errstr, [ 'file' => $errfile, '@' => $errline ] );
break;
case E_ERROR: // fall through
case E_RECOVERABLE_ERROR:
LOG->critical( $errstr, [ 'file' => $errfile, '@' => $errline ] );
exit(1);
}
/* Don't execute PHP internal error handler */
return true;
} );
?>