禁止使用协程 API 的场景(2.x 版本)
最后更新于:2022-04-02 06:30:25
# 禁止使用协程 API 的场景(2.x 版本)
[TOC]
在`ZendVM`中魔术方法、反射函数、`call_user_func`、`call_user_func_array`是由`C`函数实现的,并未`opcode`,这些操作可能会与`Swoole`底层的协程调度发生冲突。因此严禁在这些地方使用协程的`API`。请使用`PHP`提供的动态函数调用语法来实现相同的功能。
> 在`4.0`版本后已解决此问题,可以在任意函数中使用协程,下列禁用场景仅针对`2.x`版本
* `__get`
* `__set`
* `__call`
* `__callStatic`
* `__toString`
* `__invoke`
* `__destruct`
* `call_user_func`
* `call_user_func_array`
* `ReflectionFunction::invoke`
* `ReflectionFunction::invokeArgs`
* `ReflectionMethod::invoke`
* `ReflectionMethod::invokeArgs`
* `array_walk`/`array_map`
## 字符串函数
#### 错误的代码
~~~
$func = "test";
$retval = call_user_func($func, "hello");
~~~
#### 正确的代码
~~~
$func = "test";
$retval = $func("hello");
~~~
## 对象方法
#### 错误的代码
~~~
$retval = call_user_func(array($obj, "test"), "hello");
$retval = call_user_func_array(array($obj, "test"), "hello", array(1, 2, 3));
~~~
#### 正确的代码
~~~
$method = "test";
$args = array(1, 2, 3);
$retval = $obj->$method("hello");
$retval = $obj->$method("hello", ...$args);
~~~
';