首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Zend表达式中将PHP错误记录到PHP的错误文件中?

问如何在Zend表达式中将PHP错误记录到PHP的错误文件中?
EN

Stack Overflow用户
提问于 2018-02-08 15:33:18
回答 1查看 997关注 0票数 0

使用ZendExpression2.0.5,我想将PHP错误记录到PHP的错误日志文件中,我浏览了https://docs.zendframework.com/zend-expressive/features/error-handling/#handling-exceptions-and-errors

我还看到了这个帖子:Zend expressive错误报告。这为我澄清了很多问题,但仍然没有解决问题。

我所做的事情:定义了我自己的ErrorHandlerFactory,其中我将两个侦听器附加到Zend-stratigility's ErrorHandler

  1. 第一个监听器使用Zend登录到我的应用程序的日志文件中。(只是觉得在我的application.log中也有错误是很好的。)
  2. 在第二个侦听器中,我希望登录到php的错误日志文件中,因此我从php中使用了error_log()方法。

问题:

  1. error_log()没有像由php的错误处理程序打印日志时显示的那样打印日志。我的意思是: 当php的错误处理程序打印错误时,它看起来如下所示: 08-2018年2月08:22:51 US/Central PHP警告: array_push()要求至少有2个参数,第38行的array_push给出了一个参数

当我使用error_log()打印日志时,它看起来如下所示:

08-2018年09-2018年09:03:49 US/Central array_push()要求至少有2个参数,第38行的C:\webserver\webroot\myapi\src\App\src\Action\PageAction.php中有1个参数

我在这里缺少的是PHP的错误类型:PHP警告,这是错误代码吗?我得到的错误代码是一个整数,我如何解析该代码?如果我用出现在日志中的PHP常量映射错误代码,例如:警告、注意事项等,我甚至可以这样做,但问题是:在php的错误处理程序打印警告和致命错误日志时,我得到了的相同错误代码。

  1. 像这样在PHP的错误日志文件中记录错误是正确的吗?我应该做PHP错误处理程序的工作吗?错误处理程序可以做很多事情,例如:将错误消息记录在少数错误中,但是对于另一个错误,也记录堆栈跟踪。如果这是不对的,那么我如何将错误发送到的error_handler? 据我理解: 我自己的错误处理程序阻止用户查找异常和堆栈跟踪,而是返回一条通用消息。这也意味着Error handler将使用错误,并且不会在外部抛出错误,即不会将其抛给PHP的错误处理程序。
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-02-09 13:15:48

回答问题1:

我几乎能够模拟PHP错误处理程序记录PHP错误的方式。我做过的事:

  1. 通过了文档和这所以的问题。使用这些,我能够将侦听器附加到Zend-分层的ErrorHandler
  2. 研究了PHP的误差常数和处理程序(),这给了我一些关于如何找出哪种类型的错误或异常发生的想法。

下面是我的ErrorHandlerFactory的代码,我在这里附加了侦听器。

代码语言:javascript
复制
<?php
// TODO: PHP 7.0.8 is giving strict erros eben if this directive is not enabled. And that too, it should be enabled per file from my understanding.
//declare(strict_types = 1);
namespace App\Factories;
use Interop\Container\ContainerInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Zend\Log\Logger as ZendLogger;
use Throwable;
use Zend\Diactoros\Response;
use Zend\Expressive\Middleware\ErrorResponseGenerator;
use Zend\Stratigility\Middleware\ErrorHandler;
class ErrorHandlerFactory
{
    /**
     * @param ContainerInterface $container
     * @return ErrorHandler
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    public function __invoke(ContainerInterface $container)
    {
        $generator = $container->has(ErrorResponseGenerator::class)
            ? $container->get(ErrorResponseGenerator::class)
            : null;
        $errorHandler = new ErrorHandler(new Response(), $generator);

         // attaching a listener for logging into application's log file.
        if ($container->has(ZendLogger::class)) {
            /** @var ZendLogger $logger */
            $logger = $container->get(ZendLogger::class);
            $errorHandler->attachListener(function (
                Throwable $throwable,
                RequestInterface $request,
                ResponseInterface $response
            ) use ($logger) {
                $logger->err(NULL, [
                    'method'  => $request->getMethod(),
                    'uri'     => (string) $request->getUri(),
                    'message' => $throwable->getMessage(),
                    'file'    => $throwable->getFile(),
                    'line'    => $throwable->getLine(),
                ]);
            });
        }

        // Attaching second listener for logging the errors into the PHP's error log
        $errorHandler->attachListener(function (
            Throwable $throwable,
            RequestInterface $request,
            ResponseInterface $response
        ) {
            // Default Error type, when PHP Error occurs.
            $errorType = sprintf("Fatal error: Uncaught %s", get_class($throwable));
            if (get_class($throwable) === "ErrorException") {

                // this is an Exception
                /** @noinspection PhpUndefinedMethodInspection */
                $severity = $throwable->getSeverity();
                switch($severity) {
                    case E_ERROR:
                    case E_USER_ERROR:
                        $errorType = 'Fatal error';
                        break;
                    case E_USER_WARNING:
                    case E_WARNING:
                        $errorType = 'Warning';
                        break;
                    case E_USER_NOTICE:
                    case E_NOTICE:
                    case E_STRICT:
                        $errorType = 'Notice';
                        break;
                    case E_RECOVERABLE_ERROR:
                        $errorType = 'Catchable fatal error';
                        break;
                    case E_USER_DEPRECATED:
                    case E_DEPRECATED:
                        $errorType = "Deprecated";
                        break;
                    default:
                        $errorType = 'Unknown error';
                }

                error_log(sprintf("PHP %s: %s in %s on line %d", $errorType, $throwable->getMessage(), $throwable->getFile(), $throwable->getLine()), 0);
            }
            else {
                // this is an Error.
                error_log(sprintf("PHP %s: %s in %s on line %d \nStack trace:\n%s", $errorType, $throwable->getMessage(), $throwable->getFile(), $throwable->getLine(), $throwable->getTraceAsString()), 0);
            }
        });

        return $errorHandler;
    }
}

除此之外,这个工厂还需要添加到依赖项中。在文件:dependencies.global.php中,在factories数组中:

替换

Zend\Stratigility\Middleware\ErrorHandler::class => Container\ErrorHandlerFactory::class,

使用

代码语言:javascript
复制
Zend\Stratigility\Middleware\ErrorHandler::class => \App\Factories\ErrorHandlerFactory::class

这几乎可以模拟php错误处理程序的日志记录行为。

回答问题2:

我认为这样做很好,因为PHP本身提供了set_error_handler(),而且无论如何,我们必须自己处理错误,而不是将它传递给PHP的错误处理程序。如果我们的ErrorHandler(侦听器)能够复制消息并使用error_log()登录到PHP的错误日志中,那么就可以了。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48689174

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档