众所周知,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之前有输出报错 源码分析的更多相关文章
-
SAP MM 公司间STO发货单输出报错 - 合并工厂AUC1和存储位置6002没有货物收货地点 - 之对策
SAP MM 公司间STO发货单输出报错 - 合并工厂AUC1和存储位置6002没有货物收货地点 - 之对策 昨天收到客户业务部门报错,说是业务对交货单0080022298做POD失败.相关交货单的输 ...
-
Mysql报错注入原理分析(count()、rand()、group by)
Mysql报错注入原理分析(count().rand().group by) 0x00 疑问 一直在用mysql数据库报错注入方法,但为何会报错? 百度谷歌知乎了一番,发现大家都是把官网的结论发一下截 ...
-
EasyPlayerPro(Windows)流媒体播放器开发之ffmpeg log输出报错
EasyPlayerPro主要基于ffmpeg进行开发,在EasyPlayerPro开发过程中,曾遇到一个相对比较棘手的问题,该问题一般在播放不是很标准的流或者网络情况较差,容易出现丢帧的情况特别容易 ...
-
scrapy shell 中文网站输出报错.记录.
UnicodeDecodeError: 'gbk' codec can't decode bytes in position 381-382: illegal multibyte sequence 上 ...
-
【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 ...
-
cocos2d-x在android中响应返回键编译报错的bug分析
先看一段代码如何在Android中加入返回按键的响应 <span style="font-size:18px;">自己派生CCKeypadDelegate的子类,然后注 ...
-
php源码分析之php_info输出中css样式是怎么来的
我们经常使用echo phpinfo();查看php的配置信息,但是大家知道里面的css样式是怎么来的吗? 我们查看源码(php源码/ext/standard/css.c) PHPAPI void p ...
-
MySQL主从检验一致性工具pt-table-checksum报错的案例分析
[问题] 有同事反馈我们改造过的MySQL5.7.23版本,使用pt-table-checksum工具比较主从数据库的一致性时报错 Unsafe statement written to the bi ...
-
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 ...
随机推荐
-
hdfs 机架感知和复制因子的设置
dfs.replication 新更新的复制因子的参数对原来的文件不起作用. 譬如说,原来的复制因子是2,则原来文件上传的时候就只有两个副本. 现在把dfs.replication设置为3,重新启动h ...
-
Ubuntu终端常用的快捷键
Ubuntu终端常用的快捷键 Ubuntu中的许多操作在终端(Terminal)中十分的快捷,记住一些快捷键的操作更得心应手.在Ubuntu中打开终端的快捷键是Ctrl+Alt+T.其他的一些常用的快 ...
-
iOS开发——XML/JSON数据解析
NSJSONSerialization 接下来就正式开始.苹果官方给出的解析方式是性能最优越的,虽然用起来稍显复杂. 首先我们在上面已经有了我希望得到的信息的网站的API给我们的URL,在OC中,我要 ...
-
多校5 1004 HDU5784 统计锐角三角形数目
http://acm.hdu.edu.cn/showproblem.php?pid=5784 题意:n个点,找多少个锐角三角形数目 思路:极角排序+two pointers 当前选择的点集要倍增一倍, ...
-
USACO4.13Fence Loops(无向图最小环)
最近脑子有点乱 老是不想清楚就啪啪的敲 敲完之后一看 咦..样例都过不去 仔细一想 这样不对啊 刚开始就写了一SPFA 最后发现边跟点的关系没处理好 删了..写dfs..还是没转化好 开始搜解题方法 ...
-
zzuoj 10408: C.最少换乘【最短路dijkstra】
10408: C.最少换乘 Time Limit: 2 Sec Memory Limit: 128 MBSubmit: 31 Solved: 8[Submit][Status][Web Board ...
-
Build FFmpeg for iOS
FFmpeg Build Instructions MAC 10.8 or better Copy ffmpeg-2.0.tar.bz2 (https://ffmpeg.org/releases/ff ...
-
SSM学习笔记
Spring MVC[入门]就这一篇! https://www.jianshu.com/p/91a2d0a1e45a SpringMVC非注解方式和注解方式不能同时使用.注解方式只需要配一句话就行了d ...
-
[转帖]2016年时的新闻:ASP.NET Core 1.0、ASP.NET MVC Core 1.0和Entity Framework Core 1.0
ASP.NET Core 1.0.ASP.NET MVC Core 1.0和Entity Framework Core 1.0 http://www.cnblogs.com/webapi/p/5673 ...
-
ESXi去掉 SSH已经启用的警告信息
1. 在vCenter管理的机器里面 总是有几台服务器 提示 SSH启动连接 并且有黄色的警告信息 有时内存或者CPU报警的信息就看不到了.. 所以想着解决他,经过百度发现解决办法为: 选中host主 ...