PHP 在 echo 后发送 header 的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
SomeBottle
V2EX    PHP

PHP 在 echo 后发送 header 的问题

  •  
  •   SomeBottle 2018-08-19 11:53:42 +08:00 4479 次点击
    这是一个创建于 2640 天前的主题,其中的信息可能已经有所发展或是发生改变。

    之前玩 PHP 尝试在 echo 后发送 Header,但是直接写在一起是没法送出去头的..

    根据网上的方法我把 echo 和 header 丢到了 ob 缓冲区里,就像下面这个图一样..

    本地 phpStudy 环境测试非常成功..但是扔到服务器(Linux - Nginx)上后就出现了发送不出去头的问题, 本来我期待在 echo 执行完后关闭连接转服务端执行的...结果 header 发不出去只会全部执行完再返回数据..

    求问我是哪里写错了吗...还是说这种方法已经不可行了,测试 PHP 版本是 5.4...

    第 1 条附言    2018-08-19 12:33:23 +08:00

    我在header前还写了个session:

    第 2 条附言    2018-08-19 12:58:20 +08:00
    使用 fastcgi_finish_request();( PHP-fpm )可以强制断开客户端连接,可以暂时替代。
    16 条回复    2018-08-19 18:14:07 +08:00
    bao0541
        1
    bao0541  
       2018-08-19 12:04:16 +08:00
    请注意 header() 必须在任何实际输出之前调用,不管是普通的 HTML 标签,还是文件或 PHP 输出的空行,空格。这是个常见的错误,在通过 include,require,或者其访问其他文件里面的函数的时候,如果在 header()被调用之前,其中有空格或者空行。 同样的问题也存在于单独的 PHP/HTML 文件中。
    SomeBottle
        2
    SomeBottle  
    OP
       2018-08-19 12:07:15 +08:00
    @bao0541 我现在的问题就在于不懂为什么会这样,不然早就解决了...前面没有任何输出,我打开全部报错也没有任何报错,这是用于 ajax 请求的一个后端,只有这一句 echo 输出.
    chinvo
        3
    chinvo  
       2018-08-19 12:14:01 +08:00 via iPhone
    你第二行 echo 就是输出,header 必须放在任何输出前
    batnss
        4
    batnss  
       2018-08-19 12:15:17 +08:00
    header 2 句放最后试试
    SomeBottle
        5
    SomeBottle  
    OP
       2018-08-19 12:34:07 +08:00
    @chinvo 询问一下 session 算输出吗..
    @batnss 这样行不通,obflush 直接输出了缓冲区的 echo
    NextAccount
        6
    NextAccount  
       2018-08-19 12:50:39 +08:00   1
    @SomeBottle sssion 本质上是 header set-cookie,所以不算输出。这里的输出指的是 response body 的部分。

    我测试了一下 Content-Length 输出成功,但是 Connection 头仍然是 Keep-Alive,这个和 HTTP 服务器配置有关系。

    "本来我期待在 echo 执行完后关闭连接转服务端执行的...结果 header 发不出去只会全部执行完再返回数据.." --- 这句话是什么意思?
    SomeBottle
        7
    SomeBottle  
    OP
       2018-08-19 12:54:40 +08:00
    @NextAccount 就是如果没有关闭连接就要等待 flush 后的程序执行完才会返回 echo,不过刚刚我在想 fastcgi_finish_request();有没有作用..
    chinvo
        8
    chinvo  
       2018-08-19 13:01:21 +08:00
    header 放到 ob_start 之前
    chinvo
        9
    chinvo  
       2018-08-19 13:03:22 +08:00   1
    你现在的写法把 header 包在 ob cache 里面了
    SomeBottle
        10
    SomeBottle  
    OP
       2018-08-19 13:05:15 +08:00
    @chinvo 我换了好多 header 的位置还是不行,你提示的这个地方我也试过,只有 Content-Length 被设置了,看来是 http 服务器设置有问题..
    NextAccount
        11
    NextAccount  
       2018-08-19 13:08:31 +08:00
    @SomeBottle 即使你成功输出 Connection: close 头信息,也并不会关闭当前的 HTTP 连接。你完全可以 有条件的 return 掉不行么?
    NextAccount
        12
    NextAccount  
       2018-08-19 13:10:54 +08:00
    fastcgi_finish_request() 会结束客户端连接,也许可行。但是后面的代码仍然会执行。
    SomeBottle
        13
    SomeBottle  
    OP
       2018-08-19 13:14:35 +08:00
    @NextAccount 我需要的就是继续在服务端执行后面的代码。fastcgi_finish_request 虽然有环境的限制,但是我记得很多网站服务器 PHP 模块都支持 fastcgi 协议
    NextAccount
        14
    NextAccount  
       2018-08-19 13:14:38 +08:00   1
    终于明白了楼主的意思。楼主是想要尽快输出,但是有一部分代码在服务器端继续执行。

    你有几个选择:

    1. fastcgi_finish_request
    2. 通过消息系统或者直接 exec 开后台子进程去异步执行。
    mrcn
        15
    mrcn  
       2018-08-19 14:49:22 +08:00 via Android
    搞个后台队列是最方便的。

    header 发送的是 http 头,必须在所有输出之前,就像你必须先拿碗才能装菜一样。
    otakustay
        16
    otakustay  
       2018-08-19 18:14:07 +08:00
    如果你想尽快输出内容,那么就别用 Content-Length,用 chunked encoding 输出
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3023 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 12:32 PVG 20:32 LAX 04:32 JFK 07:32
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86