PHP ob_get_length似乎返回不正确的值

时间:2016-01-12 09:54:34

标签: php json output-buffering

我有一个函数应该返回客户端的JSON响应,然后继续处理而不锁定客户端,这似乎工作正常,除非我添加Content-Length标头(我想做的是确保客户端被释放了)。 功能是:

function replyAndCarryOn($responseText){
    ignore_user_abort(true);//stop apache killing php
    ob_start();//start buffer output
    echo $responseText;
    session_write_close();//close session file on server side to avoid blocking other requests
    header("Content-Encoding: none");
    header('Content-Type: application/json; charset=utf-8');                   
    header("Content-Length: ".ob_get_length());
    header("Connection: close");
    ob_end_flush();
    flush();
}

这很正常,但由于Content-Length错误,返回浏览器的JSON字符串被截断。例如,以下字符串

  

{“result”:“AUTH”,“authList”:[{“uid”:“Adam”,“gid”:“Users”,“authid”:1},“uid”:“Admin”,“ GID “:” 管理员”, “AUTHID”:2},{ “UID”: “乔治”, “GID”: “用户”, “AUTHID”:3},{ “UID”: “测试”, “GID” : “用户”, “AUTHID”:4}], “ID”: “付款”}

将显示为:

  

{ “结果”: “AUTH”, “authList”:[{ “UID”: “亚当”, “GID”: “用户”, “AUTHID”:1},{ “UID”: “系统管理员”, “GID”: “管理员”, “AUTHID”:2},{ “UID”: “乔治”, “GID”: “用户”, “AUTHID”:3},{ “UID”: “测试”,“GID “:” 用户 “ ”AUTHID“:4}], ”ID“:”

我可以保留Content-Length标题,apache(2.2)会自动添加'Transfer-Encoding:'chunked“'标题似乎有用,但我想深入了解为什么ob_get_length不会返回我需要的值,我知道如果启用了gzip,它会产生太长的结果但是我看到相反的值太短了。

所以我想知道:

a)在获取内容长度方面我做错了什么?

b)有什么问题可以解决吗?

在@Xyv的评论之后,似乎服务器在输出字符串之前输出一个新行和八个空格,但是这不包括在ob_get_length返回中。令人尴尬的是,事实证明它是一个回车,并且在第一个php标签之前以某种方式添加了八个空格。

1 个答案:

答案 0 :(得分:1)

我认为我发布此答案是为了提高可读性。

也许首先捕获输出,然后制作标题,然后是正文?

对我来说这个例子有效:

<?php
function replyAndCarryOn($responseText){
    ignore_user_abort(true);//stop apache killing php
    ob_flush( );
    ob_start( );//start buffer output
    echo $responseText;
    session_write_close();//close session file on server side to avoid blocking other requests
    header("Content-Encoding: none");
    header('Content-Type: application/json; charset=utf-8');                   
    header("Content-Length: ".ob_get_length());
    header("Connection: close");
    echo ob_get_flush();
    flush();
}


replyAndCarryOn(  '{"result":"AUTH","authList":[{"uid":"Adam","gid":"Users","authid":1}, "uid":"Admin","gid":"Admin","authid":2},{"uid":"George","gid":"Users","authid":3},{"uid":"test","gid":"Users","authid":4}],"id":"Payment"}'  );
?>

更新重要的是要知道在输出任何正文之前应该ob_start()。缓冲区将丢失此数据,因此可能不会计算。我不是输出缓冲的专家,但确保将ob_start放在脚本的开头,这样就很难犯任何错误。 (因此,请在初始<?php之前小心放置空格和/或制表符)。