From c937fbdbd50984950991f182d3f09b8955bd4000 Mon Sep 17 00:00:00 2001 From: Lin07ux Date: Mon, 20 Nov 2017 15:11:56 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E5=85=A8=20Db=E3=80=81Debug=E3=80=81E?= =?UTF-8?q?nv=E3=80=81Error=E3=80=81Exception=E3=80=81File=E3=80=81Hook?= =?UTF-8?q?=E3=80=81Lang=E3=80=81Loader=E3=80=81Log=20=E7=B1=BB=E7=9A=84?= =?UTF-8?q?=E6=96=87=E6=A1=A3=EF=BC=8C=E8=B0=83=E6=95=B4=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- library/think/Db.php | 74 +++++++++----- library/think/Debug.php | 126 +++++++++++++++-------- library/think/Env.php | 11 +- library/think/Error.php | 25 +++-- library/think/Exception.php | 19 ++-- library/think/File.php | 197 ++++++++++++++++++++++-------------- library/think/Hook.php | 60 ++++++----- library/think/Lang.php | 134 +++++++++++++++--------- library/think/Loader.php | 165 +++++++++++++++++------------- library/think/Log.php | 188 +++++++++++++++++++--------------- 10 files changed, 613 insertions(+), 386 deletions(-) diff --git a/library/think/Db.php b/library/think/Db.php index ea0071a8..0f69979b 100644 --- a/library/think/Db.php +++ b/library/think/Db.php @@ -49,19 +49,26 @@ use think\db\Query; */ class Db { - // 数据库连接实例 + /** + * @var Connection[] 数据库连接实例 + */ private static $instance = []; - // 查询次数 + + /** + * @var int 查询次数 + */ public static $queryTimes = 0; - // 执行次数 + + /** + * @var int 执行次数 + */ public static $executeTimes = 0; /** - * 数据库初始化 并取得数据库类实例 - * @static + * 数据库初始化,并取得数据库类实例 * @access public - * @param mixed $config 连接配置 - * @param bool|string $name 连接标识 true 强制重新连接 + * @param mixed $config 连接配置 + * @param bool|string $name 连接标识 true 强制重新连接 * @return Connection * @throws Exception */ @@ -70,34 +77,48 @@ class Db if (false === $name) { $name = md5(serialize($config)); } + if (true === $name || !isset(self::$instance[$name])) { // 解析连接参数 支持数组和字符串 $options = self::parseConfig($config); + if (empty($options['type'])) { throw new \InvalidArgumentException('Undefined db type'); } - $class = false !== strpos($options['type'], '\\') ? $options['type'] : '\\think\\db\\connector\\' . ucwords($options['type']); + + $class = false !== strpos($options['type'], '\\') ? + $options['type'] : + '\\think\\db\\connector\\' . ucwords($options['type']); + // 记录初始化信息 if (App::$debug) { Log::record('[ DB ] INIT ' . $options['type'], 'info'); } + if (true === $name) { $name = md5(serialize($config)); } + self::$instance[$name] = new $class($options); } + return self::$instance[$name]; } - - public static function clear() { - self::$instance = null; + + /** + * 清除连接实例 + * @access public + * @return void + */ + public static function clear() + { + self::$instance = []; } /** * 数据库连接参数解析 - * @static * @access private - * @param mixed $config + * @param mixed $config 连接参数 * @return array */ private static function parseConfig($config) @@ -105,30 +126,27 @@ class Db if (empty($config)) { $config = Config::get('database'); } elseif (is_string($config) && false === strpos($config, '/')) { - // 支持读取配置参数 - $config = Config::get($config); - } - if (is_string($config)) { - return self::parseDsn($config); - } else { - return $config; + $config = Config::get($config); // 支持读取配置参数 } + + return is_string($config) ? self::parseDsn($config) : $config; } /** - * DSN解析 + * DSN 解析 * 格式: mysql://username:passwd@localhost:3306/DbName?param1=val1¶m2=val2#utf8 - * @static * @access private - * @param string $dsnStr + * @param string $dsnStr 数据库 DSN 字符串解析 * @return array */ private static function parseDsn($dsnStr) { $info = parse_url($dsnStr); + if (!$info) { return []; } + $dsn = [ 'type' => $info['scheme'], 'username' => isset($info['user']) ? $info['user'] : '', @@ -144,13 +162,19 @@ class Db } else { $dsn['params'] = []; } + return $dsn; } - // 调用驱动类的方法 + /** + * 调用驱动类的方法 + * @access public + * @param string $method 方法名 + * @param array $params 参数 + * @return mixed + */ public static function __callStatic($method, $params) { - // 自动初始化数据库 return call_user_func_array([self::connect(), $method], $params); } } diff --git a/library/think/Debug.php b/library/think/Debug.php index 9994e20c..d3d24429 100644 --- a/library/think/Debug.php +++ b/library/think/Debug.php @@ -16,21 +16,27 @@ use think\response\Redirect; class Debug { - // 区间时间信息 + /** + * @var array 区间时间信息 + */ protected static $info = []; - // 区间内存信息 + + /** + * @var array 区间内存信息 + */ protected static $mem = []; /** * 记录时间(微秒)和内存使用情况 - * @param string $name 标记位置 - * @param mixed $value 标记值 留空则取当前 time 表示仅记录时间 否则同时记录时间和内存 - * @return mixed + * @access public + * @param string $name 标记位置 + * @param mixed $value 标记值(留空则取当前 time 表示仅记录时间 否则同时记录时间和内存) + * @return void */ public static function remark($name, $value = '') { - // 记录时间和内存使用 self::$info[$name] = is_float($value) ? $value : microtime(true); + if ('time' != $value) { self::$mem['mem'][$name] = is_float($value) ? $value : memory_get_usage(); self::$mem['peak'][$name] = memory_get_peak_usage(); @@ -39,23 +45,26 @@ class Debug /** * 统计某个区间的时间(微秒)使用情况 返回值以秒为单位 - * @param string $start 开始标签 - * @param string $end 结束标签 - * @param integer|string $dec 小数位 - * @return integer + * @access public + * @param string $start 开始标签 + * @param string $end 结束标签 + * @param integer $dec 小数位 + * @return string */ public static function getRangeTime($start, $end, $dec = 6) { if (!isset(self::$info[$end])) { self::$info[$end] = microtime(true); } + return number_format((self::$info[$end] - self::$info[$start]), $dec); } /** * 统计从开始到统计时的时间(微秒)使用情况 返回值以秒为单位 - * @param integer|string $dec 小数位 - * @return integer + * @access public + * @param integer $dec 小数位 + * @return string */ public static function getUseTime($dec = 6) { @@ -64,6 +73,7 @@ class Debug /** * 获取当前访问的吞吐率情况 + * @access public * @return string */ public static function getThroughputRate() @@ -73,9 +83,10 @@ class Debug /** * 记录区间的内存使用情况 - * @param string $start 开始标签 - * @param string $end 结束标签 - * @param integer|string $dec 小数位 + * @access public + * @param string $start 开始标签 + * @param string $end 结束标签 + * @param integer $dec 小数位 * @return string */ public static function getRangeMem($start, $end, $dec = 2) @@ -83,19 +94,23 @@ class Debug if (!isset(self::$mem['mem'][$end])) { self::$mem['mem'][$end] = memory_get_usage(); } + $size = self::$mem['mem'][$end] - self::$mem['mem'][$start]; $a = ['B', 'KB', 'MB', 'GB', 'TB']; $pos = 0; + while ($size >= 1024) { $size /= 1024; $pos++; } + return round($size, $dec) . " " . $a[$pos]; } /** * 统计从开始到统计时的内存使用情况 - * @param integer|string $dec 小数位 + * @access public + * @param integer $dec 小数位 * @return string */ public static function getUseMem($dec = 2) @@ -103,103 +118,128 @@ class Debug $size = memory_get_usage() - THINK_START_MEM; $a = ['B', 'KB', 'MB', 'GB', 'TB']; $pos = 0; + while ($size >= 1024) { $size /= 1024; $pos++; } + return round($size, $dec) . " " . $a[$pos]; } /** * 统计区间的内存峰值情况 - * @param string $start 开始标签 - * @param string $end 结束标签 - * @param integer|string $dec 小数位 - * @return mixed + * @access public + * @param string $start 开始标签 + * @param string $end 结束标签 + * @param integer $dec 小数位 + * @return string */ public static function getMemPeak($start, $end, $dec = 2) { if (!isset(self::$mem['peak'][$end])) { self::$mem['peak'][$end] = memory_get_peak_usage(); } + $size = self::$mem['peak'][$end] - self::$mem['peak'][$start]; $a = ['B', 'KB', 'MB', 'GB', 'TB']; $pos = 0; + while ($size >= 1024) { $size /= 1024; $pos++; } + return round($size, $dec) . " " . $a[$pos]; } /** * 获取文件加载信息 - * @param bool $detail 是否显示详细 + * @access public + * @param bool $detail 是否显示详细 * @return integer|array */ public static function getFile($detail = false) { + $files = get_included_files(); + if ($detail) { - $files = get_included_files(); - $info = []; - foreach ($files as $key => $file) { + $info = []; + + foreach ($files as $file) { $info[] = $file . ' ( ' . number_format(filesize($file) / 1024, 2) . ' KB )'; } + return $info; } - return count(get_included_files()); + + return count($files); } /** * 浏览器友好的变量输出 - * @param mixed $var 变量 - * @param boolean $echo 是否输出 默认为true 如果为false 则返回输出字符串 - * @param string $label 标签 默认为空 - * @param integer $flags htmlspecialchars flags - * @return void|string + * @access public + * @param mixed $var 变量 + * @param boolean $echo 是否输出(默认为 true,为 false 则返回输出字符串) + * @param string|null $label 标签(默认为空) + * @param integer $flags htmlspecialchars 的标志 + * @return null|string */ public static function dump($var, $echo = true, $label = null, $flags = ENT_SUBSTITUTE) { $label = (null === $label) ? '' : rtrim($label) . ':'; + ob_start(); var_dump($var); - $output = ob_get_clean(); - $output = preg_replace('/\]\=\>\n(\s+)/m', '] => ', $output); + $output = preg_replace('/\]\=\>\n(\s+)/m', '] => ', ob_get_clean()); + if (IS_CLI) { $output = PHP_EOL . $label . $output . PHP_EOL; } else { if (!extension_loaded('xdebug')) { $output = htmlspecialchars($output, $flags); } + $output = '
' . $label . $output . '
'; } + if ($echo) { echo($output); return; - } else { - return $output; } + + return $output; } + /** + * 调试信息注入到响应中 + * @access public + * @param Response $response 响应实例 + * @param string $content 返回的字符串 + * @return void + */ public static function inject(Response $response, &$content) { - $config = Config::get('trace'); - $type = isset($config['type']) ? $config['type'] : 'Html'; - $request = Request::instance(); - $class = false !== strpos($type, '\\') ? $type : '\\think\\debug\\' . ucwords($type); + $config = Config::get('trace'); + $type = isset($config['type']) ? $config['type'] : 'Html'; + $class = false !== strpos($type, '\\') ? $type : '\\think\\debug\\' . ucwords($type); + unset($config['type']); - if (class_exists($class)) { - $trace = new $class($config); - } else { + + if (!class_exists($class)) { throw new ClassNotFoundException('class not exists:' . $class, $class); } + /** @var \think\debug\Console|\think\debug\Html $trace */ + $trace = new $class($config); + if ($response instanceof Redirect) { - //TODO 记录 + // TODO 记录 } else { $output = $trace->output($response, Log::getLog()); + if (is_string($output)) { - // trace调试信息注入 + // trace 调试信息注入 $pos = strripos($content, ''); if (false !== $pos) { $content = substr($content, 0, $pos) . $output . substr($content, $pos); diff --git a/library/think/Env.php b/library/think/Env.php index fa87897c..870ff319 100644 --- a/library/think/Env.php +++ b/library/think/Env.php @@ -15,22 +15,25 @@ class Env { /** * 获取环境变量值 - * @param string $name 环境变量名(支持二级 .号分割) - * @param string $default 默认值 + * @access public + * @param string $name 环境变量名(支持二级 . 号分割) + * @param string $default 默认值 * @return mixed */ public static function get($name, $default = null) { $result = getenv(ENV_PREFIX . strtoupper(str_replace('.', '_', $name))); + if (false !== $result) { if ('false' === $result) { $result = false; } elseif ('true' === $result) { $result = true; } + return $result; - } else { - return $default; } + + return $default; } } diff --git a/library/think/Error.php b/library/think/Error.php index 84386f81..69ee45c3 100644 --- a/library/think/Error.php +++ b/library/think/Error.php @@ -20,6 +20,7 @@ class Error { /** * 注册异常处理 + * @access public * @return void */ public static function register() @@ -32,12 +33,15 @@ class Error /** * 异常处理 - * @param \Exception|\Throwable $e 异常 + * @access public + * @param \Exception|\Throwable $e 异常 * @return void */ public static function appException($e) { - if (!$e instanceof \Exception) $e = new ThrowableError($e); + if (!$e instanceof \Exception) { + $e = new ThrowableError($e); + } $handler = self::getExceptionHandler(); $handler->report($e); @@ -51,11 +55,12 @@ class Error /** * 错误处理 + * @access public * @param integer $errno 错误编号 * @param integer $errstr 详细错误信息 * @param string $errfile 出错的文件 * @param integer $errline 出错行号 - * @param array $errcontext 出错上下文 + * @param array $errcontext 出错上下文 * @return void * @throws ErrorException */ @@ -64,13 +69,16 @@ class Error $exception = new ErrorException($errno, $errstr, $errfile, $errline, $errcontext); // 符合异常处理的则将错误信息托管至 think\exception\ErrorException - if (error_reporting() & $errno) throw $exception; + if (error_reporting() & $errno) { + throw $exception; + } self::getExceptionHandler()->report($exception); } /** * 异常中止处理 + * @access public * @return void */ public static function appShutdown() @@ -88,7 +96,8 @@ class Error /** * 确定错误类型是否致命 - * @param int $type + * @access protected + * @param int $type 错误类型 * @return bool */ protected static function isFatal($type) @@ -98,6 +107,7 @@ class Error /** * 获取异常处理的实例 + * @access public * @return Handle */ public static function getExceptionHandler() @@ -115,7 +125,10 @@ class Error } else { $handle = new Handle; - if ($class instanceof \Closure) $handle->setRender($class); + if ($class instanceof \Closure) { + $handle->setRender($class); + } + } } diff --git a/library/think/Exception.php b/library/think/Exception.php index 034c85b6..c4ecc015 100644 --- a/library/think/Exception.php +++ b/library/think/Exception.php @@ -13,15 +13,13 @@ namespace think; class Exception extends \Exception { - /** - * 保存异常页面显示的额外Debug数据 - * @var array + * @var array 保存异常页面显示的额外 Debug 数据 */ protected $data = []; /** - * 设置异常额外的Debug数据 + * 设置异常额外的 Debug 数据 * 数据将会显示为下面的格式 * * Exception Data @@ -33,8 +31,10 @@ class Exception extends \Exception * key1 value1 * key2 value2 * - * @param string $label 数据分类,用于异常页面显示 - * @param array $data 需要显示的数据,必须为关联数组 + * @access protected + * @param string $label 数据分类,用于异常页面显示 + * @param array $data 需要显示的数据,必须为关联数组 + * @return void */ final protected function setData($label, array $data) { @@ -42,13 +42,14 @@ class Exception extends \Exception } /** - * 获取异常额外Debug数据 + * 获取异常额外 Debug 数据 * 主要用于输出到异常页面便于调试 - * @return array 由setData设置的Debug数据 + * @access public + * @return array */ final public function getData() { return $this->data; } - + } diff --git a/library/think/File.php b/library/think/File.php index 8e606f75..48f3cb92 100644 --- a/library/think/File.php +++ b/library/think/File.php @@ -16,25 +16,51 @@ use SplFileObject; class File extends SplFileObject { /** - * 错误信息 - * @var string + * @var string 错误信息 */ private $error = ''; - // 当前完整文件名 + + /** + * @var string 当前完整文件名 + */ protected $filename; - // 上传文件名 + + /** + * @var string 上传文件名 + */ protected $saveName; - // 文件上传命名规则 + + /** + * @var string 文件上传命名规则 + */ protected $rule = 'date'; - // 文件上传验证规则 + + /** + * @var array 文件上传验证规则 + */ protected $validate = []; - // 单元测试 + + /** + * @var bool 单元测试 + */ protected $isTest; - // 上传文件信息 + + /** + * @var array 上传文件信息 + */ protected $info; - // 文件hash信息 + + /** + * @var array 文件 hash 信息 + */ protected $hash = []; + /** + * File constructor. + * @access public + * @param string $filename 文件名称 + * @param string $mode 访问模式 + */ public function __construct($filename, $mode = 'r') { parent::__construct($filename, $mode); @@ -42,30 +68,35 @@ class File extends SplFileObject } /** - * 是否测试 - * @param bool $test 是否测试 + * 设置是否是单元测试 + * @access public + * @param bool $test 是否是测试 * @return $this */ public function isTest($test = false) { $this->isTest = $test; + return $this; } /** * 设置上传信息 - * @param array $info 上传文件信息 + * @access public + * @param array $info 上传文件信息 * @return $this */ public function setUploadInfo($info) { $this->info = $info; + return $this; } /** * 获取上传文件的信息 - * @param string $name + * @access public + * @param string $name 信息名称 * @return array|string */ public function getInfo($name = '') @@ -75,6 +106,7 @@ class File extends SplFileObject /** * 获取上传文件的文件名 + * @access public * @return string */ public function getSaveName() @@ -84,18 +116,21 @@ class File extends SplFileObject /** * 设置上传文件的保存文件名 - * @param string $saveName + * @access public + * @param string $saveName 保存名称 * @return $this */ public function setSaveName($saveName) { $this->saveName = $saveName; + return $this; } /** * 获取文件的哈希散列值 - * @param string $type + * @access public + * @param string $type 类型 * @return string */ public function hash($type = 'sha1') @@ -103,75 +138,79 @@ class File extends SplFileObject if (!isset($this->hash[$type])) { $this->hash[$type] = hash_file($type, $this->filename); } + return $this->hash[$type]; } /** * 检查目录是否可写 - * @param string $path 目录 + * @access protected + * @param string $path 目录 * @return boolean */ protected function checkPath($path) { - if (is_dir($path)) { + if (is_dir($path) || mkdir($path, 0755, true)) { return true; } - if (mkdir($path, 0755, true)) { - return true; - } else { - $this->error = ['directory {:path} creation failed', ['path' => $path]]; - return false; - } + $this->error = ['directory {:path} creation failed', ['path' => $path]]; + + return false; } /** * 获取文件类型信息 + * @access public * @return string */ public function getMime() { $finfo = finfo_open(FILEINFO_MIME_TYPE); + return finfo_file($finfo, $this->filename); } /** * 设置文件的命名规则 - * @param string $rule 文件命名规则 + * @access public + * @param string $rule 文件命名规则 * @return $this */ public function rule($rule) { $this->rule = $rule; + return $this; } /** * 设置上传文件的验证规则 - * @param array $rule 验证规则 + * @access public + * @param array $rule 验证规则 * @return $this */ - public function validate($rule = []) + public function validate(array $rule = []) { $this->validate = $rule; + return $this; } /** * 检测是否合法的上传文件 + * @access public * @return bool */ public function isValid() { - if ($this->isTest) { - return is_file($this->filename); - } - return is_uploaded_file($this->filename); + return $this->isTest ? is_file($this->filename) : is_uploaded_file($this->filename); } /** * 检测上传文件 - * @param array $rule 验证规则 + * @access public + * @param array $rule 验证规则 * @return bool */ public function check($rule = []) @@ -184,7 +223,7 @@ class File extends SplFileObject return false; } - /* 检查文件Mime类型 */ + /* 检查文件 Mime 类型 */ if (isset($rule['type']) && !$this->checkMime($rule['type'])) { $this->error = 'mimetype to upload is not allowed'; return false; @@ -201,12 +240,14 @@ class File extends SplFileObject $this->error = 'illegal image files'; return false; } + return true; } /** * 检测上传文件后缀 - * @param array|string $ext 允许后缀 + * @access public + * @param array|string $ext 允许后缀 * @return bool */ public function checkExt($ext) @@ -217,79 +258,73 @@ class File extends SplFileObject $extension = strtolower(pathinfo($this->getInfo('name'), PATHINFO_EXTENSION)); - if (!in_array($extension, $ext)) { - return false; - } - return true; + return in_array($extension, $ext); } /** * 检测图像文件 + * @access public * @return bool */ public function checkImg() { $extension = strtolower(pathinfo($this->getInfo('name'), PATHINFO_EXTENSION)); - /* 对图像文件进行严格检测 */ - if (in_array($extension, ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'swf']) && !in_array($this->getImageType($this->filename), [1, 2, 3, 4, 6, 13])) { - return false; - } - return true; + // 如果上传的不是图片,或者是图片而且后缀确实符合图片类型则返回 true + return !in_array($extension, ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'swf']) || in_array($this->getImageType($this->filename), [1, 2, 3, 4, 6, 13]); } - // 判断图像类型 + /** + * 判断图像类型 + * @access protected + * @param string $image 图片名称 + * @return bool|int + */ protected function getImageType($image) { if (function_exists('exif_imagetype')) { return exif_imagetype($image); - } else { - try { - $info = getimagesize($image); - return $info ? $info[2] : false; - } catch (\Exception $e) { - return false; - } + } + + try { + $info = getimagesize($image); + return $info ? $info[2] : false; + } catch (\Exception $e) { + return false; } } /** * 检测上传文件大小 - * @param integer $size 最大大小 + * @access public + * @param integer $size 最大大小 * @return bool */ public function checkSize($size) { - if ($this->getSize() > $size) { - return false; - } - return true; + return $this->getSize() <= $size; } /** * 检测上传文件类型 - * @param array|string $mime 允许类型 + * @access public + * @param array|string $mime 允许类型 * @return bool */ public function checkMime($mime) { - if (is_string($mime)) { - $mime = explode(',', $mime); - } + $mime = is_string($mime) ? explode(',', $mime) : $mime; - if (!in_array(strtolower($this->getMime()), $mime)) { - return false; - } - - return true; + return in_array(strtolower($this->getMime()), $mime); } /** * 移动文件 - * @param string $path 保存路径 - * @param string|bool $savename 保存的文件名 默认自动生成 - * @param boolean $replace 同名文件是否覆盖 - * @return false|File false-失败 否则返回File实例 + * @access public + * @param string $path 保存路径 + * @param string|bool $savename 保存的文件名 默认自动生成 + * @param boolean $replace 同名文件是否覆盖 + * @return false|File */ public function move($path, $savename = true, $replace = true) { @@ -320,7 +355,7 @@ class File extends SplFileObject return false; } - /* 不覆盖同名文件 */ + // 不覆盖同名文件 if (!$replace && is_file($filename)) { $this->error = ['has the same filename: {:filename}', ['filename' => $filename]]; return false; @@ -334,23 +369,23 @@ class File extends SplFileObject return false; } - // 返回 File对象实例 + // 返回 File 对象实例 $file = new self($filename); - $file->setSaveName($saveName); - $file->setUploadInfo($this->info); + $file->setSaveName($saveName)->setUploadInfo($this->info); return $file; } /** * 获取保存文件名 - * @param string|bool $savename 保存的文件名 默认自动生成 + * @access protected + * @param string|bool $savename 保存的文件名 默认自动生成 * @return string */ protected function buildSaveName($savename) { + // 自动生成文件名 if (true === $savename) { - // 自动生成文件名 if ($this->rule instanceof \Closure) { $savename = call_user_func_array($this->rule, [$this]); } else { @@ -382,7 +417,9 @@ class File extends SplFileObject /** * 获取错误代码信息 - * @param int $errorNo 错误号 + * @access private + * @param int $errorNo 错误号 + * @return $this */ private function error($errorNo) { @@ -406,10 +443,13 @@ class File extends SplFileObject default: $this->error = 'unknown upload error'; } + + return $this; } /** * 获取错误信息(支持多语言) + * @access public * @return string */ public function getError() @@ -424,6 +464,13 @@ class File extends SplFileObject return Lang::has($msg) ? Lang::get($msg, $vars) : $msg; } + /** + * 魔法方法,获取文件的 hash 值 + * @access public + * @param string $method 方法名 + * @param mixed $args 调用参数 + * @return string + */ public function __call($method, $args) { return $this->hash($method); diff --git a/library/think/Hook.php b/library/think/Hook.php index f06196e4..a357c3b7 100644 --- a/library/think/Hook.php +++ b/library/think/Hook.php @@ -13,19 +13,23 @@ namespace think; class Hook { - + /** + * @var array 标签 + */ private static $tags = []; /** * 动态添加行为扩展到某个标签 - * @param string $tag 标签名称 - * @param mixed $behavior 行为名称 - * @param bool $first 是否放到开头执行 + * @access public + * @param string $tag 标签名称 + * @param mixed $behavior 行为名称 + * @param bool $first 是否放到开头执行 * @return void */ public static function add($tag, $behavior, $first = false) { isset(self::$tags[$tag]) || self::$tags[$tag] = []; + if (is_array($behavior) && !is_callable($behavior)) { if (!array_key_exists('_overlay', $behavior) || !$behavior['_overlay']) { unset($behavior['_overlay']); @@ -43,8 +47,10 @@ class Hook /** * 批量导入插件 - * @param array $tags 插件信息 - * @param boolean $recursive 是否递归合并 + * @access public + * @param array $tags 插件信息 + * @param boolean $recursive 是否递归合并 + * @return void */ public static function import(array $tags, $recursive = true) { @@ -59,55 +65,59 @@ class Hook /** * 获取插件信息 - * @param string $tag 插件位置 留空获取全部 + * @access public + * @param string $tag 插件位置(留空获取全部) * @return array */ public static function get($tag = '') { if (empty($tag)) { - //获取全部的插件信息 return self::$tags; - } else { - return array_key_exists($tag, self::$tags) ? self::$tags[$tag] : []; } + + return array_key_exists($tag, self::$tags) ? self::$tags[$tag] : []; } /** * 监听标签的行为 - * @param string $tag 标签名称 - * @param mixed $params 传入参数 - * @param mixed $extra 额外参数 - * @param bool $once 只获取一个有效返回值 + * @access public + * @param string $tag 标签名称 + * @param mixed $params 传入参数 + * @param mixed $extra 额外参数 + * @param bool $once 只获取一个有效返回值 * @return mixed */ public static function listen($tag, &$params = null, $extra = null, $once = false) { $results = []; - $tags = static::get($tag); - foreach ($tags as $key => $name) { + + foreach (static::get($tag) as $key => $name) { $results[$key] = self::exec($name, $tag, $params, $extra); - if (false === $results[$key]) { - // 如果返回false 则中断行为执行 - break; - } elseif (!is_null($results[$key]) && $once) { + + // 如果返回 false,或者仅获取一个有效返回则中断行为执行 + if (false === $results[$key] || (!is_null($results[$key]) && $once)) { break; } } + return $once ? end($results) : $results; } /** * 执行某个行为 - * @param mixed $class 要执行的行为 - * @param string $tag 方法名(标签名) - * @param Mixed $params 传人的参数 - * @param mixed $extra 额外参数 + * @access public + * @param mixed $class 要执行的行为 + * @param string $tag 方法名(标签名) + * @param mixed $params 传人的参数 + * @param mixed $extra 额外参数 * @return mixed */ public static function exec($class, $tag = '', &$params = null, $extra = null) { App::$debug && Debug::remark('behavior_start', 'time'); + $method = Loader::parseName($tag, 1, false); + if ($class instanceof \Closure) { $result = call_user_func_array($class, [ & $params, $extra]); $class = 'Closure'; @@ -126,10 +136,12 @@ class Hook $method = ($tag && is_callable([$obj, $method])) ? $method : 'run'; $result = $obj->$method($params, $extra); } + if (App::$debug) { Debug::remark('behavior_end', 'time'); Log::record('[ BEHAVIOR ] Run ' . $class . ' @' . $tag . ' [ RunTime:' . Debug::getRangeTime('behavior_start', 'behavior_end') . 's ]', 'info'); } + return $result; } diff --git a/library/think/Lang.php b/library/think/Lang.php index a4404f1e..7e31c942 100644 --- a/library/think/Lang.php +++ b/library/think/Lang.php @@ -13,114 +13,148 @@ namespace think; class Lang { - // 语言数据 + /** + * @var array 语言数据 + */ private static $lang = []; - // 语言作用域 - private static $range = 'zh-cn'; - // 语言自动侦测的变量 - protected static $langDetectVar = 'lang'; - // 语言Cookie变量 - protected static $langCookieVar = 'think_var'; - // 语言Cookie的过期时间 - protected static $langCookieExpire = 3600; - // 允许语言列表 - protected static $allowLangList = []; - // Accept-Language转义为对应语言包名称 系统默认配置 - protected static $acceptLanguage = [ - 'zh-hans-cn' => 'zh-cn', - ]; - // 设定当前的语言 + /** + * @var string 语言作用域 + */ + private static $range = 'zh-cn'; + + /** + * @var string 语言自动侦测的变量 + */ + protected static $langDetectVar = 'lang'; + + /** + * @var string 语言 Cookie 变量 + */ + protected static $langCookieVar = 'think_var'; + + /** + * @var int 语言 Cookie 的过期时间 + */ + protected static $langCookieExpire = 3600; + + /** + * @var array 允许语言列表 + */ + protected static $allowLangList = []; + + /** + * @var array Accept-Language 转义为对应语言包名称 系统默认配置 + */ + protected static $acceptLanguage = ['zh-hans-cn' => 'zh-cn']; + + /** + * 设定当前的语言 + * @access public + * @param string $range 语言作用域 + * @return string + */ public static function range($range = '') { - if ('' == $range) { - return self::$range; - } else { + if ($range) { self::$range = $range; } + return self::$range; } /** * 设置语言定义(不区分大小写) - * @param string|array $name 语言变量 - * @param string $value 语言值 - * @param string $range 语言作用域 + * @access public + * @param string|array $name 语言变量 + * @param string $value 语言值 + * @param string $range 语言作用域 * @return mixed */ public static function set($name, $value = null, $range = '') { $range = $range ?: self::$range; - // 批量定义 + if (!isset(self::$lang[$range])) { self::$lang[$range] = []; } + if (is_array($name)) { return self::$lang[$range] = array_change_key_case($name) + self::$lang[$range]; - } else { - return self::$lang[$range][strtolower($name)] = $value; } + + return self::$lang[$range][strtolower($name)] = $value; } /** * 加载语言定义(不区分大小写) - * @param array|string $file 语言文件 - * @param string $range 语言作用域 + * @access public + * @param array|string $file 语言文件 + * @param string $range 语言作用域 * @return mixed */ public static function load($file, $range = '') { $range = $range ?: self::$range; + $file = is_string($file) ? [$file] : $file; + if (!isset(self::$lang[$range])) { self::$lang[$range] = []; } - // 批量定义 - if (is_string($file)) { - $file = [$file]; - } + $lang = []; + foreach ($file as $_file) { if (is_file($_file)) { // 记录加载信息 App::$debug && Log::record('[ LANG ] ' . $_file, 'info'); + $_lang = include $_file; + if (is_array($_lang)) { $lang = array_change_key_case($_lang) + $lang; } } } + if (!empty($lang)) { self::$lang[$range] = $lang + self::$lang[$range]; } + return self::$lang[$range]; } /** * 获取语言定义(不区分大小写) - * @param string|null $name 语言变量 - * @param string $range 语言作用域 + * @access public + * @param string|null $name 语言变量 + * @param string $range 语言作用域 * @return mixed */ public static function has($name, $range = '') { $range = $range ?: self::$range; + return isset(self::$lang[$range][strtolower($name)]); } /** * 获取语言定义(不区分大小写) - * @param string|null $name 语言变量 - * @param array $vars 变量替换 - * @param string $range 语言作用域 + * @access public + * @param string|null $name 语言变量 + * @param array $vars 变量替换 + * @param string $range 语言作用域 * @return mixed */ public static function get($name = null, $vars = [], $range = '') { $range = $range ?: self::$range; + // 空参数返回所有定义 if (empty($name)) { return self::$lang[$range]; } + $key = strtolower($name); $value = isset(self::$lang[$range][$key]) ? self::$lang[$range][$key] : $name; @@ -145,45 +179,50 @@ class Lang } } + return $value; } /** * 自动侦测设置获取语言选择 + * @access public * @return string */ public static function detect() { - // 自动侦测设置获取语言选择 $langSet = ''; if (isset($_GET[self::$langDetectVar])) { - // url中设置了语言变量 + // url 中设置了语言变量 $langSet = strtolower($_GET[self::$langDetectVar]); } elseif (isset($_COOKIE[self::$langCookieVar])) { - // Cookie中设置了语言变量 + // Cookie 中设置了语言变量 $langSet = strtolower($_COOKIE[self::$langCookieVar]); } elseif (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { // 自动侦测浏览器语言 preg_match('/^([a-z\d\-]+)/i', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $matches); $langSet = strtolower($matches[1]); $acceptLangs = Config::get('header_accept_lang'); + if (isset($acceptLangs[$langSet])) { $langSet = $acceptLangs[$langSet]; } elseif (isset(self::$acceptLanguage[$langSet])) { $langSet = self::$acceptLanguage[$langSet]; } } + + // 合法的语言 if (empty(self::$allowLangList) || in_array($langSet, self::$allowLangList)) { - // 合法的语言 self::$range = $langSet ?: self::$range; } + return self::$range; } /** * 设置语言自动侦测的变量 - * @param string $var 变量名称 + * @access public + * @param string $var 变量名称 * @return void */ public static function setLangDetectVar($var) @@ -192,8 +231,9 @@ class Lang } /** - * 设置语言的cookie保存变量 - * @param string $var 变量名称 + * 设置语言的 cookie 保存变量 + * @access public + * @param string $var 变量名称 * @return void */ public static function setLangCookieVar($var) @@ -202,8 +242,9 @@ class Lang } /** - * 设置语言的cookie的过期时间 - * @param string $expire 过期时间 + * 设置语言的 cookie 的过期时间 + * @access public + * @param string $expire 过期时间 * @return void */ public static function setLangCookieExpire($expire) @@ -213,7 +254,8 @@ class Lang /** * 设置允许的语言列表 - * @param array $list 语言列表 + * @access public + * @param array $list 语言列表 * @return void */ public static function setAllowLangList($list) diff --git a/library/think/Loader.php b/library/think/Loader.php index 3c15b6d4..78a8a0fb 100644 --- a/library/think/Loader.php +++ b/library/think/Loader.php @@ -15,31 +15,55 @@ use think\exception\ClassNotFoundException; class Loader { - // 实例 + /** + * @var array 实例数组 + */ protected static $instance = []; - // 类名映射 + /** + * @var array 类名映射 + */ protected static $map = []; - // 命名空间别名 + /** + * @var array 命名空间别名 + */ protected static $namespaceAlias = []; - // PSR-4 + /** + * @var array PSR-4 命名空间前缀长度映射 + */ private static $prefixLengthsPsr4 = []; - private static $prefixDirsPsr4 = []; - private static $fallbackDirsPsr4 = []; - // PSR-0 - private static $prefixesPsr0 = []; + /** + * @var array PSR-4 的加载目录 + */ + private static $prefixDirsPsr4 = []; + + /** + * @var array PSR-4 加载失败的回退目录 + */ + private static $fallbackDirsPsr4 = []; + + /** + * @var array PSR-0 命名空间前缀映射 + */ + private static $prefixesPsr0 = []; + + /** + * @var array PSR-0 加载失败的回退目录 + */ private static $fallbackDirsPsr0 = []; - // 自动加载的文件 + /** + * @var array 自动加载的文件 + */ private static $autoloadFiles = []; /** * 自动加载 * @access public - * @param string $class 类名 + * @param string $class 类名 * @return bool */ public static function autoload($class) @@ -55,14 +79,12 @@ class Loader } } - $file = self::findFile($class); - $path = pathinfo($file, PATHINFO_FILENAME); - $realPath = pathinfo(realpath($file), PATHINFO_FILENAME); - - // 非 Win 环境不严格区分大小写 - if ($file && (!IS_WIN || $path == $realPath)) { - __include_file($file); - return true; + if ($file = self::findFile($class)) { + // 非 Win 环境不严格区分大小写 + if (!IS_WIN || pathinfo($file, PATHINFO_FILENAME) == pathinfo(realpath($file), PATHINFO_FILENAME)) { + __include_file($file); + return true; + } } return false; @@ -71,8 +93,8 @@ class Loader /** * 查找文件 * @access private - * @param string $class 类名 - * @return bool + * @param string $class 类名 + * @return bool|string */ private static function findFile($class) { @@ -133,14 +155,15 @@ class Loader } } + // 找不到则设置映射为 false 并返回 return self::$map[$class] = false; } /** * 注册 classmap * @access public - * @param string|array $class 类名 - * @param string $map 映射 + * @param string|array $class 类名 + * @param string $map 映射 * @return void */ public static function addClassMap($class, $map = '') @@ -155,8 +178,8 @@ class Loader /** * 注册命名空间 * @access public - * @param string|array $namespace 命名空间 - * @param string $path 路径 + * @param string|array $namespace 命名空间 + * @param string $path 路径 * @return void */ public static function addNamespace($namespace, $path = '') @@ -171,11 +194,11 @@ class Loader } /** - * 添加 Ps0 空间 + * 添加 PSR-0 命名空间 * @access private - * @param array|null $prefix 空间前缀 - * @param array $paths 路径 - * @param bool $prepend 预先设置的优先级更高 + * @param array|string $prefix 空间前缀 + * @param array $paths 路径 + * @param bool $prepend 预先设置的优先级更高 * @return void */ private static function addPsr0($prefix, $paths, $prepend = false) @@ -198,11 +221,11 @@ class Loader } /** - * 添加 Ps4 空间 + * 添加 PSR-4 空间 * @access private - * @param array|string $prefix 空间前缀 - * @param string $paths 路径 - * @param bool $prepend 预先设置的优先级更高 + * @param array|string $prefix 空间前缀 + * @param string $paths 路径 + * @param bool $prepend 预先设置的优先级更高 * @return void */ private static function addPsr4($prefix, $paths, $prepend = false) @@ -237,8 +260,8 @@ class Loader /** * 注册命名空间别名 * @access public - * @param array|string $namespace 命名空间 - * @param string $original 源文件 + * @param array|string $namespace 命名空间 + * @param string $original 源文件 * @return void */ public static function addNamespaceAlias($namespace, $original = '') @@ -253,7 +276,7 @@ class Loader /** * 注册自动加载机制 * @access public - * @param callable $autoload 自动加载处理方法 + * @param callable $autoload 自动加载处理方法 * @return void */ public static function register($autoload = null) @@ -325,9 +348,9 @@ class Loader /** * 导入所需的类库 同 Java 的 Import 本函数有缓存功能 * @access public - * @param string $class 类库命名空间字符串 - * @param string $baseUrl 起始路径 - * @param string $ext 导入的文件扩展名 + * @param string $class 类库命名空间字符串 + * @param string $baseUrl 起始路径 + * @param string $ext 导入的文件扩展名 * @return bool */ public static function import($class, $baseUrl = '', $ext = EXT) @@ -362,12 +385,9 @@ class Loader // 如果类存在则导入类库文件 if (is_array($baseUrl)) { foreach ($baseUrl as $path) { - $filename = $path . DS . $class . $ext; - - if (is_file($filename)) { + if (is_file($filename = $path . DS . $class . $ext)) { break; } - } } else { $filename = $baseUrl . $class . $ext; @@ -389,10 +409,10 @@ class Loader /** * 实例化(分层)模型 * @access public - * @param string $name Model名称 - * @param string $layer 业务层名称 - * @param bool $appendSuffix 是否添加类名后缀 - * @param string $common 公共模块名 + * @param string $name Model名称 + * @param string $layer 业务层名称 + * @param bool $appendSuffix 是否添加类名后缀 + * @param string $common 公共模块名 * @return object * @throws ClassNotFoundException */ @@ -424,10 +444,10 @@ class Loader /** * 实例化(分层)控制器 格式:[模块名/]控制器名 * @access public - * @param string $name 资源地址 - * @param string $layer 控制层名称 - * @param bool $appendSuffix 是否添加类名后缀 - * @param string $empty 空控制器名称 + * @param string $name 资源地址 + * @param string $layer 控制层名称 + * @param bool $appendSuffix 是否添加类名后缀 + * @param string $empty 空控制器名称 * @return object * @throws ClassNotFoundException */ @@ -453,16 +473,17 @@ class Loader /** * 实例化验证类 格式:[模块名/]验证器名 * @access public - * @param string $name 资源地址 - * @param string $layer 验证层名称 - * @param bool $appendSuffix 是否添加类名后缀 - * @param string $common 公共模块名 + * @param string $name 资源地址 + * @param string $layer 验证层名称 + * @param bool $appendSuffix 是否添加类名后缀 + * @param string $common 公共模块名 * @return object|false * @throws ClassNotFoundException */ public static function validate($name = '', $layer = 'validate', $appendSuffix = false, $common = 'common') { $name = $name ?: Config::get('default_validate'); + if (empty($name)) { return new Validate; } @@ -492,9 +513,9 @@ class Loader /** * 解析模块和类名 * @access protected - * @param string $name 资源地址 - * @param string $layer 验证层名称 - * @param bool $appendSuffix 是否添加类名后缀 + * @param string $name 资源地址 + * @param string $layer 验证层名称 + * @param bool $appendSuffix 是否添加类名后缀 * @return array */ protected static function getModuleAndClass($name, $layer, $appendSuffix) @@ -518,8 +539,8 @@ class Loader /** * 数据库初始化 并取得数据库类实例 * @access public - * @param mixed $config 数据库配置 - * @param bool|string $name 连接标识 true 强制重新连接 + * @param mixed $config 数据库配置 + * @param bool|string $name 连接标识 true 强制重新连接 * @return \think\db\Connection */ public static function db($config = [], $name = false) @@ -530,10 +551,10 @@ class Loader /** * 远程调用模块的操作方法 参数格式 [模块/控制器/]操作 * @access public - * @param string $url 调用地址 - * @param string|array $vars 调用参数 支持字符串和数组 - * @param string $layer 要调用的控制层名称 - * @param bool $appendSuffix 是否添加类名后缀 + * @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) @@ -562,9 +583,9 @@ class Loader * 字符串命名风格转换 * type 0 将 Java 风格转换为 C 的风格 1 将 C 风格转换为 Java 的风格 * @access public - * @param string $name 字符串 - * @param integer $type 转换类型 - * @param bool $ucfirst 首字母是否大写(驼峰规则) + * @param string $name 字符串 + * @param integer $type 转换类型 + * @param bool $ucfirst 首字母是否大写(驼峰规则) * @return string */ public static function parseName($name, $type = 0, $ucfirst = true) @@ -583,10 +604,10 @@ class Loader /** * 解析应用类的类名 * @access public - * @param string $module 模块名 - * @param string $layer 层名 controller model ... - * @param string $name 类名 - * @param bool $appendSuffix 是否添加类名后缀 + * @param string $module 模块名 + * @param string $layer 层名 controller model ... + * @param string $name 类名 + * @param bool $appendSuffix 是否添加类名后缀 * @return string */ public static function parseClass($module, $layer, $name, $appendSuffix = false) @@ -617,7 +638,7 @@ class Loader /** * include - * @param string $file 文件路径 + * @param string $file 文件路径 * @return mixed */ function __include_file($file) @@ -627,7 +648,7 @@ function __include_file($file) /** * require - * @param string $file 文件路径 + * @param string $file 文件路径 * @return mixed */ function __require_file($file) diff --git a/library/think/Log.php b/library/think/Log.php index a20ab262..6aa62a5e 100644 --- a/library/think/Log.php +++ b/library/think/Log.php @@ -17,12 +17,12 @@ use think\exception\ClassNotFoundException; * Class Log * @package think * - * @method void log($msg) static - * @method void error($msg) static - * @method void info($msg) static - * @method void sql($msg) static - * @method void notice($msg) static - * @method void alert($msg) static + * @method void log($msg) static 记录一般日志 + * @method void error($msg) static 记录错误日志 + * @method void info($msg) static 记录一般信息日志 + * @method void sql($msg) static 记录 SQL 查询日志 + * @method void notice($msg) static 记录提示日志 + * @method void alert($msg) static 记录报警日志 */ class Log { @@ -34,41 +34,60 @@ class Log const ALERT = 'alert'; const DEBUG = 'debug'; - // 日志信息 + /** + * @var array 日志信息 + */ protected static $log = []; - // 配置参数 + + /** + * @var array 配置参数 + */ protected static $config = []; - // 日志类型 + + /** + * @var array 日志类型 + */ protected static $type = ['log', 'error', 'info', 'sql', 'notice', 'alert', 'debug']; - // 日志写入驱动 + + /** + * @var log\driver\File|log\driver\Test|log\driver\Socket 日志写入驱动 + */ protected static $driver; - // 当前日志授权key + /** + * @var string 当前日志授权 key + */ protected static $key; /** * 日志初始化 - * @param array $config + * @access public + * @param array $config 配置参数 + * @return void */ public static function init($config = []) { - $type = isset($config['type']) ? $config['type'] : 'File'; - $class = false !== strpos($type, '\\') ? $type : '\\think\\log\\driver\\' . ucwords($type); self::$config = $config; unset($config['type']); + + $type = isset($config['type']) ? $config['type'] : 'File'; + $class = false !== strpos($type, '\\') ? $type : '\\think\\log\\driver\\' . ucwords($type); + if (class_exists($class)) { self::$driver = new $class($config); } else { throw new ClassNotFoundException('class not exists:' . $class, $class); } + // 记录初始化信息 App::$debug && Log::record('[ LOG ] INIT ' . $type, 'info'); } /** * 获取日志信息 - * @param string $type 信息类型 - * @return array + * @access public + * @param string $type 信息类型 + * @return array|string */ public static function getLog($type = '') { @@ -77,21 +96,22 @@ class Log /** * 记录调试信息 - * @param mixed $msg 调试信息 - * @param string $type 信息类型 + * @access public + * @param mixed $msg 调试信息 + * @param string $type 信息类型 * @return void */ public static function record($msg, $type = 'log') { self::$log[$type][] = $msg; - if (IS_CLI) { - // 命令行下面日志写入改进 - self::save(); - } + + // 命令行下面日志写入改进 + IS_CLI && self::save(); } /** * 清空日志信息 + * @access public * @return void */ public static function clear() @@ -100,8 +120,9 @@ class Log } /** - * 当前日志记录的授权key - * @param string $key 授权key + * 设置当前日志记录的授权 key + * @access public + * @param string $key 授权 key * @return void */ public static function key($key) @@ -111,102 +132,105 @@ class Log /** * 检查日志写入权限 - * @param array $config 当前日志配置参数 + * @access public + * @param array $config 当前日志配置参数 * @return bool */ public static function check($config) { - if (self::$key && !empty($config['allow_key']) && !in_array(self::$key, $config['allow_key'])) { - return false; - } - return true; + return !self::$key || empty($config['allow_key']) || in_array(self::$key, $config['allow_key']); } /** * 保存调试信息 + * @access public * @return bool */ public static function save() { - if (!empty(self::$log)) { - if (is_null(self::$driver)) { - self::init(Config::get('log')); - } - - if (!self::check(self::$config)) { - // 检测日志写入权限 - return false; - } - - if (empty(self::$config['level'])) { - // 获取全部日志 - $log = self::$log; - if (!App::$debug && isset($log['debug'])) { - unset($log['debug']); - } - } else { - // 记录允许级别 - $log = []; - foreach (self::$config['level'] as $level) { - if (isset(self::$log[$level])) { - $log[$level] = self::$log[$level]; - } - } - } - - $result = self::$driver->save($log); - if ($result) { - self::$log = []; - } - Hook::listen('log_write_done', $log); - return $result; + // 没有需要保存的记录则直接返回 + if (empty(self::$log)) { + return true; } - return true; + + is_null(self::$driver) && self::init(Config::get('log')); + + // 检测日志写入权限 + if (!self::check(self::$config)) { + return false; + } + + if (empty(self::$config['level'])) { + // 获取全部日志 + $log = self::$log; + if (!App::$debug && isset($log['debug'])) { + unset($log['debug']); + } + } else { + // 记录允许级别 + $log = []; + foreach (self::$config['level'] as $level) { + if (isset(self::$log[$level])) { + $log[$level] = self::$log[$level]; + } + } + } + + if ($result = self::$driver->save($log)) { + self::$log = []; + } + + Hook::listen('log_write_done', $log); + + return $result; } /** * 实时写入日志信息 并支持行为 - * @param mixed $msg 调试信息 - * @param string $type 信息类型 - * @param bool $force 是否强制写入 + * @access public + * @param mixed $msg 调试信息 + * @param string $type 信息类型 + * @param bool $force 是否强制写入 * @return bool */ public static function write($msg, $type = 'log', $force = false) { $log = self::$log; - // 封装日志信息 - if (true === $force || empty(self::$config['level'])) { - $log[$type][] = $msg; - } elseif (in_array($type, self::$config['level'])) { - $log[$type][] = $msg; - } else { + + // 如果不是强制写入,而且信息类型不在可记录的类别中则直接返回 false 不做记录 + if (true !== $force && !empty(self::$config['level']) && !in_array($type, self::$config['level'])) { return false; } - // 监听log_write + // 封装日志信息 + $log[$type][] = $msg; + + // 监听 log_write Hook::listen('log_write', $log); - if (is_null(self::$driver)) { - self::init(Config::get('log')); - } + + is_null(self::$driver) && self::init(Config::get('log')); + // 写入日志 - $result = self::$driver->save($log); - if ($result) { + if ($result = self::$driver->save($log)) { self::$log = []; } + return $result; } /** - * 静态调用 - * @param $method - * @param $args - * @return mixed + * 静态方法调用 + * @access public + * @param string $method 调用方法 + * @param mixed $args 参数 + * @return void */ public static function __callStatic($method, $args) { if (in_array($method, self::$type)) { array_push($args, $method); - return call_user_func_array('\\think\\Log::record', $args); + + call_user_func_array('\\think\\Log::record', $args); } }