安装了Swoole扩展之后,查看opcode,出现许多swoole的opcode的解决方法
如果你在安装了Swoole
扩展之后,查看PHP
脚本对应的opcode
的时候,可能会发现出现很多的opcode
。我举个例子吧。PHP
脚本如下:
1 2 3 4 5 6 7 8 9
| <?php
function test() { echo "test"; }
echo "main";
|
这是一个很简单的脚本,按理来说只会生成两组opcode
。但是,如果我们查看它的opcode
的话,就会有如下情况:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| function name: (null) L1-9 {main}() /root/codeDir/phpCode/test/swoole/test.php - 0x7f82eae77840 + 5 ops L3 #0 EXT_STMT L3 #1 NOP L8 #2 EXT_STMT L8 #3 ECHO "main" L9 #4 RETURN<-1> 1
# 省略了其他的opcode
function name: _array L16-19 _array() @swoole-src/library/functions.php - 0x7f82eae6c480 + 8 ops L16 #0 RECV_INIT 1 array(0) $array L18 #1 NEW<1> "Swoole\\ArrayObje"+ @0 L18 #2 SEND_VAR_EX $array 1 L18 #3 DO_FCALL L18 #4 VERIFY_RETURN_TYPE @0 L18 #5 RETURN @0 L19 #6 VERIFY_RETURN_TYPE L19 #7 RETURN<-1> null
function name: scheduler L24-31 scheduler() @swoole-src/library/functions.php - 0x7f82eae6c700 + 8 ops L26 #0 BIND_STATIC<1> $scheduler "scheduler" L27 #1 BOOL_NOT $scheduler ~0 L27 #2 JMPZ ~0 J6 L28 #3 NEW "Swoole\\Coroutine"+ @1 L28 #4 DO_FCALL L28 #5 ASSIGN $scheduler @1 L30 #6 RETURN $scheduler L31 #7 RETURN<-1> null
function name: test L3-6 test() /root/codeDir/phpCode/test/swoole/test.php - 0x7f82eae77780 + 5 ops L3 #0 EXT_NOP L5 #1 EXT_STMT L5 #2 ECHO "test" L6 #3 EXT_STMT L6 #4 RETURN<-1> null
# 省略其他的opcode
|
我们发现,除了main
和test
的两组opcode
,还生成了其他大量的opcode
。
为什么呢?因为Swoole4
引入了一个实现扩展的技巧:通过在C/C++
扩展来直接执行PHP
代码,从而实现扩展的部分功能。
核心函数是php_swoole_library.h
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
|
static void php_swoole_load_library() { zend::eval(swoole_library_source_constants, "@swoole-src/library/constants.php"); zend::eval(swoole_library_source_std_array, "@swoole-src/library/std/array.php"); zend::eval(swoole_library_source_std_exec, "@swoole-src/library/std/exec.php"); zend::eval(swoole_library_source_ext_curl, "@swoole-src/library/ext/curl.php"); zend::eval(swoole_library_source_core_coroutine_wait_group, "@swoole-src/library/core/Coroutine/WaitGroup.php"); zend::eval(swoole_library_source_core_coroutine_object_pool, "@swoole-src/library/core/Coroutine/ObjectPool.php"); zend::eval(swoole_library_source_core_string_object, "@swoole-src/library/core/StringObject.php"); zend::eval(swoole_library_source_core_array_object, "@swoole-src/library/core/ArrayObject.php"); zend::eval(swoole_library_source_core_coroutine_server, "@swoole-src/library/core/Coroutine/Server.php"); zend::eval(swoole_library_source_core_coroutine_server_connection, "@swoole-src/library/core/Coroutine/Server/Connection.php"); zend::eval(swoole_library_source_functions, "@swoole-src/library/functions.php"); zend::eval(swoole_library_source_alias, "@swoole-src/library/alias.php"); zend::eval(swoole_library_source_alias_ns, "@swoole-src/library/alias_ns.php"); }
|
我已经给出了这个函数的注释了。其中zend::eval
直接执行PHP
代码。通过这种方式,Swoole
让curl
协程化了。
所以,这就是为什么我们只是查看一个简单脚本,就会打印出众多的opcode
。因为在加载Swoole
扩展的时候,默认会把swoole-src/library
里面的PHP
代码编译为opcode
。
所以,我们这个时候可以这样来查看我们这个脚本的opcode
:
1 2 3 4 5 6 7 8 9 10 11 12 13
| ~/codeDir/phpCode/test/swoole # phpdbg -np* test.php function name: (null) L1-9 {main}() /root/codeDir/phpCode/test/swoole/test.php - 0x7f517c681000 + 3 ops L3 #0 NOP L8 #1 ECHO "main" L9 #2 RETURN<-1> 1
function name: test L3-6 test() /root/codeDir/phpCode/test/swoole/test.php - 0x7f517c67e060 + 2 ops L5 #0 ECHO "test" L6 #1 RETURN<-1> null [Script ended normally] ~/codeDir/phpCode/test/swoole #
|
多了一个-n
参数,禁用默认的php.ini
配置。