public static function set() { if (Request::getStorage('user')) { return static::$user = Request::getStorage('user'); } else { Debug::output(new Exception("不存在Request Storage内的user")); } }
/** * 调试输出接口 * @access public * @param Response $response Response对象 * @param array $log 日志信息 * @return bool */ public function output(Response $response, array $log = []) { $request = Request::instance(); $contentType = $response->getHeader('Content-Type'); $accept = $request->header('accept'); if (strpos($accept, 'application/json') === 0 || $request->isAjax()) { return false; } elseif (!empty($contentType) && strpos($contentType, 'html') === false) { return false; } // 获取基本信息 $runtime = number_format(microtime(true), 8, '.', '') - THINK_START_TIME; $reqs = number_format(1 / $runtime, 2); $mem = number_format((memory_get_usage() - THINK_START_MEM) / 1024, 2); // 页面Trace信息 if (isset($_SERVER['HTTP_HOST'])) { $uri = $_SERVER['SERVER_PROTOCOL'] . ' ' . $_SERVER['REQUEST_METHOD'] . ' : ' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; } else { $uri = 'cmd:' . implode(' ', $_SERVER['argv']); } $base = ['请求信息' => date('Y-m-d H:i:s', $_SERVER['REQUEST_TIME']) . ' ' . $uri, '运行时间' => number_format($runtime, 6) . 's [ 吞吐率:' . $reqs . 'req/s ] 内存消耗:' . $mem . 'kb 文件加载:' . count(get_included_files()), '查询信息' => Db::$queryTimes . ' queries ' . Db::$executeTimes . ' writes ', '缓存信息' => Cache::$readTimes . ' reads,' . Cache::$writeTimes . ' writes', '配置加载' => count(Config::get())]; if (session_id()) { $base['会话信息'] = 'SESSION_ID=' . session_id(); } $info = Debug::getFile(true); // 页面Trace信息 $trace = []; foreach ($this->config['trace_tabs'] as $name => $title) { $name = strtolower($name); switch ($name) { case 'base': // 基本信息 $trace[$title] = $base; break; case 'file': // 文件信息 $trace[$title] = $info; break; default: // 调试信息 if (strpos($name, '|')) { // 多组信息 $names = explode('|', $name); $result = []; foreach ($names as $name) { $result = array_merge($result, isset($log[$name]) ? $log[$name] : []); } $trace[$title] = $result; } else { $trace[$title] = isset($log[$name]) ? $log[$name] : ''; } } } // 调用Trace页面模板 ob_start(); include $this->config['trace_file']; return ob_get_clean(); }
public function testRun() { $response = App::run(Request::create("http://www.example.com")); $expectOutputString = '<style type="text/css">*{ padding: 0; margin: 0; } div{ padding: 4px 48px;} a{color:#2E5CD5;cursor: pointer;text-decoration: none} a:hover{text-decoration:underline; } body{ background: #fff; font-family: "Century Gothic","Microsoft yahei"; color: #333;font-size:18px} h1{ font-size: 100px; font-weight: normal; margin-bottom: 12px; } p{ line-height: 1.6em; font-size: 42px }</style><div style="padding: 24px 48px;"> <h1>:)</h1><p> ThinkPHP V5<br/><span style="font-size:30px">十年磨一剑 - 为API开发设计的高性能框架</span></p><span style="font-size:22px;">[ V5.0 版本由 <a href="http://www.qiniu.com" target="qiniu">七牛云</a> 独家赞助发布 ]</span></div><script type="text/javascript" src="http://tajs.qq.com/stats?sId=9347272" charset="UTF-8"></script><script type="text/javascript" src="http://ad.topthink.com/Public/static/client.js"></script><thinkad id="ad_bd568ce7058a1091"></thinkad>'; $this->assertEquals($expectOutputString, $response->getContent()); $this->assertEquals(200, $response->getCode()); $this->assertEquals(true, function_exists('lang')); $this->assertEquals(true, function_exists('config')); $this->assertEquals(true, function_exists('input')); $this->assertEquals(Config::get('default_timezone'), date_default_timezone_get()); }
/** * 处理数据 * @access protected * @param mixed $data 要处理的数据 * @return mixed */ protected function output($data) { // 返回JSON数据格式到客户端 包含状态信息 [当url_common_param为false时是无法获取到$_GET的数据的,故使用Request来获取<*****@*****.**>] $var_jsonp_handler = Request::instance()->param($this->options['var_jsonp_handler'], ""); $handler = !empty($var_jsonp_handler) ? $var_jsonp_handler : $this->options['default_jsonp_handler']; $data = json_encode($data, $this->options['json_encode_param']); if ($data === false) { throw new \InvalidArgumentException(json_last_error_msg()); } $data = $handler . '(' . $data . ');'; return $data; }
/** * @covers think\Response::send * @todo Implement testSend(). */ public function testSend() { $dataArr = []; $dataArr["key"] = "value"; $response = Response::create($dataArr, 'json'); $result = $response->getContent(); $this->assertEquals('{"key":"value"}', $result); $request = Request::instance(); $request->get(['callback' => 'callback']); $response = Response::create($dataArr, 'jsonp'); $result = $response->getContent(); $this->assertEquals('callback({"key":"value"});', $result); }
/** * 定义系统常量 */ public function module_init() { $request = \think\Request::instance(); $method = $request->method(); define('IS_GET', $method == 'GET' ? true : false); define('IS_POST', $method == 'POST' ? true : false); define('IS_PUT', $method == 'PUT' ? true : false); define('IS_DELETE', $method == 'DELETE' ? true : false); define('IS_AJAX', $request->isAjax()); define('IS_PJAX', $request->isPjax()); define('NOW_TIME', $request->time()); define('MODULE_NAME', $request->module()); define('CONTROLLER_NAME', $request->controller()); define('ACTION_NAME', $request->action()); define('__SELF__', $request->url(true)); }
/** * 架构函数 * @param Request $request Request对象 * @access public */ public function __construct(Request $request = null) { if (is_null($request)) { $request = Request::instance(); } $this->view = View::instance(Config::get('template'), Config::get('view_replace_str')); $this->request = $request; // 控制器初始化 $this->_initialize(); // 前置操作方法 if ($this->beforeActionList) { foreach ($this->beforeActionList as $method => $options) { is_numeric($method) ? $this->beforeAction($options) : $this->beforeAction($method, $options); } } }
public function fetch($template, $data = [], $cache = []) { if (!$template) { $request = Request::instance(); $controller = $request->controller(); $action = $request->action(); $template = $controller . DS . $action; } // 根据模版文件名定位缓存文件 $tpl_cache_file = CACHE_PATH . 'angular_' . md5($template) . '.php'; if (App::$debug || !is_file($tpl_cache_file) || !$this->storage->check($tpl_cache_file, 0)) { // 编译模板内容 $content = $this->template->compiler($template, $data); $this->storage->write($tpl_cache_file, $content); } $this->storage->read($tpl_cache_file, $data); }
/** * 上传文件 * @param string $name input name * @param array $options 扩展配置 * @return array|boolean */ public function upload($name = '', $options = []) { $File = Request::instance()->file($name); // 检查是否有该文件,如果上传过,直接返回文件信息 $info = $this->where('hash', $File->hash())->find(); if ($info) { return ['file_id' => $info->id, 'path' => ltrim($info->path, '.')]; } // 合并扩展选项 $config = Config::get('storage'); if (is_array($options) && !empty($options)) { $config = array_merge($config, $options); } // 校验文件是否允许上传 if (!$File->check($config)) { $this->error = $File->getError(); return false; } else { // 保存的规则 $File->rule(function ($file) { $rule = explode('/', $file->getMime())[0] . '/'; $rule .= date('Y-m/d'); $rule .= '/' . $file->hash(); $rule .= '.' . strtolower(pathinfo($file->getInfo('name'), PATHINFO_EXTENSION)); return $rule; }); // 上传文件 $info = $File->move($config['path'], true, $config['replace']); if ($info) { $data = ['type' => explode('/', $info->getMime())[0], 'name' => rtrim($info->getInfo('name'), '.' . $info->getExtension()), 'ext' => $info->getExtension(), 'hash' => $info->hash(), 'path' => ltrim($info->getPathname(), '.'), 'size' => $info->getSize()]; // 保存文件信息 if ($insert = parent::create($data)) { return ['file_id' => $insert->id, 'path' => ltrim($insert->path, '.')]; } else { $this->error = '数据保存失败'; return false; } } else { $this->error = $File->getError(); return false; } } }
/** * 架构函数 取得模板对象实例 * @access public */ public function __construct() { // 资源类型检测 $request = Request::instance(); $ext = $request->ext(); if ('' == $ext) { // 自动检测资源类型 $this->type = $request->type(); } elseif (!preg_match('/\\(' . $this->restTypeList . '\\)$/i', $ext)) { // 资源类型非法 则用默认资源类型访问 $this->type = $this->restDefaultType; } else { $this->type = $ext; } // 请求方式检测 $method = strtolower($request->method()); if (false === stripos($this->restMethodList, $method)) { // 请求方式非法 则用默认请求方法 $method = $this->restDefaultMethod; } $this->method = $method; }
public function testValidate() { $controller = new Foo(Request::instance()); $result = $controller->test(); $this->assertTrue($result); }
/** * 解析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); }
/** * 获取当前的response 输出类型 * @access protected * @return string */ protected function getResponseType() { $isAjax = Request::instance()->isAjax(); return $isAjax ? Config::get('default_ajax_return') : Config::get('default_return_type'); }
/** * 生成表单令牌 * @param string $name 令牌名称 * @param mixed $type 令牌生成方法 * @return string */ function token($name = '__token__', $type = 'md5') { $token = Request::instance()->token($name, $type); return '<input type="hidden" name="' . $name . '" value="' . $token . '" />'; }
public function testDomain() { $request = Request::create('http://subdomain.thinkphp.cn'); Route::domain('subdomain.thinkphp.cn', 'sub?abc=test&status=1'); $rules = Route::rules('GET'); Route::checkDomain($request, $rules); $this->assertEquals('sub', Route::getbind('module')); $this->assertEquals('test', $_GET['abc']); $this->assertEquals(1, $_GET['status']); Route::domain('subdomain.thinkphp.cn', '\\app\\index\\controller'); $rules = Route::rules('GET'); Route::checkDomain($request, $rules); $this->assertEquals('\\app\\index\\controller', Route::getbind('namespace')); Route::domain(['subdomain.thinkphp.cn' => '@\\app\\index\\controller\\blog']); $rules = Route::rules('GET'); Route::checkDomain($request, $rules); $this->assertEquals('\\app\\index\\controller\\blog', Route::getbind('class')); }
/** * 验证请求类型 * @access protected * @param mixed $value 字段值 * @param mixed $rule 验证规则 * @return bool */ protected function method($value, $rule) { $method = Request::instance()->method(); return strtoupper($rule) == $method; }
/** * 自动获取当前的path * @return string */ public static function getCurrentPath() { return Request::instance()->baseUrl(); }
/** * 获取当前Request对象实例 * @return \think\Request */ function request() { return Request::instance(); }
public static function inject(Response $response) { $config = Config::get('trace'); $type = isset($config['type']) ? $config['type'] : 'Html'; $request = Request::instance(); $accept = $request->header('accept'); $contentType = $response->getHeader('Content-Type'); $class = false !== strpos($type, '\\') ? $type : '\\think\\debug\\' . ucwords($type); unset($config['type']); if (class_exists($class)) { $trace = new $class($config); } else { throw new ClassNotFoundException('class not exists:' . $class, $class); } if ($response instanceof Redirect) { //TODO 记录 } else { $output = $trace->output($response, Log::getLog()); if (is_string($output)) { // trace调试信息注入 $content = $response->getContent(); $pos = strripos($content, '</body>'); if (false !== $pos) { $content = substr($content, 0, $pos) . $output . substr($content, $pos); } else { $content = $content . $output; } $response->content($content); } } }
/** * 记住当前url后跳转 */ public function remember() { Session::set('redirect_url', Request::instance()->url()); }
/** * URL路由检测(根据PATH_INFO) * @access public * @param \think\Request $request * @param array $config * @return array * @throws \think\Exception */ public static function routeCheck($request, array $config) { $path = $request->path(); $depr = $config['pathinfo_depr']; $result = false; // 路由检测 $check = !is_null(self::$routeCheck) ? self::$routeCheck : $config['url_route_on']; if ($check) { // 开启路由 if (!empty($config['route'])) { // 导入路由配置 Route::import($config['route']); } // 路由检测(根据路由定义返回不同的URL调度) $result = Route::check($request, $path, $depr, $config['url_domain_deploy']); $must = !is_null(self::$routeMust) ? self::$routeMust : $config['url_route_must']; if ($must && false === $result) { // 路由无效 throw new HttpException(404, 'Route Not Found'); } } if (false === $result) { // 路由无效 解析模块/控制器/操作/参数... 支持控制器自动搜索 $result = Route::parseUrl($path, $depr, $config['controller_auto_search']); } return $result; }
/** * 远程调用模块的操作方法 参数格式 [模块/控制器/]操作 * @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'] : 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 App::invokeMethod([$class, $action . Config::get('action_suffix')], $vars); } }
<?php // +------------------------------------------------+ // |http://www.cjango.com | // +------------------------------------------------+ // | 修复BUG不是一朝一夕的事情,等我喝醉了再说吧! | // +------------------------------------------------+ // | Author: 小陈叔叔 <Jason.Chen> | // +------------------------------------------------+ return ['log' => ['type' => 'file', 'path' => LOG_PATH . 'index/', 'time_format' => ' c ', 'file_size' => 2097152], 'template' => ['tpl_cache' => !APP_DEBUG, 'strip_space' => false, 'taglib_pre_load' => '', 'cache_path' => TEMP_PATH . 'index/'], 'view_replace_str' => ['__SELF__' => \think\Request::instance()->url(true), '__CDN__' => '//cdn.' . ROOT_DOMAIN, '__CSS__' => '//cdn.' . ROOT_DOMAIN . '/index/css', '__JS__' => '//cdn.' . ROOT_DOMAIN . '/index/js', '__IMG__' => '//cdn.' . ROOT_DOMAIN . '/index/images', '__LIB__' => '//cdn.' . ROOT_DOMAIN . '/index/lib']];
public function testBind() { $request = new Request(); $request->user = '******'; $request->bind(['user' => 'User2']); $this->assertEquals('User2', $request->user); }
/** * 自动定位模板文件 * @access private * @param string $template 模板文件规则 * @return string */ private function parseTemplate($template) { if (empty($this->config['view_path'])) { $this->config['view_path'] = App::$modulePath . 'view' . DS; } if (strpos($template, '@')) { list($module, $template) = explode('@', $template); $path = APP_PATH . $module . DS . 'view' . DS; } else { $path = $this->config['view_path']; } // 分析模板文件规则 $request = Request::instance(); $controller = Loader::parseName($request->controller()); if ($controller && 0 !== strpos($template, '/')) { $depr = $this->config['view_depr']; $template = str_replace(['/', ':'], $depr, $template); if ('' == $template) { // 如果模板文件名为空 按照默认规则定位 $template = str_replace('.', DS, $controller) . $depr . $request->action(); } elseif (false === strpos($template, $depr)) { $template = str_replace('.', DS, $controller) . $depr . $template; } } return $path . ltrim($template, '/') . '.' . ltrim($this->config['view_suffix'], '.'); }
private function parseTemplate($template) { $request = Request::instance(); $depr = $this->config['view_depr']; $controller = Loader::parseName($request->controller()); if ($controller && 0 !== strpos($template, '/')) { if ('' == $template) { // 如果模板文件名为空 按照默认规则定位 $template = str_replace('.', DS, $controller) . $depr . $request->action(); } elseif (false === strpos($template, '/')) { $template = str_replace('.', DS, $controller) . $depr . $template; } } return str_replace('/', $depr, $template) . $this->config['view_suffix']; }
/** * URL路由检测(根据PATH_INFO) * @access public * @param \think\Request $request * @param array $config * @throws Exception */ public static function route($request, array $config) { define('__INFO__', $request->pathinfo()); define('__EXT__', $request->ext()); // 检测URL禁用后缀 if ($config['url_deny_suffix'] && preg_match('/\\.(' . $config['url_deny_suffix'] . ')$/i', __INFO__)) { throw new Exception('url suffix deny'); } $_SERVER['PATH_INFO'] = $request->path(); $depr = $config['pathinfo_depr']; $result = false; // 路由检测 if (APP_ROUTE_ON && !empty($config['url_route_on'])) { // 开启路由 if (!empty($config['route'])) { // 导入路由配置 Route::import($config['route']); } // 路由检测(根据路由定义返回不同的URL调度) $result = Route::check($request, $_SERVER['PATH_INFO'], $depr, !IS_CLI ? $config['url_domain_deploy'] : false); if (APP_ROUTE_MUST && false === $result && $config['url_route_must']) { // 路由无效 throw new Exception('route not define '); } } if (false === $result) { // 路由无效默认分析为模块/控制器/操作/参数...方式URL $result = Route::parseUrl($_SERVER['PATH_INFO'], $depr); } //保证$_REQUEST正常取值 $_REQUEST = array_merge($_POST, $_GET, $_COOKIE); // 注册调度机制 return $request->dispatch($result); }
public function run(Request $request) { define('MODULE_NAME', $request->module()); define('CONTROLLER_NAME', $request->controller()); define('ACTION_NAME', $request->action()); }
<?php // +------------------------------------------------+ // |http://www.cjango.com | // +------------------------------------------------+ // | 修复BUG不是一朝一夕的事情,等我喝醉了再说吧! | // +------------------------------------------------+ // | Author: 小陈叔叔 <Jason.Chen> | // +------------------------------------------------+ return ['log' => ['type' => 'file', 'path' => LOG_PATH . 'system/', 'time_format' => ' c ', 'file_size' => 2097152], 'template' => ['tpl_cache' => !APP_DEBUG, 'strip_space' => false, 'taglib_pre_load' => '', 'cache_path' => TEMP_PATH . 'system/'], 'view_replace_str' => ['__SELF__' => \think\Request::instance()->url(true), '__CDN__' => '//cdn.' . ROOT_DOMAIN, '__CSS__' => '//cdn.' . ROOT_DOMAIN . '/system/css', '__JS__' => '//cdn.' . ROOT_DOMAIN . '/system/js', '__IMG__' => '//cdn.' . ROOT_DOMAIN . '/system/img', '__LIB__' => '//cdn.' . ROOT_DOMAIN . '/system/lib'], 'backdata' => ['path' => realpath('../backup/data/') . DS, 'part' => 2097152, 'compress' => true, 'level' => 9]];
public static function root($root) { self::$root = $root; Request::instance()->root($root); }