ThinkPHP3.1.3源码分析(五) App.class.php
扫描二维码
随时随地手机看文章
Think.class.php 的 start()方法 最后 调用了App::run();
App类最重要的是两个部分
1、init()函数
a.过滤了$_GET,$_POST的数据
b.
// URL调度
Dispatcher::dispatch();
2、exec()函数
a.创建对应的Action
if(!preg_match('/^[A-Za-z](w)*$/',MODULE_NAME)){ // 安全检测
$module = false;
}else{
//创建Action控制器实例
$group = defined('GROUP_NAME') && C('APP_GROUP_MODE')==0 ? GROUP_NAME.'/' : '';
$module = A($group.MODULE_NAME);
}
b.调用对应的方法
try{
if(!preg_match('/^[A-Za-z](w)*$/',$action)){
// 非法操作
throw new ReflectionException();
}
//执行当前操作
$method = new ReflectionMethod($module, $action);
if($method->isPublic()) {
$class = new ReflectionClass($module);
// 前置操作
if($class->hasMethod('_before_'.$action)) {
$before = $class->getMethod('_before_'.$action);
if($before->isPublic()) {
$before->invoke($module);
}
}
// URL参数绑定检测
if(C('URL_PARAMS_BIND') && $method->getNumberOfParameters()>0){
switch($_SERVER['REQUEST_METHOD']) {
case 'POST':
$vars = array_merge($_GET,$_POST);
break;
case 'PUT':
parse_str(file_get_contents('php://input'), $vars);
break;
default:
$vars = $_GET;
}
$params = $method->getParameters();
foreach ($params as $param){
$name = $param->getName();
if(isset($vars[$name])) {
$args[] = $vars[$name];
}elseif($param->isDefaultValueAvailable()){
$args[] = $param->getDefaultValue();
}else{
throw_exception(L('_PARAM_ERROR_').':'.$name);
}
}
$method->invokeArgs($module,$args);
}else{
$method->invoke($module);
}
// 后置操作
if($class->hasMethod('_after_'.$action)) {
$after = $class->getMethod('_after_'.$action);
if($after->isPublic()) {
$after->invoke($module);
}
}
}else{
// 操作方法不是Public 抛出异常
throw new ReflectionException();
}
} catch (ReflectionException $e) {
// 方法调用发生异常后 引导到__call方法处理
$method = new ReflectionMethod($module,'__call');
$method->invokeArgs($module,array($action,''));
}
二、值得说的编程小细节:
在调用 Action对应方法的时候,使用了php中的反射机制