php里面为什么header之前有输出报错 源码分析
众所周知,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 ...
随机推荐
- HTML5入门1---Canvas画布
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- sudo和su
su命令就是切换用户的工具 sudo 授权许可使用的su,也是受限制的su 1. sudo 的适用条件 由于su 对切换到超级权限用户root后,权限的无限制性,所以su并不能担任多个管理员所管理的系 ...
- AutoCAD图形打印出图片 C#
这几天搞cad二次开发,用的是C#语言,目前在网上找到的资料比较少.弄了两天,才做出怎样实现打印出图片.首先得在AutoCAD软件界面下,设置打印机的页面设置和打印机设备名称一样(以防打印不出来).即 ...
- hadoop2 环境的搭建(手动HA)
1.手工切换ha的环境的搭建(比hadoop1多出来journalnode的配置) namenode:hadoop110和hadoop111 datanode:hadoop112.hadoop113. ...
- ListView(2)最简单的上拉刷新,下拉刷新
最简单的上拉刷新和下拉刷新,当listview滚动到底部时向上拉刷新数据.当listview滚动到最顶部时下拉刷新. 图1,上拉刷新 图2,下拉刷新 1,设置lisview,加载heade ...
- Android相对布局(RelativeLayout)
Android相对布局(RelativeLayout) 备注:这里的视图和元素是等同的概念. RelativeLayout是一个允许子视图相对于其他兄弟视图或是父视图显示的视图组(通过ID指定).每个 ...
- Servlet错误一览
错误:HTTP Status 405 - HTTP method POST is not supported by this URL 原因:没有提供doPost方法 错误:控制器跳转到空白界面 原因: ...
- 1641. Duties
1641 枚举 #include <iostream> #include<cstdio> #include<cstring> #include<algorit ...
- fil_space_create
/*******************************************************************//** Creates a space memory obje ...
- FTP出现211-Extension supported 停止的解决方法
FTP出问题211-Extension supported 停止的解决方法 FTP出问题211-Extension supported 停止的解决方法 FLASHFXP FTP上传登录时提示Exten ...
