/** * 远程调用模块的操作方法 参数格式 [模块/控制器/]操作 * @param string $url 调用地址 * @param string|array $vars 调用参数 支持字符串和数组 * @param string $layer 要调用的控制层名称 * @param bool $appendSuffix 是否添加类名后缀 * @return mixed */ public static function action($url, $vars = [], $layer = 'Controller', $appendSuffix = false) { $info = pathinfo($url); $action = $info['basename']; $module = '.' != $info['dirname'] ? $info['dirname'] : \Norma\Request::instance()->controller(); $class = self::controller($module, $layer, $appendSuffix); if ($class) { if (is_scalar($vars)) { if (strpos($vars, '=')) { parse_str($vars, $vars); } else { $vars = [$vars]; } } return \Norma\App::invokeMethod([$class, $action . \Norma\Config::get('action_suffix')], $vars); } }
/** * 绑定参数 * @access public * @param \ReflectionMethod|\ReflectionFunction $reflect 反射类 * @param array $vars 变量 * @return array */ private static function bindParams($reflect, $vars) { $args = []; // 判断数组类型 数字数组时按顺序绑定参数 $type = key($vars) === 0 ? 1 : 0; if ($reflect->getNumberOfParameters() > 0) { $params = $reflect->getParameters(); foreach ($params as $param) { $name = $param->getName(); $class = $param->getClass(); if ($class && 'think\\Request' == $class->getName()) { $args[] = \Norma\Request::instance(); } elseif (1 == $type && !empty($vars)) { $args[] = array_shift($vars); } elseif (0 == $type && isset($vars[$name])) { $args[] = $vars[$name]; } elseif ($param->isDefaultValueAvailable()) { $args[] = $param->getDefaultValue(); } else { throw new \InvalidArgumentException('method param miss:' . $name); } } // 全局过滤 array_walk_recursive($args, [\Norma\Request::instance(), 'filterExp']); } return $args; }
/** * 解析URL地址中的参数Request对象 * @access private * @param string $rule 路由规则 * @param array $var 变量 * @return void */ private static function parseUrlParams($url, $var = []) { if ($url) { if (Config::get('url_param_type')) { $var += explode('/', $url); } else { preg_replace_callback('/(\\w+)\\/([^\\/]+)/', function ($match) use(&$var) { $var[$match[1]] = strip_tags($match[2]); }, $url); } } // 设置当前请求的参数 Request::instance()->route($var); }
/** * 自动定位模板文件 * @access private * @param string $template 模板文件规则 * @return string */ private function parseTemplate($template) { // 获取视图根目录 if (strpos($template, '@')) { // 跨模块调用 list($module, $template) = explode('@', $template); $path = APP_PATH . '/' . $module . DIRECTORY_SEPARATOR . 'view' . DIRECTORY_SEPARATOR; } else { // 当前视图目录 $path = $this->config['view_path']; } // 分析模板文件规则 $request = \Norma\Request::instance(); $controller = $request->controller(); if ($controller && 0 !== strpos($template, '/')) { $depr = $this->config['view_depr']; $template = str_replace(['/', ':'], $depr, $template); if ('' == $template) { // 如果模板文件名为空 按照默认规则定位 $template = str_replace('.', DIRECTORY_SEPARATOR, $controller) . $depr . $request->action(); } elseif (false === strpos($template, $depr)) { $template = str_replace('.', DIRECTORY_SEPARATOR, $controller) . $depr . $template; } } return $path . ltrim($template, '/') . '.' . ltrim($this->config['view_suffix'], '.'); }