ThinkPHP3.1.3源碼分析(五) App.class.php
Think.class.php 的 start()方法 最后 調(diào)用了App::run();
App類最重要的是兩個(gè)部分
1、init()函數(shù)
a.過濾了$_GET,$_POST的數(shù)據(jù)
b.?
// URL調(diào)度
Dispatcher::dispatch();
2、exec()函數(shù)
a.創(chuàng)建對應(yīng)的Action
if(!preg_match('/^[A-Za-z](w)*$/',MODULE_NAME)){ // 安全檢測
$module = false;
}else{
//創(chuàng)建Action控制器實(shí)例
$group = defined('GROUP_NAME') && C('APP_GROUP_MODE')==0 ? GROUP_NAME.'/' : '';
$module = A($group.MODULE_NAME);
}
b.調(diào)用對應(yīng)的方法
try{
if(!preg_match('/^[A-Za-z](w)*$/',$action)){
// 非法操作
throw new ReflectionException();
}
//執(zhí)行當(dāng)前操作
$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參數(shù)綁定檢測
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) {
// 方法調(diào)用發(fā)生異常后 引導(dǎo)到__call方法處理
$method = new ReflectionMethod($module,'__call');
$method->invokeArgs($module,array($action,''));
}
二、值得說的編程小細(xì)節(jié):
在調(diào)用 Action對應(yīng)方法的時(shí)候,使用了php中的反射機(jī)制