echo 作为PHP中的语言结构, 经常会被使用, 因此了解他的实现还是有必要的.
Note: 因为是一个语言构造器而不是一个函数,不能被 可变函数 调用。
输出对象时汇报以上错误, 所以如果需要输出对象, 一定要在其内部实现 __toString()。
php 是一门脚本语言, 所以所有的符号都会先经过词法解析和语法解析阶段, 这两个阶段由lex & yacc 完成。
在计算机科学里面,lex是一个产生词法分析器的程序。 Lex常常与yacc 语法分析器产生程序一起使用。Lex是许多UNIX系统的标准词法分析器产生程序,而且这个工具所作的行为被详列为POSIX标准的一部分。 Lex读进一个代表词法分析器规则的输入字符串流,然后输出以C语言实做的词法分析器源代码。 --维基百科
对应的文件在 Zend/zend_language_parser.y 和 Zend/zend_language_scanner.l。
ZEND引擎在读取一个PHP文件之后会先进行词法分析,就是用lex扫描,把对应的PHP字符转换成相应的标记(也叫token),比如 echo $a; 在碰到这句首先会匹配到echo,符合上面的规则,然后就返回一个 T_ECHO 标记,这个在后面的语法分析会用上,也就是在 zend_language_parser.y 文件中
在 statement 看到了 T_ECHO, 后面跟着 echo_expr_list,再搜这个字符串,找到如下代码:
这么看比较难理解,接下来我们从一个简单的例子看下最终生成的语法树。
具体解析过程这里不再解释,有兴趣的可以翻下zend_language_parse.y中,这个过程不太容易理解,需要多领悟几遍,最后生成的ast如下图:
通过 write_function 绑定PHP输出函 数php_output_wrapper 至 zend_utility_functions结构体, 此结构体会在xx被使用
百度大模型语义搜索体验中心
在 php_out_wrapper 中调用的 php_output_write 在 main/output.c 中实现, 实现代码如下:
不调用sapi_module的输出
调用sapi_module的输出
php_output_op 详细实现如下:
以上了解了PHP输出函数的实现, 接下来了解echo实现.
可以看到在 zend vm 中通过调用zend_write来实现输出,接下来看下zend_write的实现。
zend_utility_functions *utility_functions 在 main/main.c php_module_startup()的 zuf中被定义:
echo 输出大字符串(500K)的时候,执行时间会明显变长,所以会被认为PHP的echo性能很差, 实际上这并不是语言(PHP)问题, 而是一个IO问题(IO的速度限制了输出的速度)。
那么使用 apache 时如何优化使的 echo 变快, 让PHP的请求处理过程尽快结束?
echo慢是在等待“写数据”成功返回, 所以可打开输出缓存:
ob_start() 会开辟一块4096大小的buffer,所以如果 $hugeString 大于 4096,将不会起到加速作用。
echo 会立即执行成功返回, 因为数据暂时写到了我们的输出缓存中,如果buffer足够大,那么内容会等到脚本的最后,才一次性的发送给客户端(严格的说是发给webserver)。
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!