简体   繁体   English

是否可以忽略 PHP 中的致命错误?

[英]is it possible to ignore a fatal error in PHP?

I understand the significance of the term 'fatal error', but I want to write a test class like this (disgustingly simplified):我理解术语“致命错误”的重要性,但我想编写一个这样的测试类(令人作呕的简化):

class tester {

    function execute() {

        if( @$this->tryit() === true ) return true;
        return false;

    }

    function tryit() {

        $doesntexist = new noobject();
        return true;

    }

}

actually I'd have a Test parent class, and then classes would extend it and contain a bunch of methods with a bunch of tests.实际上我有一个Test父类,然后类会扩展它并包含一堆带有一堆测试的方法。 The parent class would define execute and it would just run every method in the child class (excluding execute of course) and collecting data on which functions pass and which fail.父类将定义execute ,它只会运行子类中的每个方法(当然不包括execute )并收集有关哪些函数通过和哪些失败的数据。

I want to write tests before I actually write part of my code, but instead of using assert I just want to run every test and generate a list of which functions of which test classes fail.我想在实际编写部分代码之前编写测试,但我不想使用assert我只想运行每个测试并生成哪些测试类的哪些函数失败的列表。 But that means if a test fails it means there was an error -- but I also want to handle instances where I forgot to define a class, etc. Is it possible to do that, while not having the entire script die?但这意味着如果测试失败,则意味着存在错误——但我也想处理我忘记定义类等的实例。是否有可能做到这一点,同时不让整个脚本死掉?

I was thinking that the script would just fail up until the function call with the @ in front of it, and then continue, but obviously I was wrong.我以为脚本只会失败,直到函数调用前面带有@ ,然后继续,但显然我错了。 Is there a workaround?有解决方法吗?

A fatal error is fatal , and there is nothing you can do about it.致命错误是致命的,您对此无能为力。

Two ideas of solutions could be :解决方案的两种想法可能是:

  • To test if the method exists before trying to call it ;在尝试调用之前测试该方法是否存在; see method_existsmethod_exists
  • Or, to run each "test" in a separate processus : this way, if there is a Fatal Error caused by one test, only the "child" process corresponding to that test dies, and the "parent" process, the test launcher, can detect this and consider it as a failure.或者,在单独的进程中运行每个“测试”:这样,如果一个测试导致致命错误,则只有与该测试对应的“子”进程死亡,“父”进程,测试启动器,可以检测到这一点并将其视为失败。

Actually, the second solution exists in PHPUnit since version 3.4, if I remember correctly ;-)实际上,如果我没记错的话, PHPUnit自 3.4 版以来就存在第二种解决方案;-)

Fatal errors cannot be stopped, not even with set_error_handler .即使使用set_error_handler也无法阻止致命错误。 However, you can often find another way at the expense of writing more code.但是,您通常可以以编写更多代码为代价找到另一种方法。 For the example method tryit , you can write an autoload function that triggers a non-fatal error or (in PHP 5.3.0) throws an exception, or use class_exists to skip the instantiation of a non-existent class.对于示例方法tryit ,您可以编写触发非致命错误或(在 PHP 5.3.0 中)抛出异常的自动加载函数,或使用class_exists跳过不存在类的实例化。

Yes and No是和否

You cannot write it so that the code picks up where it left off, after the fatal.您不能编写它以便代码在致命的之后从停止的地方开始。 However, you can use register_shutdown_function() to continue processing php after the fatal error.但是,您可以在发生致命错误后使用 register_shutdown_function() 继续处理 php。

I've written code that checks which kind of fatal error it was and then attempt to fix it before redirecting the user back to the same page, or dying.我已经编写了代码来检查它是哪种致命错误,然后在将用户重定向回同一页面或死亡之前尝试修复它。

register_shutdown_function is excellent for redirecting the user to a 500 error page with a contact form prevalued with the error info. register_shutdown_function 非常适合将用户重定向到 500 错误页面,其中包含一个带有错误信息预赋值的联系表单。 This way I could have the users help me out by opening an issue on my github acct.这样我就可以让用户通过在我的 github 账户上打开一个问题来帮助我。

我猜你会用set_error_handler()函数设置一个错误处理程序,调用你的测试类来报告错误,但我不完全确定你将如何实现它。

With PHP 7, you can now try/catch a fatal error.使用 PHP 7,您现在可以尝试/捕获致命错误。

https://www.php.net/manual/en/language.exceptions.php https://www.php.net/manual/en/language.exceptions.php

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM