php 根据通知/警告停止脚本执行

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10520390/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 22:23:24  来源:igfitidea点击:

Stop script execution upon notice/warning

phpconfiguration

提问by Michael

Is it possible to have PHP stop execution upon a notice/warning, globally?

是否可以在全球范围内根据通知/警告停止执行 PHP?

We run a development server with a lot of sites on, but want to force our developers to fix these warnings/notices (or ask for help with them at least) instead of ignoring and moving on.

我们运行了一个有很多站点的开发服务器,但想强迫我们的开发人员修复这些警告/通知(或至少寻求帮助),而不是忽略并继续前进。

回答by rdlowrey

Yes, it is possible. This question speaks to the more general issue of how to handle errors in PHP. You should define and register a custom error handler using set_error_handlerdocsto customize handling for PHP errors.

对的,这是可能的。这个问题涉及如何处理 PHP 中的错误的更普遍的问题。您应该使用set_error_handlerdocs定义和注册自定义错误处理程序来自定义 PHP 错误的处理。

IMHO it's best to throw an exception on any PHP error and use try/catch blocks to control program flow, but opinions differ on this point.

恕我直言,最好对任何 PHP 错误抛出异常并使用 try/catch 块来控制程序流程,但在这一点上存在不同意见。

To accomplish the OP's stated goal you might do something like:

要完成 OP 的既定目标,您可能会执行以下操作:

function errHandle($errNo, $errStr, $errFile, $errLine) {
    $msg = "$errStr in $errFile on line $errLine";
    if ($errNo == E_NOTICE || $errNo == E_WARNING) {
        throw new ErrorException($msg, $errNo);
    } else {
        echo $msg;
    }
}

set_error_handler('errHandle');

The above code will throw an ErrorExceptionany time an E_NOTICEor E_WARNINGis raised, effectively terminating script output (if the exception isn't caught). Throwing exceptions on PHP errors is best combined with a parallel exception handling strategy (set_exception_handler) to gracefully terminate in production environments.

上面的代码会在ErrorException任何时候抛出一个E_NOTICEor E_WARNING,从而有效地终止脚本输出(如果没有捕获到异常)。在 PHP 错误上抛出异常最好与并行异常处理策略 ( set_exception_handler)结合使用,以便在生产环境中正常终止。

Note that the above example will not respect the @error suppression operator. If this is important to you, simply add a check with the error_reporting()function as demonstrated here:

请注意,上面的示例不会考虑@错误抑制运算符。如果这对您很重要,只需使用error_reporting()此处演示的函数添加检查:

function errHandle($errNo, $errStr, $errFile, $errLine) {
    if (error_reporting() == 0) {
        // @ suppression used, don't worry about it
        return;
    }
    // handle error here
}

回答by Tiberiu-Ionu? Stan

As of PHP 5.3.0:

从 PHP 5.3.0 开始:

set_error_handler(
    function(int $nSeverity, string $strMessage, string $strFilePath, int $nLineNumber){
        if(error_reporting()!==0) // Not error suppression operator @
            throw new \ErrorException($strMessage, /*nExceptionCode*/ 0, $nSeverity, $strFilePath, $nLineNumber);
    },
    /*E_ALL*/ -1
);

回答by hakre

You can globally configure this within your php.ini file­Docs.

您可以在全球范围内的配置此php.ini文件-Docs

You do this by specifying a file that is being included by all PHP processes with the auto_prepend_filedirective­Docs:

您通过指定被包括通过与所有PHP进程的一个文件auto_prepend_file指令-Docs

auto_prepend_file "/full/path/to/a/prepend-file.php"

Doing that inside you global php.ini file will ensure that the code inside the prepend file will be always exectued. You can use it then to register a global error handler that will turn all errors into exceptions­Docs:

在全局 php.ini 文件中执行此操作将确保 prepend 文件中的代码将始终执行。您可以使用它,然后注册一个全局错误处理程序,将关闭所有的错误到异常-Docs

<?php
function exception_error_handler($errno, $errstr, $errfile, $errline ) {
    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}
set_error_handler("exception_error_handler");

This little script will turn all errors/warnings/notices etc. into an ErrorException.

这个小脚本会将所有错误/警告/通知等转换为ErrorException.

Combine it with the error_reportingini directive­Docs, the values are describe in your php.ini file.

将它与error_reportingini 指令Docs结合起来这些值在你的 php.ini 文件中描述。

Throwing an exception is a very strict thing. Your programmers will be forced to deal with warnings and errors otherwise the code won't not work.

抛出异常是一件非常严格的事情。您的程序员将被迫处理警告和错误,否则代码将无法运行。

Probably this is too much for your programmers and not socially acceptable within your company. Instead you can also log all errors and add them at the end of the output (or at the top so it's more visible) by making use of output buffering.

可能这对您的程序员来说太过分了,并且在您的公司内不被社会接受。相反,您还可以通过使用输出缓冲来记录所有错误并将它们添加到输出的末尾(或在顶部,以便更明显)。

Another alternative is to log errors and warnings to the logfile and then monitor that file with another process and aggregate the information. You could create a scoreboard that display the number of warnings per application and make this visible in the office so everybody sees how well a team performs or some fun like that.

另一种方法是将错误和警告记录到日志文件中,然后使用另一个进程监视该文件并汇总信息。您可以创建一个记分牌,显示每个应用程序的警告数量,并将其显示在办公室中,以便每个人都能看到团队的表现如何或类似的乐趣。

What I try to say is: Next to the technical problem, it's a social problem you need to be creative with and actually talk the problem out of your developers. You need to make clear why it's important to fix warnings and errors and how their coding and skills will benefit from that.

我想说的是:在技术问题旁边,这是一个社会问题,你需要创造性地解决这个问题,并真正与你的开发人员讨论这个问题。您需要弄清楚为什么修复警告和错误很重要,以及他们的编码和技能将如何从中受益。

回答by hakre

If you are in a development environment, you might consider installing the module Xdebug and set xdebug.halt_level=E_WARNING|E_NOTICE|E_USER_WARNING|E_USER_NOTICEsomewhere in your PHP ini files. The developer can reset xdebug.halt_level, but we have the same issue with the answer based on set_error_handler, because we can restore the handler to its original value.

如果您在开发环境中,您可能会考虑安装模块 Xdebug 并设置xdebug.halt_level=E_WARNING|E_NOTICE|E_USER_WARNING|E_USER_NOTICE在您的 PHP ini 文件中的某个位置。开发人员可以重置xdebug.halt_level,但我们对基于 的答案有同样的问题set_error_handler,因为我们可以将处理程序恢复到其原始值。

回答by leemes

The other solutions implement a custom error handler which overrides the default error logging mechanism. That means when we set a custom error handler, the notice / warning is not printed anymore in the default way, so we change more than just "stop script execution upon notice / warning".

其他解决方案实现了一个自定义错误处理程序,它覆盖了默认的错误记录机制。这意味着当我们设置自定义错误处理程序时,通知/警告不再以默认方式打印,因此我们更改的不仅仅是“在通知/警告时停止脚本执行”。

However, I needed a way to still print the message - in my case in PHP CLI - since the output is then parsed by another program. So I didn't want to print the message in some waybut in the exact same way than PHP usually does it. I justwanted to stopthe PHP CLI process with an exit code of != 0right after a notice / warning was printed, and do not change anything else.

但是,我需要一种方法来仍然打印消息 - 在我的情况下是在 PHP CLI 中 - 因为输出随后被另一个程序解析。所以我不想以某种方式打印消息,而是以与 PHP 通常完全相同的方式打印。我只是想在打印通知/警告后以退出代码停止PHP CLI 进程!= 0,并且不要更改任何其他内容

Unfortunately, there does not seem to be a default way of exiting the script without changing the whole error handling. So I needed to reimplement the default error handler (which is implemented in C) in PHP.

不幸的是,在不更改整个错误处理的情况下,似乎没有退出脚本的默认方式。所以我需要在 PHP 中重新实现默认的错误处理程序(用 C 实现)。

For this, I looked into the default error printing mechanism in PHP's source code and ported the relevant pieces from C to PHP to get the following error handler, which I want to share with you in case you need something similar:

为此,我研究了 PHP 源代码中的默认错误打印机制,并将相关部分从 C 移植到 PHP 以获得以下错误处理程序,如果您需要类似的内容,我想与您分享:

set_error_handler(
    function($errNo, $errStr, $errFile, $errLine) {
        $error_type_str = 'Error';
        // Source of the switch logic: default error handler in PHP's main.c
        switch ($errNo) {
            case E_ERROR:
            case E_CORE_ERROR:
            case E_COMPILE_ERROR:
            case E_USER_ERROR:
                $error_type_str = "Fatal error";
                break;
            case E_RECOVERABLE_ERROR:
                $error_type_str = "Recoverable fatal error";
                break;
            case E_WARNING:
            case E_CORE_WARNING:
            case E_COMPILE_WARNING:
            case E_USER_WARNING:
                $error_type_str = "Warning";
                break;
            case E_PARSE:
                $error_type_str = "Parse error";
                break;
            case E_NOTICE:
            case E_USER_NOTICE:
                $error_type_str = "Notice";
                break;
            case E_STRICT:
                $error_type_str = "Strict Standards";
                break;
            case E_DEPRECATED:
            case E_USER_DEPRECATED:
                $error_type_str = "Deprecated";
                break;
            default:
                $error_type_str = "Unknown error";
                break;
        }
        fwrite(STDERR, "PHP $error_type_str:  $errStr in $errFile on line $errLine\n");
        exit(1);
    },
    E_ALL
);

回答by Jose Philip Raja

You can turn on the error_reportingto E_ALLin PHP Configuration file of your server.

您可以在服务器的 PHP 配置文件中打开error_reportingto E_ALL

In PHP 5 a new error level E_STRICT is available. As E_STRICT is not included within E_ALL you have to explicitly enable this kind of error level. Enabling E_STRICT during development has some benefits. STRICT messages will help you to use the latest and greatest suggested method of coding, for example warn you about using deprecated functions.

在 PHP 5 中,新的错误级别 E_STRICT 可用。由于 E_STRICT 不包含在 E_ALL 中,您必须明确启用这种错误级别。在开发期间启用 E_STRICT 有一些好处。STRICT 消息将帮助您使用最新和最好的建议编码方法,例如警告您使用已弃用的函数。

Reference: PHP Configuration Manual

参考:PHP 配置手册

The following settings guide you to output all the errors in a script. Please note that these will need to be included in the start of all your script files.

以下设置指导您输出脚本中的所有错误。请注意,这些需要包含在所有脚本文件的开头。

<?php

// Turn off all error reporting
error_reporting(0);

// Report simple running errors
error_reporting(E_ERROR | E_WARNING | E_PARSE);

// Reporting E_NOTICE can be good too (to report uninitialized
// variables or catch variable name misspellings ...)
error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE);

// Report all errors except E_NOTICE
// This is the default value set in php.ini
error_reporting(E_ALL ^ E_NOTICE);

// Report all PHP errors (see changelog)
error_reporting(E_ALL);

// Report all PHP errors
error_reporting(-1);

// Same as error_reporting(E_ALL);
ini_set('error_reporting', E_ALL);

?>