众所周知,php 里面 header之前有输出的话,会报错,例如下面这样

 

就这个错误,我们开始查阅php源代码,到底是怎样做的,至于php源代码分析,安装,和调试时怎样配置的,我会专门写一篇文章去记录的,这里我是使用php-cli命令行的sapi,方便啊,首先我们先看看var_dump的实现啦

1.var_dump

我们知道,var_dump是php的标准函数啦,不是扩展里面的东西,所以会容易比较好找

我们可以见到啦,var_dump调用了php_var_dump函数啦

之后又调用了php_printf,我猜这个应该都是php内核用到的输出函数吧,我们再去php_printf看看吧

可见,php_printf模仿了c的printf,又是一个不定参数的函数,上面可以看到,又调用了PHPWRITE这个宏

实际是php_output_write函数啦

 

我们看看这个函数的逻辑吧

1,输出层是否激活,如果激活就调用php_output_op函数

2,如果不激活,那么直接输出到stderr去

2。 PHP_OUT_ACTIVATED由来

我们是用php-cli这个sapi的,跟踪了php启动过程,发觉,每个sapi都会调用一个函数,那就是

这个文件时在php-cli.c里面,有兴趣的读者可以看看这个,php在开始接受请求之前都会调用它的,截取一部分函数吧

我看看见了一个函数,php_out_activate函数啦

激活了输出层啦,证明可以输出啦

3 回到php_output_op函数

流程

   1 如果开启了缓冲区的话(obstart这种函数啦),就进入php_output_handler_op函数

   2,如果没有开启的话,就直接赋值给临时通道(context)

   3,如果真的有内容输出的话,就执行php_output_header函数

我们重点看php_output_header函数

4 php_output_header

 

这个函数很简单啦,就是设置当前输出行和该页面的名称,也就是我们调用var_dump的位置啦

具体有什么用,下面就知道啦

5,header函数实现

 

跟到sapi_header_op函数

在这里我们终于可以看到报错的哪行信息啦

header_sent什么时候开始设置呢

答案就是在在上面的 php_output_header函数里面调用的php_header里面啦

6 php_header

该函数的作用就是发送一个header(content-type:text/html);的东西,然后设置 SG(headers_sent) = 1

7 下面来分析为什么开启ob_start不会报错

  答案是开启了 因为开启了缓冲区,还记得上面php_output_op函数里面的一句代码吗

/*
* broken up for better performance:
*  - apply op to the one active handler; note that OG(active) might be popped off the stack on a flush
*  - or apply op to the handler stack
*/
if (OG(active) && (obh_cnt = zend_stack_count(&OG(handlers)))) {

 

上面的注释大家应该应该很清楚吗,如果我们调用了一个ob_start函数,php内核会申请一个handler结构同时为这个结构申请一个缓冲区 php_output_buffer

typedef struct _php_output_handler {
    char *name;
    size_t name_len;
    int flags;
    int level;
    size_t size;
    php_output_buffer buffer;
    void *opaq;
    void (*dtor)(void *opaq TSRMLS_DC);
    union {
        php_output_handler_user_func_t *user;
        php_output_handler_context_func_t internal;
    } func;
} php_output_handler;

当然,申请完缓冲区,就会初始化它然后把它压入栈啦,然后把handler赋给 OG(handlers)

 

下一篇说下,为什么header之前不能有输出,来更加深入httpd协议

php里面为什么header之前有输出报错 源码分析的更多相关文章

  1. SAP MM 公司间STO发货单输出报错 - 合并工厂AUC1和存储位置6002没有货物收货地点 - 之对策

    SAP MM 公司间STO发货单输出报错 - 合并工厂AUC1和存储位置6002没有货物收货地点 - 之对策 昨天收到客户业务部门报错,说是业务对交货单0080022298做POD失败.相关交货单的输 ...

  2. Mysql报错注入原理分析(count()、rand()、group by)

    Mysql报错注入原理分析(count().rand().group by) 0x00 疑问 一直在用mysql数据库报错注入方法,但为何会报错? 百度谷歌知乎了一番,发现大家都是把官网的结论发一下截 ...

  3. EasyPlayerPro(Windows)流媒体播放器开发之ffmpeg log输出报错

    EasyPlayerPro主要基于ffmpeg进行开发,在EasyPlayerPro开发过程中,曾遇到一个相对比较棘手的问题,该问题一般在播放不是很标准的流或者网络情况较差,容易出现丢帧的情况特别容易 ...

  4. scrapy shell 中文网站输出报错.记录.

    UnicodeDecodeError: 'gbk' codec can't decode bytes in position 381-382: illegal multibyte sequence 上 ...

  5. 【MySQL】MySQL同步报错-> received end packet from server, apparent master shutdown: Slave I/O thread: Failed reading log event, reconnecting to retry报错解决和分析

    [root@db-ft-db-48 ~]# tail -f /mysqlLog/beside_index_err.log 140102 20:42:26 [Note] Slave: received ...

  6. cocos2d-x在android中响应返回键编译报错的bug分析

    先看一段代码如何在Android中加入返回按键的响应 <span style="font-size:18px;">自己派生CCKeypadDelegate的子类,然后注 ...

  7. php源码分析之php_info输出中css样式是怎么来的

    我们经常使用echo phpinfo();查看php的配置信息,但是大家知道里面的css样式是怎么来的吗? 我们查看源码(php源码/ext/standard/css.c) PHPAPI void p ...

  8. MySQL主从检验一致性工具pt-table-checksum报错的案例分析

    [问题] 有同事反馈我们改造过的MySQL5.7.23版本,使用pt-table-checksum工具比较主从数据库的一致性时报错 Unsafe statement written to the bi ...

  9. MySQL Server has gone away报错原因汇总分析(转自:http://cenalulu.github.io/mysql/mysql-has-gone-away/)

    原因1. MySQL 服务宕了 判断是否属于这个原因的方法很简单,执行以下命令,查看mysql的运行时长 $ mysql -uroot -p -e "show global status l ...

随机推荐

  1. Lumina将是基于 Qt工具箱,旨在取代KDE成为PC-BSD默认的桌面环境

    Lumina Desktop 1.1.0 发布了,该版本是重要更新,包括全新的以及完全重新编写的utilities,并对底层基础架构进行改进. Lumina将是基于 Qt工具箱,旨在取代KDE成为PC ...

  2. PostMessage与SendMessage各自的问题

     深入解析SendMessage.PostMessage 本文将使用C++语言,在MFC框架的配合下给出PostMessage.SendMessage等的使用方式与使用不当造成的后果(讨论均针对自定义 ...

  3. PowerDesigner模型设计

    原文:PowerDesigner模型设计 绪论 Sybase PowerDesigner(简称PD)是最强大的数据库建模工具,市场占有率第一,功能也确实十分强大,现在最新版本是15.1,已经支持最新的 ...

  4. HDU5086——Revenge of Segment Tree(BestCoder Round #16)

    Revenge of Segment Tree Problem DescriptionIn computer science, a segment tree is a tree data struct ...

  5. linux下手动安装apache详解

    引自:http://blog.chinaunix.net/uid-28458801-id-4211258.html error1:出现以下错误时候,需要下载安装apr configure: error ...

  6. Android开发之onActivityResult()中的resultCode为0,intent为null的解决办法

    BUG:昨天在使用activity之间传值的时候,遇到了一个bug,该bug为:Activity A启动Activity B,然后在Activity B中取到一个值,并通过back键返回到Activi ...

  7. makefile的常用规则

    一.前言 这篇文章介绍在LINUX下进行C语言编程所需要的基础知识.在这篇文章当中,我们将会学到以下内容: 源程序编译 Makefile的编写 程序库的链接 程序的调试 头文件和系统求助 二.正文 1 ...

  8. 安卓学习之--如何关闭所有的activity

    根据Activity的声明周期 方法1   我们知道Android的窗口类提供了历史栈,我们可以通过stack的原理来巧妙的实现,这里我们在A窗口打开B窗口时在Intent中直接加入标志 Intent ...

  9. axis : java.lang.NoSuchMethodError

    Hi friends,Iam getting the following error when deploying my app in jboss error.Iam new to axis .can ...

  10. return File

    public ActionResult DownloadMessage() { string strExportData = "无数据!"; byte[] data = Syste ...