PHP的配置设置'error_log'无法工作

40

我在这里做错了什么?

我在.ini文件中设置了error_log和error_reporting = E_ALL | E_STRICT

还有什么是我忽略的吗?通常这就能解决问题。我想在.ini文件中设置,而不是在我的脚本中设置。

另一个有趣的事情是,当我故意在我的脚本中抛出错误时,Apache会一遍又一遍地重新启动。


这是发生一个错误后我的事件日志。请查看时间戳。

Wed Nov 04 19:34:23 2009] [notice] Apache/2.2.14 (Win32) PHP/5.3.0 configured -- resuming normal operations
[Wed Nov 04 19:34:23 2009] [notice] Server built: Sep 28 2009 22:41:08
[Wed Nov 04 19:34:23 2009] [notice] Parent: Created child process 1700
[Wed Nov 04 19:34:23 2009] [notice] Child 1700: Child process is running
[Wed Nov 04 19:34:23 2009] [notice] Child 3008: Released the start mutex
[Wed Nov 04 19:34:23 2009] [notice] Child 1700: Acquired the start mutex.
[Wed Nov 04 19:34:23 2009] [notice] Child 1700: Starting 64 worker threads.
[Wed Nov 04 19:34:23 2009] [notice] Child 1700: Starting thread to listen on port 80.
[Wed Nov 04 19:34:24 2009] [notice] Child 3008: All worker threads have exited.
[Wed Nov 04 19:34:24 2009] [notice] Child 3008: Child process is exiting
[Wed Nov 04 19:34:53 2009] [notice] Parent: child process exited with status 128 -- Restarting.
[Wed Nov 04 19:34:53 2009] [notice] Apache/2.2.14 (Win32) PHP/5.3.0 configured -- resuming normal operations
[Wed Nov 04 19:34:53 2009] [notice] Server built: Sep 28 2009 22:41:08
[Wed Nov 04 19:34:53 2009] [notice] Parent: Created child process 3656
[Wed Nov 04 19:34:53 2009] [notice] Child 3656: Child process is running
[Wed Nov 04 19:34:53 2009] [notice] Child 3656: Acquired the start mutex.
[Wed Nov 04 19:34:53 2009] [notice] Child 3656: Starting 64 worker threads.
[Wed Nov 04 19:34:53 2009] [notice] Child 3656: Starting thread to listen on port 80.
[Wed Nov 04 19:34:53 2009] [notice] Parent: child process exited with status 128 -- Restarting.
[Wed Nov 04 19:34:54 2009] [notice] Apache/2.2.14 (Win32) PHP/5.3.0 configured -- resuming normal operations
[Wed Nov 04 19:34:54 2009] [notice] Server built: Sep 28 2009 22:41:08
[Wed Nov 04 19:34:54 2009] [notice] Parent: Created child process 3980
[Wed Nov 04 19:34:54 2009] [notice] Child 3980: Child process is running
[Wed Nov 04 19:34:54 2009] [notice] Child 3980: Acquired the start mutex.
[Wed Nov 04 19:34:54 2009] [notice] Child 3980: Starting 64 worker threads.
[Wed Nov 04 19:34:54 2009] [notice] Child 3980: Starting thread to listen on port 80.
[Wed Nov 04 19:34:54 2009] [notice] Parent: child process exited with status 128 -- Restarting.
[Wed Nov 04 19:34:54 2009] [notice] Apache/2.2.14 (Win32) PHP/5.3.0 configured -- resuming normal operations
[Wed Nov 04 19:34:54 2009] [notice] Server built: Sep 28 2009 22:41:08
[Wed Nov 04 19:34:54 2009] [notice] Parent: Created child process 1600
[Wed Nov 04 19:34:54 2009] [notice] Child 1600: Child process is running
[Wed Nov 04 19:34:54 2009] [notice] Child 1600: Acquired the start mutex.
[Wed Nov 04 19:34:54 2009] [notice] Child 1600: Starting 64 worker threads.
[Wed Nov 04 19:34:54 2009] [notice] Child 1600: Starting thread to listen on port 80.
[Wed Nov 04 19:34:55 2009] [notice] Parent: child process exited with status 128 -- Restarting.
[Wed Nov 04 19:34:55 2009] [notice] Apache/2.2.14 (Win32) PHP/5.3.0 configured -- resuming normal operations
[Wed Nov 04 19:34:55 2009] [notice] Server built: Sep 28 2009 22:41:08
[Wed Nov 04 19:34:55 2009] [notice] Parent: Created child process 1068
[Wed Nov 04 19:34:55 2009] [notice] Child 1068: Child process is running
[Wed Nov 04 19:34:55 2009] [notice] Child 1068: Acquired the start mutex.
[Wed Nov 04 19:34:55 2009] [notice] Child 1068: Starting 64 worker threads.
[Wed Nov 04 19:34:55 2009] [notice] Child 1068: Starting thread to listen on port 80.
[Wed Nov 04 19:34:55 2009] [notice] Parent: child process exited with status 128 -- Restarting.
[Wed Nov 04 19:34:55 2009] [notice] Apache/2.2.14 (Win32) PHP/5.3.0 configured -- resuming normal operations
[Wed Nov 04 19:34:55 2009] [notice] Server built: Sep 28 2009 22:41:08
[Wed Nov 04 19:34:55 2009] [notice] Parent: Created child process 3220
[Wed Nov 04 19:34:56 2009] [notice] Child 3220: Child process is running
[Wed Nov 04 19:34:56 2009] [notice] Child 3220: Acquired the start mutex.
[Wed Nov 04 19:34:56 2009] [notice] Child 3220: Starting 64 worker threads.
[Wed Nov 04 19:34:56 2009] [notice] Child 3220: Starting thread to listen on port 80.

这个问题已经被问过1000次了,我在发布这篇提问之前浏览了不同的帖子,但是没有找到答案。自从我开始使用PHP编程以来,这一点就一直是让人噩梦般的难以解决。


关于定位PHP错误日志的相关问题:*PHP 5,Apache,FastCGI和cPanel中PHP存储错误日志的位置在哪里?*(尽管标题过于具体)。 - Peter Mortensen
15个回答

25

检查PHP-FPM是否没有显式设置error_log

确保文件/etc/php-fpm.d/www.conf中不包含php_admin_value关于error_log的设置。搜索以下内容并使用分号将其注释掉:

; NOTE: If these are set, ini_set('error_log', 'path') will have no effect
; inside your php code, and this will be forced to be the value always.
; php_admin_value[error_log] = /var/log/php-fpm/www-error.log
; php_admin_flag[log_errors] = on

然后重新启动php-fpm:

systemctl restart php-fpm

检查 Apache .htaccess 文件是否使用 php_admin_value 设置 error_log

在 Apache 配置文件中设置的 php_admin_value 无法被覆盖,因此请确保在 Apache 配置文件中没有任何 php_admin_value 设置了 error_log 值。同时,也要检查是否有 php_value 设置。

PHP 网站 - 如何更改配置设置


3
救命稻草!在经过数小时的疲惫排查后,这个解决方案为我解决了问题。谢谢! - paulmiller3000

12

Flimm的故障排除指南

这是我的故障排除指南,针对error_log()调用无法工作的问题。

  1. 查看您服务器的配置,找出默认错误日志文件所在位置。 这取决于您使用的服务器。如果您正在使用Apache,请参考Apache的ErrorLog选项;如果您正在使用Nginx,则参考Nginx的error_log选项。确保它被设置为一个文件。如果您使用像Valet这样的工具,请注意它在幕后使用类似Nginx的服务器软件。

  2. 检查服务器错误日志文件的权限。在类Unix系统上,它应该可写,并且父目录及其祖先的权限也需要正确。使用chmodchown进行更改。

  • 检查.ini文件中PHP的配置。特别地,检查log_errors = On, error_reporting = E_ALL | E_STRICT, 和 error_log = /tmp/example/php_errors.log这些log_errors, error_reporting, 和 error_log 的配置设置(详见文档)。要找到.ini文件,请查看phpinfo();的输出。如果error_log未设置,默认情况下会记录到服务器的错误日志中(在之前的步骤中提到)。如果error_log设置为一个文件,则该文件应该已经存在并且可写,就像之前的步骤一样。记得在更改配置后重新启动服务器。

  • 检查服务器配置是否改变了PHP的设置。即使是 .htaccess 文件也可以更改PHP配置设置。在Apache中,使用 php_admin_valuephp_admin_flag 进行更改(文档)。例如,你可能会在 .htaccess 文件中找到这一行:php_admin_flag[log_errors] = off。记得在更改配置后重启服务器。此时,你应该能够创建一个测试文件test.php,其内容为<?php error_log("test");,重启服务器并在浏览器中打开URL,你应该能够在错误日志中看到test(无论是服务器的还是由error_log = 指定的日志)。但是请继续阅读。

  • 检查PHP的设置是否在运行时被改变。选项log_errors可以通过运行ini_set('log_errors', 1);在运行时更改,并且其他配置选项error_reportingerror_log也可以这样做。还要注意,有一个特殊的error_reporting() PHP函数可以在运行时更改配置。搜索您的代码库以查找任何对ini_seterror_reporting的调用。例如,WordPress会根据WP_DEBUG的值运行它们。

  • 其他需要注意的事项:您可能在SELinux中遇到权限问题(请参见此答案)。


    2
    还有一件事:如果您正在访问一个https:网站,那么您需要查看ssl_error_log文件而不是error_log文件。 - charlesdeb
    @charlesdeb 你是在说nginx吗? - Flimm
    2
    我的经验是使用Apache。我花了很长时间试图弄清楚为什么不再将任何内容记录到“error_log”文件中,然后意识到所有内容都被发送到“ssl_error_log”(尽管某些安装程序无论是否为SSL都会将所有内容发送到“error_log”)。 - charlesdeb
    在我的情况下,应用程序本身有它自己的日志文件。 - MeSo2

    11

    5
    嗨Chaos,谢谢。我已将其设置为打开状态。还有什么我漏掉的吗? - Jim
    3
    请重新启动服务器。 - aagjalpankaj
    1
    @aagjalpankaj,你能解释一下为什么它有帮助并且为什么它之前是出错的吗? - Sam Tyurenkov
    php.ini 文件位于哪里?在 /etc/php/7.4/apache2/php.ini 中吗? - Peter Mortensen
    1
    好的,一种方法是查看 phpinfo() 输出中带有 "Loaded Configuration File" 的那一行。从命令行运行:php -r "phpinfo();" | grep "Loaded Configuration File"(示例输出:Loaded Configuration File => /etc/php/7.4/cli/php.ini)。在 Web 上下文中:如果测试页面文件 test.php 存在,则其中包含对 phpinfo() 的调用 - 例如,URL http://localhost/test.php(示例输出:*/etc/php/7.4/apache2/php.ini*)。 - Peter Mortensen

    9
    如果有人在本地开发环境中无法记录错误,以下是我解决问题的方法:
    在Windows上,必须将error_log设置为日志的完整路径才能使error_log()起作用(error_log = c:\apache\php_errors.log)。但是,如果error_log = php_errors.log没有路径,PHP仍然能够记录启动错误,例如:

    PHP启动:无法加载动态库'ext\php_mysqli.dll' - 找不到指定的模块


    我指定了完整路径,但没有提前创建文件。当我重新启动WAMP时,日志文件被创建,但WAMP显示黄色图标,本地主机无法加载。有什么想法吗?当我注释掉“error_log”时,一切正常,但PHP错误出现在Apache日志中。 - thomthom

    8

    我遇到的问题是我指定的错误日志是受保护的。 我所有的 .htaccess 设置都正确,但是PHP无法写入错误日志,因为它没有任何权限。 下面的代码解决了我的问题:

    chmod 777 watermellon-app-errors.log
    

    显然,您需要将 .log 部分更改为您用作日志的任何文件。


    1
    是的,你说得对。当然,如果文件的所有者是其他人,644可能不够用。你可以使用777来测试它,然后降低权限以查看哪些权限有效。 - Thomas Keene
    在我的情况下,我需要646.. 只是提供一下信息,以防其他人遇到像我这样的问题。 - FastTrack
    在Mac OS上,我不得不使用666,因为普通文件设置为root:wheel。我可能本可以将其保留为646,因为我认为apache默认情况下是以“_www”运行的。 - Phil Glau
    chmod 777 = "设置权限,使得(U)用户/所有者可以读取、写入和执行。(G)组可以读取、写入和执行。(O)其他人可以读取、写入和执行。" 这样安全吗? - Peter Mortensen

    4
    如果设置了error_log指令,该文件将用于记录PHP错误。如果未设置,则错误将记录在Apache日志中。请查看error_log
    error_log文件及其所在的目录必须可写入Apache正在运行的用户。如果文件未被创建,则可能是权限问题。
    我不确定为什么Apache会崩溃,但我猜测这是某种权限问题。

    2

    我不知道为什么,但错误日志现在可以正常工作了。这是我所做的。

    我放弃了并将error_log指令注释掉并关闭了ini文件。我运行了带有解析错误的脚本,以查看Apache是否仍会崩溃,并在日志文件中得到了PHP错误。这很奇怪,因为ini文件不再启用error_log,而我的脚本也没有使用ini_set()


    这更像是一个问题而不是答案。Stack Overflow 不是一个论坛 - Peter Mortensen

    2
    在我的情况下,在一个CentOS开发服务器上,经过完整的yum update之后,/var/log/http的权限被更改为700,用户变成了“root”,因此用户“apache”无法进入或写入该文件夹。
    它仍然能够写入现有文件/var/log/httpd/error.log,但是无法创建新文件,因为我使用日期后缀的日志文件。
    输入以下命令:
    chown apache /var/log/httpd
    

    解决了问题。

    "chmod 700" = "设置权限,使得(U)用户/所有者可以读取、写入和执行。(G)组不能读取、写入和执行。(O)其他人不能读取、写入和执行。" - Peter Mortensen

    1
    如果您正在使用FedoraSELinux(默认启用),即使在php.ini文件中指定了您的文件并且其所在目录具有所有权限,Apache / httpd也会防止将错误附加到日志文件中。 您可以通过查看/var/log/messages系统日志文件来确定是否发生了这种情况。

    Enter image description here

    理想的解决方案是配置SELinux以允许访问日志文件。

    更快的解决方法是在/etc/selinux/config中将SELINUX设置为disabled来禁用SELinux。

    完成此操作后,您需要重新启动系统才能使更改生效。


    4
    你提供的建议实际上有一个网站可以阻止提供该建议。http://stopdisablingselinux.com - ʰᵈˑ
    2
    我知道,因此我写下了“理想”。我还没有被说服一个本地工作的家庭用户需要开启SELinux。 - Anthony
    如果SElinux的人们不再让一切都崩溃,那么人们可能会想要使用它。即使是一个SElinux日志,表明:“嘿,我也阻止了这个。如果您想要,这是如何启用它的。”将非常有帮助。目前为止,除非你说“可能是因为SElinux破坏了一切”,否则你无法知道它为什么会出现故障。基本上任何故障,我都会看看SElinux直到最后放弃,因为它花费了我数小时的时间来诊断是SElinux还是搜索模糊命令或设置以让此实例通过。 - Altimus Prime

    1

    进一步调试:

    phpinfo();

    它显示当前的error_log设置,紧挨着phpinfo()中的error_log值,当虚拟主机没有记录日志时非常有用。

    我在php.ini文件和虚拟主机中被覆盖后最终来到了这里。我最终记录到了系统日志中。


    感谢@PeterMortensen的格式和拼写更新。我已经更新了它,以指定error_log值在error_log下找到。然而,我不确定这样做有多少价值,但还是感谢格式和拼写的更新。 - themullet
    1
    我确信自己正在查看正确的错误日志,所以从未想过要检查phpinfo -- 直到看到你提到vhost后,我终于放弃了并尝试了一下。当然,真正日志的路径就在那里。 - tobybot

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接