记一次PHP测试环境调试

325 阅读2分钟

记一次PHP测试环境调试

一个简单的调试场景,在服务器测试一个脚本,composer管理,slim框架,Medoo作为ORM,脚本使用到了server中封装的方法,测试中脚本中断,在脚本中添加了print_r来查看运行状态,于是在server的代码中也添加了print_r,试图更精准的定位问题,没想到server挂了,准确说涉及到这个调用的接口都挂了。

知道挂了的时候忽然感觉可能会是添加了print_r的原因,果不其然。

那么为什么加了print_r打印会影响server的程序执行呢?

原因

首先明白缓冲区的作用,缓冲解决的是高速cpu与低速I/O设备不匹配的问题。

PHP对缓冲的操作时基于一系列的ob函数,ob是 output_buffering的简写。PHP中的echoprint_r函数显示到浏览器上的流程是:

echo、print_r=>php output_buffering=>webServer buffer=>browser buffer=>browser display

如果PHP server部署是使用了Apache和PHP,那么PHP要输出数据的时候,会经理两个缓冲区,显示PHP自身的换冲突,然后是Apache的缓冲区

缓冲区的数据什么时候输出呢?1,当缓冲区满了的时候,缓冲是有容量大小的,到达极限则会自动输出内容。2,脚本执行完毕。

print_r打印的过程,是一个打开缓冲区,写入,然后输出缓冲区的过程,而在PHP的web server中,响应内容是通过缓冲区来构建的,显式或隐式的使用ob_start来打开缓冲区,而使用print_r会影响web server对缓冲区的操作,导致返回异常或者没有返回。

深究

print_r并不一定会操作缓冲区,与输出缓冲区有关的配置 在php.ini中,有两个

  1. output_buffering 该配置直接影响的是php本身的缓冲区,有3种配置参数.on/off/xK(x为某个整型数值);

    • on - 开启缓冲区
    • off - 关闭缓冲区
    • 256k - 开启缓冲区,而且当缓冲区的内容超过256k的时候,自动刷新缓冲区(把数据发送到apache);
  2. implicit_flush

    该配置直接影响apache的缓冲区,有2种配置参数. on/off

    • on - 自动刷新apache缓冲区,也就是,当php发送数据到apache的缓冲区的时候,不需要等待其他指令,直接就把输出返回到浏览器
    • off - 不自动刷新apache缓冲区,接受到数据后,等待刷新指令

其他的ob函数可以通过PHP文档来查看。

www.php.net/manual-look…