php 在内容前插入十六进制字符数 [英] php inserts HEX number of characters before the content

查看:42
本文介绍了php 在内容前插入十六进制字符数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将网站移至新服务器.(旧服务器有 php 5.3.2,新服务器有 php 5.5.9)Centos,httpd Apache/2.2.26.

I'm moving a website to a new server. (Old server had php 5.3.2, the new one has php 5.5.9) Centos, httpd Apache/2.2.26.

我复制了文件,除了唯一奇怪的事情外,它工作正常:在页面内容之前插入了一些奇怪的十六进制数字:

I've copied files and it works fine except the only weird thing: some strange HEX number is inserted before the content of pages:

此外,在页面底部,0 被插入到 </html> 标签之后.

Also, in the bottom of the page, 0 is inserted after the </html> tag.

我注意到两件事:

1) 就我而言,php 脚本只发送了两个标头:

1) In my case only two headers are sent from php script:

header("HTTP/1.1 200 OK");
header("Status: 200");

如果我评论第一个标题,那就没问题了 - 没有奇怪的数字.

If I comment the first header than It will be ok - no strange numbers.

2) 看起来这个数字是页面上的字符数(我已经检查过了).如果页面少于 8000 个字符,则不会出现数字,但如果页面有 8001 个字符,则出现 1F41

2) It looks like that number is the number of characters on the page (I've checked it). And if the page is less then 8000 characters, than the number doesn't appear, but if page has 8001 characters than 1F41 appears

附言我被建议从文件中删除所有 BOM.文件没问题 - 已经没有 BOM.所以这与 BOM 无关.

P.S. I was advised to remove all BOM from files. Files were OK - already without BOM. So it's not about BOM.

UPD:我做了一个非常简单的测试(index.php):

UPD: I made a very simple test (index.php):

<?php header("HTTP/1.1 200 OK"); ?>
Lorem Ipsum ... 8000 characters

一切正常.

<?php header("HTTP/1.1 200 OK"); ?>
Lorem Ipsum ... 8001 characters

Bug 在 Lorem Ipsum 之前发生 1f41.

Bug happens 1f41 before Lorem Ipsum.

推荐答案

这不是 PHP 也不是 BOM.您的内容传输编码有问题.

This is not PHP nor a BOM. You have a problem with Content-Transfer-Encoding.

服务器正在发送一个Chunked编码(这个通常在 Content-Length 不可用时完成)客户端显然不知道如何处理,标头组合使客户端相信它可以绕过分块.

The server is sending along a Chunked encoding (this is usually done when the Content-Length is unavailable) which the client apparently doesn't know how to handle, or the header combination makes the client believe that it can bypass dechunking.

因此,客户端解释的下一个块的长度"实际上是多少,您将其视为内容之前的十六进制位:

Therefore, what is actually the "length of next chunk" gets interpreted by the client, and you see it as a hex bit before the content:

05
These
05
 Are 
03
the
1F
 first characters of the senten
03
ce.

代替

Content-Length: 48
These are the first characters of the sentence.

(我是用肉眼计算长度的,他们可能是错的)

可能的原因是您有某种干扰内容编码的缓冲.如果一切都保留在缓冲区中,一切都很好,那么 Content-Length 可用,并被发送并且 Bob 是你的叔叔.但是,如果您发送的缓冲区超过 8000 字节,则缓冲区将被刷新,并且会发生一些不愉快的事情.尝试查看 zlib 和输出缓冲的文档,您可能会在 php.ini 中在 Apache 的功能和 PHP 的功能之间存在一些冲突.

The likely cause is that you have some kind of buffering which interferes with Content Encoding. If everything stays in the buffer, all well and good, a Content-Length is available, gets sent and Bob's your uncle. But if you send more than the 8000 bytes of the buffer, the buffer is flushed and something untoward happens. Try looking in the documentation for zlib and output buffering, you might have some conflict in php.ini between what Apache does and what PHP does.

显示 8000 究竟是(是?)在 apache 的某些部分中使用的缓冲区大小的有趣链接:

Interesting links that show how exactly 8000 is (was?) a buffer size used in some portions of apache:

https://bugs.php.net/bug.php?id=45945

https://serverfault.com/questions/366996/how-can-the-apache-2-2-deflate-module-length-limit-be-increased

最后一个链接建议我建议您尝试检查 zlib、mod_gzip、ob_gzhandler 和/或 mod_deflate 是否已启用,并且可能存在冲突,或者尝试将一个替换为另一个.

This last link suggests me to suggest you to try checking whether zlib, mod_gzip, ob_gzhandler and/or mod_deflate are enabled, and possibly conflicting, or to try exchanging the one for the other.

添加适当的 Transfer-Encoding 标头可解决问题.

Adding the appropriate Transfer-Encoding header fixes the problem.

那么究竟发生了什么?我们知道输出是正确分块编码的(即分块本身是正确的),并且客户端能够在被告知后对其进行解释.因此,所缺少的只是关于被分块的内容的知识,这看起来很荒谬,而且有一点错误:无论分块,内容都必须知道它会被分块(天啊!),所以它有责任添加适当的标题,但它没有(或者它做了,但其他东西剥离它),直到 OP纠正了自己手动添加标题的情况.

So what really happened? We know that the output was correctly chunked-encoded (i.e. the chunking itself was correct), and the client was able to interpret it after being told to. So what was missing was simply the knowledge of the content being chunked, which looks absurd and a good bit buggy: for whatever chunked the content had to know it would get chunked (d'oh!), so it had responsibility of adding the appropriate header, and yet it did not (or it did, but something else stripped it), until the OP rectified the situation adding a header himself by hand.

问题现在已经解决了,但我认为在工作流程中的某个地方一定仍然存在一个错误,无论是在模块、应用程序中,还是在标题的处理方式中.

The problem is now solved, but I think there must be still a bug lingering somewhere in the workflow, either in the modules, the application, or in how the headers are processed.

这篇关于php 在内容前插入十六进制字符数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆