PHP 5.6:headers_sent间歇性地返回true,空文件名和第0行

Aar*_*ron 8 php php-extension http-headers php-5.6

我在我的PHP脚本(PHP 5.6,Apache 2.2)中间歇性地遇到了这个问题:

警告:无法修改标头信息 - 已在第55行的/path/to/index.php中发送的标头

这个警告没有我在其他问题中看过的"发送者"部分,所以我在犯罪header()setcookie()调用之前添加了这段代码:

if (headers_sent($filename, $linenum)){
    echo("Output buffer: #" . ob_get_contents() . "#");
    echo "Headers already sent in $filename on line $linenum: ";
    print_r(headers_list());
}
Run Code Online (Sandbox Code Playgroud)

这是问题发生时我得到的输出:

Output buffer: ##
Headers already sent in on line 0:
Array (
  [0] => X-Powered-By: PHP/5.6.23
  [1] => Content-type: text/html; charset=UTF-8
)
Run Code Online (Sandbox Code Playgroud)

(旁注:我在php.ini中将output_buffering设置为4096字节,所以这两个标题中的63个字符是否应该被缓存并等待更多,而不是过早发送?)

第一次启动包含Web服务器的Docker容器时出现此问题.之后,当我第一次访问我的网站(可能是一两个小时),当我打电话并登录用户或重定向到登录页面时,它只会(但不总是)发生.header()setcookie()

我已阅读并重读了一般"已发送标题"错误的答案,并且尽我所能,我已排除了这些可能的原因:

  1. HTML块或调用print,echo等等.在我调用setcookie()header()
  2. 我的PHP标签之外的空格
  3. 物料清单
  4. auto_prepend_file php.ini设置
  5. gzip流编码 - 已安装zlib,但zlib.output_compression已关闭
  6. 重复的extension=php.ini设置

答案提到了这一点

如果没有错误源具体化,它通常是PHP扩展或php.ini设置.

所以,我现在正在查看我的扩展... get_loaded_extensions给我一个51长度的数组与这些条目:

Core, date, ereg, libxml, openssl,
pcre, zlib, filter, hash, Reflection,
SPL, session, standard, apache2handler, bz2,
calendar, ctype, curl, dom, exif,
fileinfo, ftp, gd, gettext, iconv,
mysqlnd, PDO, Phar, posix, shmop,
SimpleXML, snmp, soap, sockets, sqlite3,
sysvmsg, sysvsem, sysvshm, tokenizer, xml,
xmlwriter, xsl, mysql, mysqli, pdo_mysql,
pdo_sqlite, wddx, xmlreader, json, zip, mhash
Run Code Online (Sandbox Code Playgroud)

我没有使用所有这些,所以我打算通过并删除未使用的,并希望其中一个导致问题.

最坏的情况下,我会尽我撞output_buffering的值或使用ob_start(),并ob_end_flush()在开始和我的文件结束.我不知道为什么当我output_buffering4096的当前值没有时,这会解决它,并且我理解这种解决方法带有它自己的问题.

我在这里缺少什么 - 我还需要检查其他可能的原因吗?我应该尝试不同的PHP版本,或者在没有扩展的干净PHP安装上运行我的代码子集?

编辑:添加了ob_get_contents()调用和输出,以及有关能够通过旋转新的Docker容器一致地重现这一点的信息.删除了有关我的error_reporting价值的信息; 改变这一点只发现了一个always_populate_raw_post_data弃用通知,修正了对这里描述的问题没有影响.

Aar*_*ron 1

取出一些未使用的遗留代码\xe2\x80\x94(包括require_once对所有遗留代码\xe2\x80\x94的文件的调用)后,此问题不再发生。它可能会在我最初观察到的“间歇性”条件下重现,但我的重现方法不再出现这个问题。

\n\n

我不知道为什么这似乎有帮助 - 删除的行完全在<php? ?>标签内,并且我检查了删除的文件中标签、BOM 和 CRLF 外部的空白。

\n\n

我也不知道为什么这个问题是间歇性的;如果它与删除的代码或文件有关,那么它应该每次都会发生。

\n\n

感谢大家的评论和回答!

\n