进入module函数
thinkphp/library/think/App.php:493行

public static function module($result, $config, $convert = null)
{
if (is_string($result)) {
$result = explode('/', $result);
}
$request = Request::instance();
if ($config['app_multi_module']) {
// 多模块部署
$module = strip_tags(strtolower($result[0] ?: $config['default_module']));
$bind = Route::getBind('module');
$available = false;
if ($bind) {
// 绑定模块
list($bindModule) = explode('/', $bind);
if (empty($result[0])) {
$module = $bindModule;
$available = true;
} elseif ($module == $bindModule) {
$available = true;
}
} elseif (!in_array($module, $config['deny_module_list']) && is_dir(APP_PATH . $module)) {
$available = true;
}
// 模块初始化
if ($module && $available) {
// 初始化模块
$request->module($module);
$config = self::init($module);
// 模块请求缓存检查
$request->cache(
$config['request_cache'],
$config['request_cache_expire'],
$config['request_cache_except']
);
} else {
throw new HttpException(404, 'module not exists:' . $module);
}
} else {
// 单一模块部署
$module = '';
$request->module($module);
}
// 设置默认过滤机制
$request->filter($config['default_filter']);
// 当前模块路径
App::$modulePath = APP_PATH . ($module ? $module . DS : '');
// 是否自动转换控制器和操作名
$convert = is_bool($convert) ? $convert : $config['url_convert'];
// 获取控制器名
$controller = strip_tags($result[1] ?: $config['default_controller']);
$controller = $convert ? strtolower($controller) : $controller;
否则,在类c实现的接口列表以及它们的父接口之中递归查找是否有简单名称和描述符都与目标相匹配的方法,如果存在匹配的方法,则说明类c是一个抽象类,这是查找结束,抛出java.lang.abstractmethoderror异常。myproperty就是你要绑定的成员,由dependencyobject d来得到具体的通知对象,这样就会抛出异常)在需要多线程 中操作的绑定变量.test,于是换成代码绑定吧: inotifypropertychanged { private string test。另外,可以使用 cjson 2.1.0,该版本新增一个 cjson.safe 模块接口,该接口兼容 cjson 模块,并且在解析错误时不抛出异常,而是返回 nil。
但是这里需要特别指出的是:在互斥对象通知引起调用等待函数返回时,等待函数的返回值不再是通常的wait_object_0(对于waitforsingleobject()函数)或是在wait_object_0到wait_object_0+ncount-1之间的一个值(对于waitformultipleobjects()函数),而是将返回一个wait_abandoned_0(对于waitforsingleobject()函数)或是在wait_abandoned_0到wait_abandoned_0+ncount-1之间的一个值(对于waitformultipleobjects()函数)。此时rs的值为null,如果加入g,rs的值仍然为null,如果加入m,则rs的值为{bj}(也就是说,在第一行没有找到匹配,因为有参数m,所以可以继续去下面的行去找是否有匹配)thinkphp function.php,如果m和g都加上,则返回{bj,b7}(只加m不加g说明,可以去多行进行匹配,但是找到一个匹配后就返回,加入g表明将多行中所有的匹配返回,当然对于match方法是如此,对于exec呢,则需要执行多次才能依次返回)。 * array_filter():此函数是专门用于过去数组中的元素,简单点说就是对数组中的经过回调函数判断的value进行过滤(一般为自定义回调函数,如:奇数或偶数的过滤等),并通过array_filter()函数返回处理后的数组。
进入self::invokeMethod函数
thinkphp/library/think/App.php:329行
public static function invokeMethod($method, $vars = [])
{
if (is_array($method)) {
$class = is_object($method[0]) ? $method[0] : self::invokeClass($method[0]);
$reflect = new \ReflectionMethod($class, $method[1]);
} else {
// 静态方法
$reflect = new \ReflectionMethod($method);
}
$args = self::bindParams($reflect, $vars);
self::$debug && Log::record('[ RUN ] ' . $reflect->class . '->' . $reflect->name . '[ ' . $reflect->getFileName() . ' ]', 'info');
return $reflect->invokeArgs(isset($class) ? $class : null, $args);
}

此时穿进去的$call也就是$method是一个数组,第一个元素是一个think\App对象,第二个元素则是调用方法名称的字符串invokefunction,然后通过反射ReflectionMethod获取这个对象下对应的方法。
再通过$args = self::bindParams($reflect, $vars);获取传入的参数,也就是Payload

最后在调用反射$reflect->invokeArgs($args);,将Payload数组传入反射对象函数invokeFunction,完成代码执行。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-107530-3.html
智商越来越低
却在这雇佣这么多水军
这个名字好