这里的拓展分为了两种,通常在php.ini中,通过extension=加载的扩展我们称为php扩展,通过zend_extension=加载的扩展我们称为zend扩展,但从源码的角度来讲,php扩展应该称为“模块”(源码中以module命名),而zend扩展称为“扩展”(源码中以extension命名)。两者最大的区别在于向引擎注册的钩子,向用户层面提供一些c实现的php函数,需要用到zend_module_entry(即作为php扩展),而需要hook到zend引擎的话,就得用到zend_extension(即作为zend扩展)。
<?php echo "hello world";
切割成了4部分
<?php => #define t_open_tag 379 echo => #define t_echo 328 空格 => #define t_whitespace 382 "hello world" => #define t_constant_encapsed_string 323
单独存在的词块不能完整表达语义,还需要语法分析器,它会检查语法,匹配token,对token进行关联,组织串联后的产物就是ast.ast 分为多种类型,对应php语法,比如赋值语句,生成的抽象语法树节点是zend_ast_assign,赋值语句的左右会被作为zend_ast_assign类型节点的孩子(ast是php7才加入的,解耦了编译器和解释器).
opcode是php执行过程中的中间代码,生成后由虚拟机执行,生成的opcode是类似下面的样子
line op 1 echo 2 return
源码中对应的opcode及handler
zend_echo // handler:zend_echo_spec_const_handler 实现的功能是输出"hello world" zend_return // handler:zend_return_spec_const_handler
=> compile_file => open_file_for_scanning(读取php代码内容,并使词法分析指针指向第一个位置) => zendparse(词法分析语法分析后生成ast) => init_op_array(初始化op_array) => zend_compile_top_stmt(把ast转为op_array) => pass_two(设置op_array对应的zend虚拟机handler) => 生成op_array => zend_execute(zend虚拟机中执行op_array)
fcgi.c ... fcgi_lock(req->listen_socket); req->fd = accept(listen_socket, (struct sockaddr *)&sa, &len); fcgi_unlock(req->listen_socket);
引用
如对本文有疑问, 点击进行留言回复!!
php 使用 yansongda/pay 进行微信,支付宝支付
Codeforces Round #658 (Div. 2) (C1、C2)
van-uploader + thinkphp6.0 图片上传
网友评论