【问题标题】:How can I find out all the errors that can possibly be thrown by a block of PHP code?如何找出所有可能由 PHP 代码块引发的错误?
【发布时间】:2018-06-06 03:09:54
【问题描述】:

我想知道对于动态代码(而不是静态代码)会抛出哪些我没有发现的错误。例如,我的代码可能运行 10 年没有抛出任何异常,然后抛出 UncaughtException

我想专门(非一般地)捕获我正在使用的方法可能引发的每种类型的异常。我怎么知道这些方法可能会抛出什么异常?

我想非泛型地捕获可能为一段 PHP 代码抛出的每种类型的错误。

可能抛出的异常示例:

PDOException
ExpiredException

现在我什么都有了:

try{
 ...
}catch(Exception $e){
 ...
}

我想用这样的东西替换它:

try{
 ...
}catch(PDOException $e){
 ...
}catch(ExpiredException $e){
 ...
}catch(Exception $e){
 ...
}

我想确信我可以捕获代码部分中的方法可能引发的所有不同类型的异常

如果我单独捕获所有异常,删除这部分是否安全?:

catch(Exception $e){
 ... 
}

或者有没有简单的抛出异常的方法?

我的解决方案偏好列表(1 是最偏好的解决方案):

1:我可以打开一个标志,它会导致 php.exe 警告我未明确捕获的每种可能类型的异常

2:一种单独检查每个方法并查看可能引发的错误的方法。文档是唯一的检查方法吗?或者是否有一些 IDE 或 PHP 块可以告诉我个别方法可能会抛出哪些异常?

【问题讨论】:

  • 要回答第 1 部分,您可以在脚本开头调用 error_reporting(E_ALL); 来记录发生的每个错误,无论您是否发现它。
  • This answer 介绍了如何将所有警告捕获为异常,然后您可以根据需要进行处理。
  • 当然可以,但我想知道一段代码(或单独为每个方法)可能会引发哪些错误,因为某些错误可能需要以特定方式处理。
  • 我的代码不是静态的,所以这没有帮助。昨天第一次抛出ExpiredException,被catch(Exception $e){ ... }处理不当。我添加了 catch(ExpiredException){ ... } 现在如果再次发生它将得到适当的处理。我想知道可能会抛出哪些我没有发现的错误。例如,明天可能会抛出一种我没有正确处理的新异常。我正在使用标准的 PHP 代码,例如 $this->connection = new PDO($dsn, $username, $password, $dboptions);,但这会抛出 PDOException。

标签: php error-handling exception-handling


【解决方案1】:

您甚至可以在不调用try 的情况下捕获所有异常。

function hello($e)
{
  if ($e instanceof PDOException){
  echo "something".
}else echo $e->getMessage();


}


set_exception_handler('hello');

这应该捕获所有异常。

更新 2

我已经编辑了代码,所以你知道使用get_class();会抛出什么异常

class mycustomException extends Exception{} // making new exception
function hello($e)
{
    if ($e instanceof PDOException){ // exception already known
        echo "something";
}else{

        echo get_class($e); // get exception name.
    }


}


set_exception_handler('hello');
throw new mycustomException(); // throw exception that we made.

【讨论】:

  • 酷,但我想知道可能会抛出哪些异常。捕获和处理错误是另一个问题。例如,我今天才发现 ExpiredException 可以被其中一种方法抛出。它由导致意外行为的 catch(Exception $e){ ... } 处理。所以我想知道还有什么我不知道的可能会被抛出。
  • 您可以在调用 else 时捕获 ExpiredException 或您不知道的任何其他异常,我们已调用 $e instanceof PDOException 以防您对该异常执行特殊操作。跨度>
  • 该代码捕获 PDOException。我的观点是我不知道会抛出什么样的异常,我想知道。我想知道会抛出什么异常。这与捕获特定异常非常不同。我什至可能不想抓住他们中的任何一个!我想知道它们是什么。
  • 通过调用 get_class();函数,您将能够知道抛出了哪个异常。无论如何,我已经编辑了答案。
  • 这也很有趣,但它仍然与问题完全无关。我不想知道抛出后抛出了哪类异常。我想知道我的代码中的每个方法可能会抛出哪类异常。我想非一般地处理每一类异常。对于 1000 行 PHP 100 种方法,我如何知道每种方法,我没有具体捕获哪些异常类?
【解决方案2】:

如果你说的是例外,那你已经有了答案

try{
 ...
}catch(PDOException $e){
 ...
}catch(ExpiredException $e){
 ...
}catch(Exception $e){
   echo get_class($e); // get's the class of unrecorded exceptions.
   //catches any exceptions missed by the above
}

现在,如果您在谈论“错误”,您可以使用custom error handler

  if(!function_exists('myErrorHandler')){
      function myErrorHandler($severity, $message, $file = 'UNKNOWN', $line = 'UNKNOWN')
      {

         throw new ErrorException(
             $message,
             1,
             $severity,
             $file,
             $line
         );
      }

      set_error_handler('myErrorHandler');
 }

它的作用是将所有 PHP 错误转换为异常,或者更确切地说是ErrorExceptoins

现在您可以更进一步,使用这两个函数。

register_shutdown_function

set_exception_handler

我实际上正在努力将我使用的东西移植到它自己的独立 github project。在我完成我的eJinn 项目后,您可能会感兴趣。eJinn 旨在基于配置文件构建异常类,因此您可以在每个异常文件中出现一个错误,并且在项目中拥有唯一的错误代码。

【讨论】:

  • 这些步骤正是我在项目中所做的。
  • 不错,兼容PHP7?
  • 应该是,但是我更大的框架还没有完成(实际上我必须重做它,我打算分成单独的repos)。所以我不确定它在此之外的效果如何。我需要一些时间来处理错误的内容。
  • 在我的 index.php 中,第 310 行是从 github.com/ArtisticPhoenix/Evo/blob/master/index.php 调用它的地方,它需要一个编写器和格式化的回调,这样可以将错误写入屏幕、文件、电子邮件,等等......它有一些后退,所以没有它也可以工作。
【解决方案3】:

您可以使用 register_shutdown_function() 设置回调函数,该函数将在您的 php 代码执行的每一端调用。在此回调函数中,您可以使用 error_get_last() 检查是否发生任何错误。 例如:

// Register shutdown function
register_shutdown_function("shutdownTracker");

// Define all error types you want to catch and handle
define('E_FATAL', E_ERROR | E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR | E_RECOVERABLE_ERROR);

function shutdownTracker() {
    $error = error_get_last(); // This will return empty if no error occurs while executing php code.
    if(!empty($error) && ($error['type'] & E_FATAL)) {
        // Write your code here to handle you error

    }
}

注意:您应该在代码顶部包含此代码。

【讨论】:

  • 我不想知道什么时候发生错误,我可以用 catch(Exception $e){ ... } 来处理。
  • 我想知道我的代码中的方法会抛出哪些错误。例如,我今天才发现 ExpiredException 可以被其中一种方法抛出。它由导致意外行为的 catch(Exception $e){ ... } 处理。
猜你喜欢
  • 2020-12-01
  • 2018-03-22
  • 1970-01-01
  • 2021-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-16
  • 1970-01-01
相关资源
最近更新 更多