调整 Build、Cache、Collection、Config、Console、Controller、Cookie 的代码样式

This commit is contained in:
Lin07ux
2017-11-11 17:56:42 +08:00
committed by ThinkPHP
parent 75ddca152a
commit 5df96ceff5
7 changed files with 794 additions and 508 deletions

View File

@@ -15,21 +15,27 @@ class Build
{ {
/** /**
* 根据传入的 build 资料创建目录和文件 * 根据传入的 build 资料创建目录和文件
* @access protected * @access public
* @param array $build build 列表 * @param array $build build 列表
* @param string $namespace 应用类库命名空间 * @param string $namespace 应用类库命名空间
* @param bool $suffix 类库后缀 * @param bool $suffix 类库后缀
* @return void * @return void
* @throws Exception
*/ */
public static function run(array $build = [], $namespace = 'app', $suffix = false) public static function run(array $build = [], $namespace = 'app', $suffix = false)
{ {
// 锁定 // 锁定
$lockfile = APP_PATH . 'build.lock'; $lock = APP_PATH . 'build.lock';
if (is_writable($lockfile)) {
return; // 如果锁定文件不可写(不存在)则进行处理,否则表示已经有程序在处理了
} elseif (!touch($lockfile)) { if (!is_writable($lock)) {
throw new Exception('应用目录[' . APP_PATH . ']不可写,目录无法自动生成!<BR>请手动生成项目目录~', 10006); if (!touch($lock)) {
throw new Exception(
'应用目录[' . APP_PATH . ']不可写,目录无法自动生成!<BR>请手动生成项目目录~',
10006
);
} }
foreach ($build as $module => $list) { foreach ($build as $module => $list) {
if ('__dir__' == $module) { if ('__dir__' == $module) {
// 创建目录列表 // 创建目录列表
@@ -42,8 +48,10 @@ class Build
self::module($module, $list, $namespace, $suffix); self::module($module, $list, $namespace, $suffix);
} }
} }
// 解除锁定 // 解除锁定
unlink($lockfile); unlink($lock);
}
} }
/** /**
@@ -55,10 +63,8 @@ class Build
protected static function buildDir($list) protected static function buildDir($list)
{ {
foreach ($list as $dir) { foreach ($list as $dir) {
if (!is_dir(APP_PATH . $dir)) { // 目录不存在则创建目录
// 创建目录 !is_dir(APP_PATH . $dir) && mkdir(APP_PATH . $dir, 0755, true);
mkdir(APP_PATH . $dir, 0755, true);
}
} }
} }
@@ -71,12 +77,17 @@ class Build
protected static function buildFile($list) protected static function buildFile($list)
{ {
foreach ($list as $file) { foreach ($list as $file) {
// 先创建目录
if (!is_dir(APP_PATH . dirname($file))) { if (!is_dir(APP_PATH . dirname($file))) {
// 创建目录
mkdir(APP_PATH . dirname($file), 0755, true); mkdir(APP_PATH . dirname($file), 0755, true);
} }
// 再创建文件
if (!is_file(APP_PATH . $file)) { if (!is_file(APP_PATH . $file)) {
file_put_contents(APP_PATH . $file, 'php' == pathinfo($file, PATHINFO_EXTENSION) ? "<?php\n" : ''); file_put_contents(
APP_PATH . $file,
'php' == pathinfo($file, PATHINFO_EXTENSION) ? "<?php\n" : ''
);
} }
} }
} }
@@ -92,27 +103,29 @@ class Build
*/ */
public static function module($module = '', $list = [], $namespace = 'app', $suffix = false) public static function module($module = '', $list = [], $namespace = 'app', $suffix = false)
{ {
$module = $module ? $module : ''; $module = $module ?: '';
if (!is_dir(APP_PATH . $module)) {
// 创建模块目录 // 创建模块目录
mkdir(APP_PATH . $module); !is_dir(APP_PATH . $module) && mkdir(APP_PATH . $module);
}
// 如果不是 runtime 目录则需要创建配置文件和公共文件、创建模块的默认页面
if (basename(RUNTIME_PATH) != $module) { if (basename(RUNTIME_PATH) != $module) {
// 创建配置文件和公共文件
self::buildCommon($module); self::buildCommon($module);
// 创建模块的默认页面
self::buildHello($module, $namespace, $suffix); self::buildHello($module, $namespace, $suffix);
} }
// 未指定文件和目录,则创建默认的模块目录和文件
if (empty($list)) { if (empty($list)) {
// 创建默认的模块目录和文件
$list = [ $list = [
'__file__' => ['config.php', 'common.php'], '__file__' => ['config.php', 'common.php'],
'__dir__' => ['controller', 'model', 'view'], '__dir__' => ['controller', 'model', 'view'],
]; ];
} }
// 创建子目录和文件 // 创建子目录和文件
foreach ($list as $path => $file) { foreach ($list as $path => $file) {
$modulePath = APP_PATH . $module . DS; $modulePath = APP_PATH . $module . DS;
if ('__dir__' == $path) { if ('__dir__' == $path) {
// 生成子目录 // 生成子目录
foreach ($file as $dir) { foreach ($file as $dir) {
@@ -122,7 +135,10 @@ class Build
// 生成(空白)文件 // 生成(空白)文件
foreach ($file as $name) { foreach ($file as $name) {
if (!is_file($modulePath . $name)) { if (!is_file($modulePath . $name)) {
file_put_contents($modulePath . $name, 'php' == pathinfo($name, PATHINFO_EXTENSION) ? "<?php\n" : ''); file_put_contents(
$modulePath . $name,
'php' == pathinfo($name, PATHINFO_EXTENSION) ? "<?php\n" : ''
);
} }
} }
} else { } else {
@@ -132,6 +148,7 @@ class Build
$filename = $modulePath . $path . DS . $val . ($suffix ? ucfirst($path) : '') . EXT; $filename = $modulePath . $path . DS . $val . ($suffix ? ucfirst($path) : '') . EXT;
$space = $namespace . '\\' . ($module ? $module . '\\' : '') . $path; $space = $namespace . '\\' . ($module ? $module . '\\' : '') . $path;
$class = $val . ($suffix ? ucfirst($path) : ''); $class = $val . ($suffix ? ucfirst($path) : '');
switch ($path) { switch ($path) {
case 'controller': // 控制器 case 'controller': // 控制器
$content = "<?php\nnamespace {$space};\n\nclass {$class}\n{\n\n}"; $content = "<?php\nnamespace {$space};\n\nclass {$class}\n{\n\n}";
@@ -159,7 +176,7 @@ class Build
/** /**
* 创建模块的欢迎页面 * 创建模块的欢迎页面
* @access public * @access protected
* @param string $module 模块名 * @param string $module 模块名
* @param string $namespace 应用类库命名空间 * @param string $namespace 应用类库命名空间
* @param bool $suffix 类库后缀 * @param bool $suffix 类库后缀
@@ -167,10 +184,19 @@ class Build
*/ */
protected static function buildHello($module, $namespace, $suffix = false) protected static function buildHello($module, $namespace, $suffix = false)
{ {
$filename = APP_PATH . ($module ? $module . DS : '') . 'controller' . DS . 'Index' . ($suffix ? 'Controller' : '') . EXT; $filename = APP_PATH . ($module ? $module . DS : '') .
'controller' . DS . 'Index' .
($suffix ? 'Controller' : '') . EXT;
if (!is_file($filename)) { if (!is_file($filename)) {
$content = file_get_contents(THINK_PATH . 'tpl' . DS . 'default_index.tpl'); $module = $module ? $module . '\\' : '';
$content = str_replace(['{$app}', '{$module}', '{layer}', '{$suffix}'], [$namespace, $module ? $module . '\\' : '', 'controller', $suffix ? 'Controller' : ''], $content); $suffix = $suffix ? 'Controller' : '';
$content = str_replace(
['{$app}', '{$module}', '{layer}', '{$suffix}'],
[$namespace, $module, 'controller', $suffix],
file_get_contents(THINK_PATH . 'tpl' . DS . 'default_index.tpl')
);
self::checkDirBuild(dirname($filename)); self::checkDirBuild(dirname($filename));
file_put_contents($filename, $content); file_put_contents($filename, $content);
} }
@@ -178,28 +204,32 @@ class Build
/** /**
* 创建模块的公共文件 * 创建模块的公共文件
* @access public * @access protected
* @param string $module 模块名 * @param string $module 模块名
* @return void * @return void
*/ */
protected static function buildCommon($module) protected static function buildCommon($module)
{ {
$filename = CONF_PATH . ($module ? $module . DS : '') . 'config.php'; $config = CONF_PATH . ($module ? $module . DS : '') . 'config.php';
self::checkDirBuild(dirname($filename)); self::checkDirBuild(dirname($config));
if (!is_file($filename)) {
file_put_contents($filename, "<?php\n//配置文件\nreturn [\n\n];"); if (!is_file($config)) {
} file_put_contents($config, "<?php\n//配置文件\nreturn [\n\n];");
$filename = APP_PATH . ($module ? $module . DS : '') . 'common.php';
if (!is_file($filename)) {
file_put_contents($filename, "<?php\n");
}
} }
$common = APP_PATH . ($module ? $module . DS : '') . 'common.php';
if (!is_file($common)) file_put_contents($common, "<?php\n");
}
/**
* 创建目录
* @access protected
* @param string $dirname 目录名称
* @return void
*/
protected static function checkDirBuild($dirname) protected static function checkDirBuild($dirname)
{ {
if (!is_dir($dirname)) { !is_dir($dirname) && mkdir($dirname, 0755, true);
mkdir($dirname, 0755, true);
}
} }
} }

View File

@@ -15,19 +15,28 @@ use think\cache\Driver;
class Cache class Cache
{ {
protected static $instance = []; /**
* @var array 缓存的实例
*/
public static $instance = [];
/**
* @var int 缓存读取次数
*/
public static $readTimes = 0; public static $readTimes = 0;
/**
* @var int 缓存写入次数
*/
public static $writeTimes = 0; public static $writeTimes = 0;
/** /**
* 操作句柄 * @var object 操作句柄
* @var object
* @access protected
*/ */
protected static $handler; public static $handler;
/** /**
* 连接缓存 * 连接缓存驱动
* @access public * @access public
* @param array $options 配置数组 * @param array $options 配置数组
* @param bool|string $name 缓存连接标识 true 强制重新连接 * @param bool|string $name 缓存连接标识 true 强制重新连接
@@ -36,21 +45,22 @@ class Cache
public static function connect(array $options = [], $name = false) public static function connect(array $options = [], $name = false)
{ {
$type = !empty($options['type']) ? $options['type'] : 'File'; $type = !empty($options['type']) ? $options['type'] : 'File';
if (false === $name) {
$name = md5(serialize($options)); if (false === $name) $name = md5(serialize($options));
}
if (true === $name || !isset(self::$instance[$name])) { if (true === $name || !isset(self::$instance[$name])) {
$class = false !== strpos($type, '\\') ? $type : '\\think\\cache\\driver\\' . ucwords($type); $class = false === strpos($type, '\\') ?
'\\think\\cache\\driver\\' . ucwords($type) :
$type;
// 记录初始化信息 // 记录初始化信息
App::$debug && Log::record('[ CACHE ] INIT ' . $type, 'info'); App::$debug && Log::record('[ CACHE ] INIT ' . $type, 'info');
if (true === $name) {
return new $class($options); if (true === $name) return new $class($options);
} else {
self::$instance[$name] = new $class($options); self::$instance[$name] = new $class($options);
} }
}
return self::$instance[$name]; return self::$instance[$name];
} }
@@ -63,7 +73,6 @@ class Cache
public static function init(array $options = []) public static function init(array $options = [])
{ {
if (is_null(self::$handler)) { if (is_null(self::$handler)) {
// 自动初始化缓存
if (!empty($options)) { if (!empty($options)) {
$connect = self::connect($options); $connect = self::connect($options);
} elseif ('complex' == Config::get('cache.type')) { } elseif ('complex' == Config::get('cache.type')) {
@@ -71,8 +80,10 @@ class Cache
} else { } else {
$connect = self::connect(Config::get('cache')); $connect = self::connect(Config::get('cache'));
} }
self::$handler = $connect; self::$handler = $connect;
} }
return self::$handler; return self::$handler;
} }
@@ -87,6 +98,7 @@ class Cache
if ('' !== $name && 'complex' == Config::get('cache.type')) { if ('' !== $name && 'complex' == Config::get('cache.type')) {
return self::connect(Config::get('cache.' . $name), strtolower($name)); return self::connect(Config::get('cache.' . $name), strtolower($name));
} }
return self::init(); return self::init();
} }
@@ -99,6 +111,7 @@ class Cache
public static function has($name) public static function has($name)
{ {
self::$readTimes++; self::$readTimes++;
return self::init()->has($name); return self::init()->has($name);
} }
@@ -112,6 +125,7 @@ class Cache
public static function get($name, $default = false) public static function get($name, $default = false)
{ {
self::$readTimes++; self::$readTimes++;
return self::init()->get($name, $default); return self::init()->get($name, $default);
} }
@@ -126,6 +140,7 @@ class Cache
public static function set($name, $value, $expire = null) public static function set($name, $value, $expire = null)
{ {
self::$writeTimes++; self::$writeTimes++;
return self::init()->set($name, $value, $expire); return self::init()->set($name, $value, $expire);
} }
@@ -139,6 +154,7 @@ class Cache
public static function inc($name, $step = 1) public static function inc($name, $step = 1)
{ {
self::$writeTimes++; self::$writeTimes++;
return self::init()->inc($name, $step); return self::init()->inc($name, $step);
} }
@@ -152,6 +168,7 @@ class Cache
public static function dec($name, $step = 1) public static function dec($name, $step = 1)
{ {
self::$writeTimes++; self::$writeTimes++;
return self::init()->dec($name, $step); return self::init()->dec($name, $step);
} }
@@ -164,6 +181,7 @@ class Cache
public static function rm($name) public static function rm($name)
{ {
self::$writeTimes++; self::$writeTimes++;
return self::init()->rm($name); return self::init()->rm($name);
} }
@@ -176,6 +194,7 @@ class Cache
public static function clear($tag = null) public static function clear($tag = null)
{ {
self::$writeTimes++; self::$writeTimes++;
return self::init()->clear($tag); return self::init()->clear($tag);
} }
@@ -189,6 +208,7 @@ class Cache
{ {
self::$readTimes++; self::$readTimes++;
self::$writeTimes++; self::$writeTimes++;
return self::init()->pull($name); return self::init()->pull($name);
} }
@@ -203,6 +223,7 @@ class Cache
public static function remember($name, $value, $expire = null) public static function remember($name, $value, $expire = null)
{ {
self::$readTimes++; self::$readTimes++;
return self::init()->remember($name, $value, $expire); return self::init()->remember($name, $value, $expire);
} }

View File

@@ -19,20 +19,35 @@ use JsonSerializable;
class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable
{ {
/**
* @var array 数据
*/
protected $items = []; protected $items = [];
/**
* Collection constructor.
* @access public
* @param array $items 数据
*/
public function __construct($items = []) public function __construct($items = [])
{ {
$this->items = $this->convertToArray($items); $this->items = $this->convertToArray($items);
} }
/**
* 创建 Collection 实例
* @access public
* @param array $items 数据
* @return static
*/
public static function make($items = []) public static function make($items = [])
{ {
return new static($items); return new static($items);
} }
/** /**
* 是否为空 * 判断数据是否为空
* @access public
* @return bool * @return bool
*/ */
public function isEmpty() public function isEmpty()
@@ -40,43 +55,33 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria
return empty($this->items); return empty($this->items);
} }
/**
* 将数据转成数组
* @access public
* @return array
*/
public function toArray() public function toArray()
{ {
return array_map(function ($value) { return array_map(function ($value) {
return ($value instanceof Model || $value instanceof self) ? $value->toArray() : $value; return ($value instanceof Model || $value instanceof self) ?
$value->toArray() :
$value;
}, $this->items); }, $this->items);
} }
/**
* 获取全部的数据
* @access public
* @return array
*/
public function all() public function all()
{ {
return $this->items; return $this->items;
} }
/**
* 合并数组
*
* @param mixed $items
* @return static
*/
public function merge($items)
{
return new static(array_merge($this->items, $this->convertToArray($items)));
}
/**
* 比较数组,返回差集
*
* @param mixed $items
* @return static
*/
public function diff($items)
{
return new static(array_diff($this->items, $this->convertToArray($items)));
}
/** /**
* 交换数组中的键和值 * 交换数组中的键和值
* * @access public
* @return static * @return static
*/ */
public function flip() public function flip()
@@ -85,19 +90,8 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria
} }
/** /**
* 比较数组,返回交集 * 返回数组中所有的键名组成的新 Collection 实例
* * @access public
* @param mixed $items
* @return static
*/
public function intersect($items)
{
return new static(array_intersect($this->items, $this->convertToArray($items)));
}
/**
* 返回数组中所有的键名
*
* @return static * @return static
*/ */
public function keys() public function keys()
@@ -106,8 +100,41 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria
} }
/** /**
* 删除数组的最后一个元素(出栈) * 合并数组并返回一个新的 Collection 实例
* * @access public
* @param mixed $items 新的数据
* @return static
*/
public function merge($items)
{
return new static(array_merge($this->items, $this->convertToArray($items)));
}
/**
* 比较数组,返回差集生成的新 Collection 实例
* @access public
* @param mixed $items 做比较的数据
* @return static
*/
public function diff($items)
{
return new static(array_diff($this->items, $this->convertToArray($items)));
}
/**
* 比较数组,返回交集组成的 Collection 新实例
* @access public
* @param mixed $items 比较数据
* @return static
*/
public function intersect($items)
{
return new static(array_intersect($this->items, $this->convertToArray($items)));
}
/**
* 返回并删除数据中的的最后一个元素(出栈)
* @access public
* @return mixed * @return mixed
*/ */
public function pop() public function pop()
@@ -116,30 +143,8 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria
} }
/** /**
* 通过使用用户自定义函数,以字符串返回数组 * 返回并删除数据中首个元素
* * @access public
* @param callable $callback
* @param mixed $initial
* @return mixed
*/
public function reduce(callable $callback, $initial = null)
{
return array_reduce($this->items, $callback, $initial);
}
/**
* 以相反的顺序返回数组。
*
* @return static
*/
public function reverse()
{
return new static(array_reverse($this->items));
}
/**
* 删除数组中首个元素,并返回被删除元素的值
*
* @return mixed * @return mixed
*/ */
public function shift() public function shift()
@@ -148,10 +153,64 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria
} }
/** /**
* 把一个数组分割为新的数组块. * 在数组开头插入一个元素
* * @access public
* @param int $size * @param mixed $value 值
* @param bool $preserveKeys * @param mixed $key 键名
* @return void
*/
public function unshift($value, $key = null)
{
if (is_null($key)) {
array_unshift($this->items, $value);
} else {
$this->items = [$key => $value] + $this->items;
}
}
/**
* 在数组结尾插入一个元素
* @access public
* @param mixed $value 值
* @param mixed $key 键名
* @return void
*/
public function push($value, $key = null)
{
if (is_null($key)) {
$this->items[] = $value;
} else {
$this->items[$key] = $value;
}
}
/**
* 通过使用用户自定义函数,以字符串返回数组
* @access public
* @param callable $callback 回调函数
* @param mixed $initial 初始值
* @return mixed
*/
public function reduce(callable $callback, $initial = null)
{
return array_reduce($this->items, $callback, $initial);
}
/**
* 以相反的顺序创建一个新的 Collection 实例
* @access public
* @return static
*/
public function reverse()
{
return new static(array_reverse($this->items));
}
/**
* 把数据分割为新的数组块
* @access public
* @param int $size 分隔长度
* @param bool $preserveKeys 是否保持原数据索引
* @return static * @return static
*/ */
public function chunk($size, $preserveKeys = false) public function chunk($size, $preserveKeys = false)
@@ -166,73 +225,40 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria
} }
/** /**
* 在数组开头插入一个元素 * 给数据中的每个元素执行回调
* @param mixed $value * @access public
* @param miexed $key * @param callable $callback 回调函数
* @return void
*/
public function unshift($value, $key = null)
{
if (is_null($key)) {
array_unshift($this->items, $value);
} else {
$this->items = [$key => $value] + $this->items;
}
}
/**
* 在数组结尾插入一个元素
* @param mixed $value
* @param mixed $key
* @return void
*/
public function push($value, $key = null)
{
if (is_null($key)) {
$this->items[] = $value;
} else {
$this->items[$key] = $value;
}
}
/**
* 给每个元素执行个回调
*
* @param callable $callback
* @return $this * @return $this
*/ */
public function each(callable $callback) public function each(callable $callback)
{ {
foreach ($this->items as $key => $item) { foreach ($this->items as $key => $item) {
$result = $callback($item, $key); $result = $callback($item, $key);
if (false === $result) {
break; if (false === $result) break;
} elseif (!is_object($item)) {
$this->items[$key] = $result; if (!is_object($item)) $this->items[$key] = $result;
}
} }
return $this; return $this;
} }
/** /**
* 用回调函数过滤数中的元素 * 用回调函数过滤数中的元素
* @param callable|null $callback * @access public
* @param callable|null $callback 回调函数
* @return static * @return static
*/ */
public function filter(callable $callback = null) public function filter(callable $callback = null)
{ {
if ($callback) { return new static(array_filter($this->items, $callback ?: null));
return new static(array_filter($this->items, $callback));
}
return new static(array_filter($this->items));
} }
/** /**
* 返回数中指定的一列 * 返回数中指定的一列
* @param $column_key * @access public
* @param null $index_key * @param mixed $column_key 键名
* @param null $index_key 作为索引值的列
* @return array * @return array
*/ */
public function column($column_key, $index_key = null) public function column($column_key, $index_key = null)
@@ -245,10 +271,12 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria
foreach ($this->items as $row) { foreach ($this->items as $row) {
$key = $value = null; $key = $value = null;
$keySet = $valueSet = false; $keySet = $valueSet = false;
if (null !== $index_key && array_key_exists($index_key, $row)) { if (null !== $index_key && array_key_exists($index_key, $row)) {
$keySet = true;
$key = (string) $row[$index_key]; $key = (string) $row[$index_key];
$keySet = true;
} }
if (null === $column_key) { if (null === $column_key) {
$valueSet = true; $valueSet = true;
$value = $row; $value = $row;
@@ -256,6 +284,7 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria
$valueSet = true; $valueSet = true;
$value = $row[$column_key]; $value = $row[$column_key];
} }
if ($valueSet) { if ($valueSet) {
if ($keySet) { if ($keySet) {
$result[$key] = $value; $result[$key] = $value;
@@ -264,51 +293,44 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria
} }
} }
} }
return $result; return $result;
} }
/** /**
* 对数组排序 * 对数据排序,并返回排序后的数据组成的新 Collection 实例
* * @access public
* @param callable|null $callback * @param callable|null $callback 回调函数
* @return static * @return static
*/ */
public function sort(callable $callback = null) public function sort(callable $callback = null)
{ {
$items = $this->items; $items = $this->items;
$callback = $callback ?: function ($a, $b) {
return $a == $b ? 0 : (($a < $b) ? -1 : 1);
};
$callback ? uasort($items, $callback) : uasort($items, function ($a, $b) { return new static(uasort($items, $callback));
if ($a == $b) {
return 0;
}
return ($a < $b) ? -1 : 1;
});
return new static($items);
} }
/** /**
* 将数打乱 * 将数打乱后组成新的 Collection 实例
* * @access public
* @return static * @return static
*/ */
public function shuffle() public function shuffle()
{ {
$items = $this->items; $items = $this->items;
shuffle($items); return new static(shuffle($items));
return new static($items);
} }
/** /**
* 截取数 * 截取数据并返回新的 Collection 实例
* * @access public
* @param int $offset * @param int $offset 起始位置
* @param int $length * @param int $length 截取长度
* @param bool $preserveKeys * @param bool $preserveKeys 是否保持原先的键名
* @return static * @return static
*/ */
public function slice($offset, $length = null, $preserveKeys = false) public function slice($offset, $length = null, $preserveKeys = false)
@@ -316,17 +338,35 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria
return new static(array_slice($this->items, $offset, $length, $preserveKeys)); return new static(array_slice($this->items, $offset, $length, $preserveKeys));
} }
// ArrayAccess /**
* 指定的键是否存在
* @access public
* @param mixed $offset 键名
* @return bool
*/
public function offsetExists($offset) public function offsetExists($offset)
{ {
return array_key_exists($offset, $this->items); return array_key_exists($offset, $this->items);
} }
/**
* 获取指定键对应的值
* @access public
* @param mixed $offset 键名
* @return mixed
*/
public function offsetGet($offset) public function offsetGet($offset)
{ {
return $this->items[$offset]; return $this->items[$offset];
} }
/**
* 设置键值
* @access public
* @param mixed $offset 键名
* @param mixed $value 值
* @return void
*/
public function offsetSet($offset, $value) public function offsetSet($offset, $value)
{ {
if (is_null($offset)) { if (is_null($offset)) {
@@ -336,24 +376,42 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria
} }
} }
/**
* 删除指定键值
* @access public
* @param mixed $offset 键名
* @return void
*/
public function offsetUnset($offset) public function offsetUnset($offset)
{ {
unset($this->items[$offset]); unset($this->items[$offset]);
} }
//Countable /**
* 统计数据的个数
* @access public
* @return int
*/
public function count() public function count()
{ {
return count($this->items); return count($this->items);
} }
//IteratorAggregate /**
* 获取数据的迭代器
* @access public
* @return ArrayIterator
*/
public function getIterator() public function getIterator()
{ {
return new ArrayIterator($this->items); return new ArrayIterator($this->items);
} }
//JsonSerializable /**
* 将数据反序列化成数组
* @access public
* @return array
*/
public function jsonSerialize() public function jsonSerialize()
{ {
return $this->toArray(); return $this->toArray();
@@ -370,22 +428,24 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria
return json_encode($this->toArray(), $options); return json_encode($this->toArray(), $options);
} }
/**
* 将数据转换成字符串
* @access public
* @return string
*/
public function __toString() public function __toString()
{ {
return $this->toJson(); return $this->toJson();
} }
/** /**
* 转换成数组 * 将数据转换成数组
* * @access protected
* @param mixed $items * @param mixed $items 数据
* @return array * @return array
*/ */
protected function convertToArray($items) protected function convertToArray($items)
{ {
if ($items instanceof self) { return $items instanceof self ? $items->all() : (array) $items;
return $items->all();
}
return (array) $items;
} }
} }

View File

@@ -25,6 +25,7 @@ class Config
/** /**
* 设定配置参数的作用域 * 设定配置参数的作用域
* @access public
* @param string $range 作用域 * @param string $range 作用域
* @return void * @return void
*/ */
@@ -37,6 +38,7 @@ class Config
/** /**
* 解析配置文件或内容 * 解析配置文件或内容
* @access public
* @param string $config 配置文件路径或内容 * @param string $config 配置文件路径或内容
* @param string $type 配置解析类型 * @param string $type 配置解析类型
* @param string $name 配置名(如设置即表示二级配置) * @param string $name 配置名(如设置即表示二级配置)
@@ -58,6 +60,7 @@ class Config
/** /**
* 加载配置文件PHP格式 * 加载配置文件PHP格式
* @access public
* @param string $file 配置文件名 * @param string $file 配置文件名
* @param string $name 配置名(如设置即表示二级配置) * @param string $name 配置名(如设置即表示二级配置)
* @param string $range 作用域 * @param string $range 作用域
@@ -89,6 +92,7 @@ class Config
/** /**
* 检测配置是否存在 * 检测配置是否存在
* @access public
* @param string $name 配置参数名(支持二级配置 . 号分割) * @param string $name 配置参数名(支持二级配置 . 号分割)
* @param string $range 作用域 * @param string $range 作用域
* @return bool * @return bool
@@ -108,6 +112,7 @@ class Config
/** /**
* 获取配置参数 为空则获取所有配置 * 获取配置参数 为空则获取所有配置
* @access public
* @param string $name 配置参数名(支持二级配置 . 号分割) * @param string $name 配置参数名(支持二级配置 . 号分割)
* @param string $range 作用域 * @param string $range 作用域
* @return mixed * @return mixed
@@ -146,6 +151,7 @@ class Config
/** /**
* 设置配置参数 name 为数组则为批量设置 * 设置配置参数 name 为数组则为批量设置
* @access public
* @param string|array $name 配置参数名(支持二级配置 . 号分割) * @param string|array $name 配置参数名(支持二级配置 . 号分割)
* @param mixed $value 配置值 * @param mixed $value 配置值
* @param string $range 作用域 * @param string $range 作用域
@@ -191,6 +197,7 @@ class Config
/** /**
* 重置配置参数 * 重置配置参数
* @access public
* @param string $range 作用域 * @param string $range 作用域
* @return void * @return void
*/ */

View File

@@ -20,20 +20,49 @@ use think\console\output\driver\Buffer;
class Console class Console
{ {
/**
* @var string 命令名称
*/
private $name; private $name;
/**
* @var string 命令版本
*/
private $version; private $version;
/** @var Command[] */ /**
* @var Command[] 命令
*/
private $commands = []; private $commands = [];
/**
* @var bool 是否需要帮助信息
*/
private $wantHelps = false; private $wantHelps = false;
/**
* @var bool 是否捕获异常
*/
private $catchExceptions = true; private $catchExceptions = true;
/**
* @var bool 是否自动退出执行
*/
private $autoExit = true; private $autoExit = true;
/**
* @var InputDefinition 输入定义
*/
private $definition; private $definition;
/**
* @var string 默认执行的命令
*/
private $defaultCommand; private $defaultCommand;
/**
* @var array 默认提供的命令
*/
private static $defaultCommands = [ private static $defaultCommands = [
"think\\console\\command\\Help", "think\\console\\command\\Help",
"think\\console\\command\\Lists", "think\\console\\command\\Lists",
@@ -47,6 +76,12 @@ class Console
"think\\console\\command\\optimize\\Schema", "think\\console\\command\\optimize\\Schema",
]; ];
/**
* Console constructor.
* @access public
* @param string $name 名称
* @param string $version 版本
*/
public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN') public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN')
{ {
$this->name = $name; $this->name = $name;
@@ -60,38 +95,44 @@ class Console
} }
} }
/**
* 初始化 Console
* @access public
* @param bool $run 是否运行 Console
* @return int|Console
*/
public static function init($run = true) public static function init($run = true)
{ {
static $console; static $console;
if (!$console) { if (!$console) {
// 实例化 console // 实例化 console
$console = new self('Think Console', '0.1'); $console = new self('Think Console', '0.1');
// 读取指令集 // 读取指令集
if (is_file(CONF_PATH . 'command' . EXT)) { if (is_file(CONF_PATH . 'command' . EXT)) {
$commands = include CONF_PATH . 'command' . EXT; $commands = include CONF_PATH . 'command' . EXT;
if (is_array($commands)) { if (is_array($commands)) {
foreach ($commands as $command) { foreach ($commands as $command) {
if (class_exists($command) && is_subclass_of($command, "\\think\\console\\Command")) { class_exists($command) &&
// 注册指令 is_subclass_of($command, "\\think\\console\\Command") &&
$console->add(new $command()); $console->add(new $command()); // 注册指令
} }
} }
} }
} }
}
if ($run) { return $run ? $console->run() : $console;
// 运行 }
return $console->run();
} else {
return $console;
}
}
/** /**
* @param $command * 调用命令
* @access public
* @param string $command
* @param array $parameters * @param array $parameters
* @param string $driver * @param string $driver
* @return Output|Buffer * @return Output
*/ */
public static function call($command, array $parameters = [], $driver = 'buffer') public static function call($command, array $parameters = [], $driver = 'buffer')
{ {
@@ -110,9 +151,9 @@ class Console
/** /**
* 执行当前的指令 * 执行当前的指令
* @access public
* @return int * @return int
* @throws \Exception * @throws \Exception
* @api
*/ */
public function run() public function run()
{ {
@@ -124,27 +165,21 @@ class Console
try { try {
$exitCode = $this->doRun($input, $output); $exitCode = $this->doRun($input, $output);
} catch (\Exception $e) { } catch (\Exception $e) {
if (!$this->catchExceptions) { if (!$this->catchExceptions) throw $e;
throw $e;
}
$output->renderException($e); $output->renderException($e);
$exitCode = $e->getCode(); $exitCode = $e->getCode();
if (is_numeric($exitCode)) { if (is_numeric($exitCode)) {
$exitCode = (int) $exitCode; $exitCode = ((int) $exitCode) ?: 1;
if (0 === $exitCode) {
$exitCode = 1;
}
} else { } else {
$exitCode = 1; $exitCode = 1;
} }
} }
if ($this->autoExit) { if ($this->autoExit) {
if ($exitCode > 255) { if ($exitCode > 255) $exitCode = 255;
$exitCode = 255;
}
exit($exitCode); exit($exitCode);
} }
@@ -154,12 +189,14 @@ class Console
/** /**
* 执行指令 * 执行指令
* @param Input $input * @access public
* @param Output $output * @param Input $input 输入
* @param Output $output 输出
* @return int * @return int
*/ */
public function doRun(Input $input, Output $output) public function doRun(Input $input, Output $output)
{ {
// 获取版本信息
if (true === $input->hasParameterOption(['--version', '-V'])) { if (true === $input->hasParameterOption(['--version', '-V'])) {
$output->writeln($this->getLongVersion()); $output->writeln($this->getLongVersion());
@@ -168,6 +205,7 @@ class Console
$name = $this->getCommandName($input); $name = $this->getCommandName($input);
// 获取帮助信息
if (true === $input->hasParameterOption(['--help', '-h'])) { if (true === $input->hasParameterOption(['--help', '-h'])) {
if (!$name) { if (!$name) {
$name = 'help'; $name = 'help';
@@ -182,25 +220,26 @@ class Console
$input = new Input([$this->defaultCommand]); $input = new Input([$this->defaultCommand]);
} }
$command = $this->find($name); return $this->doRunCommand($this->find($name), $input, $output);
$exitCode = $this->doRunCommand($command, $input, $output);
return $exitCode;
} }
/** /**
* 设置输入参数定义 * 设置输入参数定义
* @param InputDefinition $definition * @access public
* @param InputDefinition $definition 输入定义
* @return $this;
*/ */
public function setDefinition(InputDefinition $definition) public function setDefinition(InputDefinition $definition)
{ {
$this->definition = $definition; $this->definition = $definition;
return $this;
} }
/** /**
* 获取输入参数定义 * 获取输入参数定义
* @return InputDefinition The InputDefinition instance * @access public
* @return InputDefinition
*/ */
public function getDefinition() public function getDefinition()
{ {
@@ -208,8 +247,9 @@ class Console
} }
/** /**
* Gets the help message. * 获取帮助信息
* @return string A help message. * @access public
* @return string
*/ */
public function getHelp() public function getHelp()
{ {
@@ -217,27 +257,34 @@ class Console
} }
/** /**
* 是否捕获异常 * 设置是否捕获异常
* @param bool $boolean * @access public
* @api * @param bool $boolean 是否捕获
* @return $this
*/ */
public function setCatchExceptions($boolean) public function setCatchExceptions($boolean)
{ {
$this->catchExceptions = (bool) $boolean; $this->catchExceptions = (bool) $boolean;
return $this;
} }
/** /**
* 是否自动退出 * 设置是否自动退出
* @param bool $boolean * @access public
* @api * @param bool $boolean 是否自动退出
* @return $this
*/ */
public function setAutoExit($boolean) public function setAutoExit($boolean)
{ {
$this->autoExit = (bool) $boolean; $this->autoExit = (bool) $boolean;
return $this;
} }
/** /**
* 获取名称 * 获取名称
* @access public
* @return string * @return string
*/ */
public function getName() public function getName()
@@ -247,17 +294,21 @@ class Console
/** /**
* 设置名称 * 设置名称
* @param string $name * @access public
* @param string $name 名称
* @return $this
*/ */
public function setName($name) public function setName($name)
{ {
$this->name = $name; $this->name = $name;
return $this;
} }
/** /**
* 获取版本 * 获取版本
* @access public
* @return string * @return string
* @api
*/ */
public function getVersion() public function getVersion()
{ {
@@ -266,21 +317,30 @@ class Console
/** /**
* 设置版本 * 设置版本
* @param string $version * @access public
* @param string $version 版本信息
* @return $this
*/ */
public function setVersion($version) public function setVersion($version)
{ {
$this->version = $version; $this->version = $version;
return $this;
} }
/** /**
* 获取完整的版本号 * 获取完整的版本号
* @access public
* @return string * @return string
*/ */
public function getLongVersion() public function getLongVersion()
{ {
if ('UNKNOWN' !== $this->getName() && 'UNKNOWN' !== $this->getVersion()) { if ('UNKNOWN' !== $this->getName() && 'UNKNOWN' !== $this->getVersion()) {
return sprintf('<info>%s</info> version <comment>%s</comment>', $this->getName(), $this->getVersion()); return sprintf(
'<info>%s</info> version <comment>%s</comment>',
$this->getName(),
$this->getVersion()
);
} }
return '<info>Console Tool</info>'; return '<info>Console Tool</info>';
@@ -288,7 +348,8 @@ class Console
/** /**
* 注册一个指令 * 注册一个指令
* @param string $name * @access public
* @param string $name 指令名称
* @return Command * @return Command
*/ */
public function register($name) public function register($name)
@@ -297,32 +358,37 @@ class Console
} }
/** /**
* 添加指令 * 批量添加指令
* @param Command[] $commands * @access public
* @param Command[] $commands 指令实例
* @return $this
*/ */
public function addCommands(array $commands) public function addCommands(array $commands)
{ {
foreach ($commands as $command) { foreach ($commands as $command) $this->add($command);
$this->add($command);
} return $this;
} }
/** /**
* 添加一个指令 * 添加一个指令
* @param Command $command * @access public
* @return Command * @param Command $command 命令实例
* @return Command|bool
*/ */
public function add(Command $command) public function add(Command $command)
{ {
$command->setConsole($this);
if (!$command->isEnabled()) { if (!$command->isEnabled()) {
$command->setConsole(null); $command->setConsole(null);
return; return false;
} }
$command->setConsole($this);
if (null === $command->getDefinition()) { if (null === $command->getDefinition()) {
throw new \LogicException(sprintf('Command class "%s" is not correctly initialized. You probably forgot to call the parent constructor.', get_class($command))); throw new \LogicException(
sprintf('Command class "%s" is not correctly initialized. You probably forgot to call the parent constructor.', get_class($command))
);
} }
$this->commands[$command->getName()] = $command; $this->commands[$command->getName()] = $command;
@@ -336,6 +402,7 @@ class Console
/** /**
* 获取指令 * 获取指令
* @access public
* @param string $name 指令名称 * @param string $name 指令名称
* @return Command * @return Command
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
@@ -343,7 +410,9 @@ class Console
public function get($name) public function get($name)
{ {
if (!isset($this->commands[$name])) { if (!isset($this->commands[$name])) {
throw new \InvalidArgumentException(sprintf('The command "%s" does not exist.', $name)); throw new \InvalidArgumentException(
sprintf('The command "%s" does not exist.', $name)
);
} }
$command = $this->commands[$name]; $command = $this->commands[$name];
@@ -363,6 +432,7 @@ class Console
/** /**
* 某个指令是否存在 * 某个指令是否存在
* @access public
* @param string $name 指令名称 * @param string $name 指令名称
* @return bool * @return bool
*/ */
@@ -373,16 +443,22 @@ class Console
/** /**
* 获取所有的命名空间 * 获取所有的命名空间
* @access public
* @return array * @return array
*/ */
public function getNamespaces() public function getNamespaces()
{ {
$namespaces = []; $namespaces = [];
foreach ($this->commands as $command) { foreach ($this->commands as $command) {
$namespaces = array_merge($namespaces, $this->extractAllNamespaces($command->getName())); $namespaces = array_merge(
$namespaces, $this->extractAllNamespaces($command->getName())
);
foreach ($command->getAliases() as $alias) { foreach ($command->getAliases() as $alias) {
$namespaces = array_merge($namespaces, $this->extractAllNamespaces($alias)); $namespaces = array_merge(
$namespaces, $this->extractAllNamespaces($alias)
);
} }
} }
@@ -390,21 +466,25 @@ class Console
} }
/** /**
* 查找注册命名空间中的名称或缩写 * 查找注册命名空间中的名称或缩写
* @access public
* @param string $namespace * @param string $namespace
* @return string * @return string
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
public function findNamespace($namespace) public function findNamespace($namespace)
{ {
$allNamespaces = $this->getNamespaces();
$expr = preg_replace_callback('{([^:]+|)}', function ($matches) { $expr = preg_replace_callback('{([^:]+|)}', function ($matches) {
return preg_quote($matches[1]) . '[^:]*'; return preg_quote($matches[1]) . '[^:]*';
}, $namespace); }, $namespace);
$allNamespaces = $this->getNamespaces();
$namespaces = preg_grep('{^' . $expr . '}', $allNamespaces); $namespaces = preg_grep('{^' . $expr . '}', $allNamespaces);
if (empty($namespaces)) { if (empty($namespaces)) {
$message = sprintf('There are no commands defined in the "%s" namespace.', $namespace); $message = sprintf(
'There are no commands defined in the "%s" namespace.', $namespace
);
if ($alternatives = $this->findAlternatives($namespace, $allNamespaces)) { if ($alternatives = $this->findAlternatives($namespace, $allNamespaces)) {
if (1 == count($alternatives)) { if (1 == count($alternatives)) {
@@ -420,8 +500,14 @@ class Console
} }
$exact = in_array($namespace, $namespaces, true); $exact = in_array($namespace, $namespaces, true);
if (count($namespaces) > 1 && !$exact) { if (count($namespaces) > 1 && !$exact) {
throw new \InvalidArgumentException(sprintf('The namespace "%s" is ambiguous (%s).', $namespace, $this->getAbbreviationSuggestions(array_values($namespaces)))); throw new \InvalidArgumentException(
sprintf(
'The namespace "%s" is ambiguous (%s).',
$namespace,
$this->getAbbreviationSuggestions(array_values($namespaces)))
);
} }
return $exact ? $namespace : reset($namespaces); return $exact ? $namespace : reset($namespaces);
@@ -429,20 +515,22 @@ class Console
/** /**
* 查找指令 * 查找指令
* @access public
* @param string $name 名称或者别名 * @param string $name 名称或者别名
* @return Command * @return Command
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
public function find($name) public function find($name)
{ {
$allCommands = array_keys($this->commands);
$expr = preg_replace_callback('{([^:]+|)}', function ($matches) { $expr = preg_replace_callback('{([^:]+|)}', function ($matches) {
return preg_quote($matches[1]) . '[^:]*'; return preg_quote($matches[1]) . '[^:]*';
}, $name); }, $name);
$allCommands = array_keys($this->commands);
$commands = preg_grep('{^' . $expr . '}', $allCommands); $commands = preg_grep('{^' . $expr . '}', $allCommands);
if (empty($commands) || count(preg_grep('{^' . $expr . '$}', $commands)) < 1) { if (empty($commands) || count(preg_grep('{^' . $expr . '$}', $commands)) < 1) {
if (false !== $pos = strrpos($name, ':')) { if (false !== ($pos = strrpos($name, ':'))) {
$this->findNamespace(substr($name, 0, $pos)); $this->findNamespace(substr($name, 0, $pos));
} }
@@ -473,7 +561,9 @@ class Console
if (count($commands) > 1 && !$exact) { if (count($commands) > 1 && !$exact) {
$suggestions = $this->getAbbreviationSuggestions(array_values($commands)); $suggestions = $this->getAbbreviationSuggestions(array_values($commands));
throw new \InvalidArgumentException(sprintf('Command "%s" is ambiguous (%s).', $name, $suggestions)); throw new \InvalidArgumentException(
sprintf('Command "%s" is ambiguous (%s).', $name, $suggestions)
);
} }
return $this->get($exact ? $name : reset($commands)); return $this->get($exact ? $name : reset($commands));
@@ -481,21 +571,20 @@ class Console
/** /**
* 获取所有的指令 * 获取所有的指令
* @access public
* @param string $namespace 命名空间 * @param string $namespace 命名空间
* @return Command[] * @return Command[]
* @api
*/ */
public function all($namespace = null) public function all($namespace = null)
{ {
if (null === $namespace) { if (null === $namespace) return $this->commands;
return $this->commands;
}
$commands = []; $commands = [];
foreach ($this->commands as $name => $command) { foreach ($this->commands as $name => $command) {
if ($this->extractNamespace($name, substr_count($namespace, ':') + 1) === $namespace) { $ext = $this->extractNamespace($name, substr_count($namespace, ':') + 1);
$commands[$name] = $command;
} if ($ext === $namespace) $commands[$name] = $command;
} }
return $commands; return $commands;
@@ -503,7 +592,8 @@ class Console
/** /**
* 获取可能的指令名 * 获取可能的指令名
* @param array $names * @access public
* @param array $names 指令名
* @return array * @return array
*/ */
public static function getAbbreviations($names) public static function getAbbreviations($names)
@@ -520,9 +610,11 @@ class Console
} }
/** /**
* 配置基于用户的参数和选项的输入和输出实例 * 配置基于用户的参数和选项的输入和输出实例
* @access protected
* @param Input $input 输入实例 * @param Input $input 输入实例
* @param Output $output 输出实例 * @param Output $output 输出实例
* @return void
*/ */
protected function configureIO(Input $input, Output $output) protected function configureIO(Input $input, Output $output)
{ {
@@ -551,6 +643,7 @@ class Console
/** /**
* 执行指令 * 执行指令
* @access protected
* @param Command $command 指令实例 * @param Command $command 指令实例
* @param Input $input 输入实例 * @param Input $input 输入实例
* @param Output $output 输出实例 * @param Output $output 输出实例
@@ -563,8 +656,9 @@ class Console
} }
/** /**
* 获取指令的基础名称 * 获取指令的名称
* @param Input $input * @access protected
* @param Input $input 输入实例
* @return string * @return string
*/ */
protected function getCommandName(Input $input) protected function getCommandName(Input $input)
@@ -574,6 +668,7 @@ class Console
/** /**
* 获取默认输入定义 * 获取默认输入定义
* @access protected
* @return InputDefinition * @return InputDefinition
*/ */
protected function getDefaultInputDefinition() protected function getDefaultInputDefinition()
@@ -591,40 +686,54 @@ class Console
} }
/** /**
* 设置默认命令 * 获取默认命令
* @return Command[] An array of default Command instances * @access protected
* @return Command[]
*/ */
protected function getDefaultCommands() protected function getDefaultCommands()
{ {
$defaultCommands = []; $defaultCommands = [];
foreach (self::$defaultCommands as $classname) { foreach (self::$defaultCommands as $class) {
if (class_exists($classname) && is_subclass_of($classname, "think\\console\\Command")) { if (class_exists($class) && is_subclass_of($class, "think\\console\\Command")) {
$defaultCommands[] = new $classname(); $defaultCommands[] = new $class();
} }
} }
return $defaultCommands; return $defaultCommands;
} }
public static function addDefaultCommands(array $classnames) /**
* 添加默认指令
* @access public
* @param array $classes 指令
* @return void
*/
public static function addDefaultCommands(array $classes)
{ {
self::$defaultCommands = array_merge(self::$defaultCommands, $classnames); self::$defaultCommands = array_merge(self::$defaultCommands, $classes);
} }
/** /**
* 获取可能的建议 * 获取可能的建议
* @access private
* @param array $abbrevs * @param array $abbrevs
* @return string * @return string
*/ */
private function getAbbreviationSuggestions($abbrevs) private function getAbbreviationSuggestions($abbrevs)
{ {
return sprintf('%s, %s%s', $abbrevs[0], $abbrevs[1], count($abbrevs) > 2 ? sprintf(' and %d more', count($abbrevs) - 2) : ''); return sprintf(
'%s, %s%s',
$abbrevs[0],
$abbrevs[1],
count($abbrevs) > 2 ? sprintf(' and %d more', count($abbrevs) - 2) : ''
);
} }
/** /**
* 返回命名空间部分 * 返回指令的命名空间部分
* @param string $name 指令 * @access public
* @param string $name 指令名称
* @param string $limit 部分的命名空间的最大数量 * @param string $limit 部分的命名空间的最大数量
* @return string * @return string
*/ */
@@ -638,16 +747,17 @@ class Console
/** /**
* 查找可替代的建议 * 查找可替代的建议
* @param string $name * @access private
* @param array|\Traversable $collection * @param string $name 指令名称
* @param array|\Traversable $collection 建议集合
* @return array * @return array
*/ */
private function findAlternatives($name, $collection) private function findAlternatives($name, $collection)
{ {
$threshold = 1e3; $threshold = 1e3;
$alternatives = []; $alternatives = [];
$collectionParts = []; $collectionParts = [];
foreach ($collection as $item) { foreach ($collection as $item) {
$collectionParts[$item] = explode(':', $item); $collectionParts[$item] = explode(':', $item);
} }
@@ -655,6 +765,7 @@ class Console
foreach (explode(':', $name) as $i => $subname) { foreach (explode(':', $name) as $i => $subname) {
foreach ($collectionParts as $collectionName => $parts) { foreach ($collectionParts as $collectionName => $parts) {
$exists = isset($alternatives[$collectionName]); $exists = isset($alternatives[$collectionName]);
if (!isset($parts[$i]) && $exists) { if (!isset($parts[$i]) && $exists) {
$alternatives[$collectionName] += $threshold; $alternatives[$collectionName] += $threshold;
continue; continue;
@@ -663,8 +774,14 @@ class Console
} }
$lev = levenshtein($subname, $parts[$i]); $lev = levenshtein($subname, $parts[$i]);
if ($lev <= strlen($subname) / 3 || '' !== $subname && false !== strpos($parts[$i], $subname)) {
$alternatives[$collectionName] = $exists ? $alternatives[$collectionName] + $lev : $lev; if ($lev <= strlen($subname) / 3 ||
'' !== $subname &&
false !== strpos($parts[$i], $subname)
) {
$alternatives[$collectionName] = $exists ?
$alternatives[$collectionName] + $lev :
$lev;
} elseif ($exists) { } elseif ($exists) {
$alternatives[$collectionName] += $threshold; $alternatives[$collectionName] += $threshold;
} }
@@ -673,14 +790,18 @@ class Console
foreach ($collection as $item) { foreach ($collection as $item) {
$lev = levenshtein($name, $item); $lev = levenshtein($name, $item);
if ($lev <= strlen($name) / 3 || false !== strpos($item, $name)) { if ($lev <= strlen($name) / 3 || false !== strpos($item, $name)) {
$alternatives[$item] = isset($alternatives[$item]) ? $alternatives[$item] - $lev : $lev; $alternatives[$item] = isset($alternatives[$item]) ?
$alternatives[$item] - $lev :
$lev;
} }
} }
$alternatives = array_filter($alternatives, function ($lev) use ($threshold) { $alternatives = array_filter($alternatives, function ($lev) use ($threshold) {
return $lev < 2 * $threshold; return $lev < 2 * $threshold;
}); });
asort($alternatives); asort($alternatives);
return array_keys($alternatives); return array_keys($alternatives);
@@ -688,24 +809,28 @@ class Console
/** /**
* 设置默认的指令 * 设置默认的指令
* @param string $commandName The Command name * @access public
* @param string $commandName 指令名称
* @return $this
*/ */
public function setDefaultCommand($commandName) public function setDefaultCommand($commandName)
{ {
$this->defaultCommand = $commandName; $this->defaultCommand = $commandName;
return $this;
} }
/** /**
* 返回所有的命名空间 * 返回所有的命名空间
* @param string $name * @access private
* @param string $name 指令名称
* @return array * @return array
*/ */
private function extractAllNamespaces($name) private function extractAllNamespaces($name)
{ {
$parts = explode(':', $name, -1);
$namespaces = []; $namespaces = [];
foreach ($parts as $part) { foreach (explode(':', $name, -1) as $part) {
if (count($namespaces)) { if (count($namespaces)) {
$namespaces[] = end($namespaces) . ':' . $part; $namespaces[] = end($namespaces) . ':' . $part;
} else { } else {

View File

@@ -24,34 +24,36 @@ class Controller
* @var \think\View 视图类实例 * @var \think\View 视图类实例
*/ */
protected $view; protected $view;
/** /**
* @var \think\Request Request 实例 * @var \think\Request Request 实例
*/ */
protected $request; protected $request;
// 验证失败是否抛出异常
/**
* @var bool 验证失败是否抛出异常
*/
protected $failException = false; protected $failException = false;
// 是否批量验证
/**
* @var bool 是否批量验证
*/
protected $batchValidate = false; protected $batchValidate = false;
/** /**
* 前置操作方法列表 * @var array 前置操作方法列表
* @var array $beforeActionList
* @access protected
*/ */
protected $beforeActionList = []; protected $beforeActionList = [];
/** /**
* 构造方法 * 构造方法
* @param Request $request Request对象
* @access public * @access public
* @param Request $request Request 对象
*/ */
public function __construct(Request $request = null) 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->view = View::instance(Config::get('template'), Config::get('view_replace_str'));
$this->request = $request; $this->request = is_null($request) ? Request::instance() : $request;
// 控制器初始化 // 控制器初始化
$this->_initialize(); $this->_initialize();
@@ -66,7 +68,10 @@ class Controller
} }
} }
// 初始化 /**
* 初始化操作
* @access protected
*/
protected function _initialize() protected function _initialize()
{ {
} }
@@ -76,6 +81,7 @@ class Controller
* @access protected * @access protected
* @param string $method 前置操作方法名 * @param string $method 前置操作方法名
* @param array $options 调用参数 ['only'=>[...]] 或者 ['except'=>[...]] * @param array $options 调用参数 ['only'=>[...]] 或者 ['except'=>[...]]
* @return void
*/ */
protected function beforeAction($method, $options = []) protected function beforeAction($method, $options = [])
{ {
@@ -83,6 +89,7 @@ class Controller
if (is_string($options['only'])) { if (is_string($options['only'])) {
$options['only'] = explode(',', $options['only']); $options['only'] = explode(',', $options['only']);
} }
if (!in_array($this->request->action(), $options['only'])) { if (!in_array($this->request->action(), $options['only'])) {
return; return;
} }
@@ -90,6 +97,7 @@ class Controller
if (is_string($options['except'])) { if (is_string($options['except'])) {
$options['except'] = explode(',', $options['except']); $options['except'] = explode(',', $options['except']);
} }
if (in_array($this->request->action(), $options['except'])) { if (in_array($this->request->action(), $options['except'])) {
return; return;
} }
@@ -131,22 +139,26 @@ class Controller
* @access protected * @access protected
* @param mixed $name 要显示的模板变量 * @param mixed $name 要显示的模板变量
* @param mixed $value 变量的值 * @param mixed $value 变量的值
* @return void * @return $this
*/ */
protected function assign($name, $value = '') protected function assign($name, $value = '')
{ {
$this->view->assign($name, $value); $this->view->assign($name, $value);
return $this;
} }
/** /**
* 初始化模板引擎 * 初始化模板引擎
* @access protected * @access protected
* @param array|string $engine 引擎参数 * @param array|string $engine 引擎参数
* @return void * @return $this
*/ */
protected function engine($engine) protected function engine($engine)
{ {
$this->view->engine($engine); $this->view->engine($engine);
return $this;
} }
/** /**
@@ -158,6 +170,7 @@ class Controller
protected function validateFailException($fail = true) protected function validateFailException($fail = true)
{ {
$this->failException = $fail; $this->failException = $fail;
return $this; return $this;
} }
@@ -178,24 +191,21 @@ class Controller
$v = Loader::validate(); $v = Loader::validate();
$v->rule($validate); $v->rule($validate);
} else { } else {
if (strpos($validate, '.')) {
// 支持场景 // 支持场景
if (strpos($validate, '.')) {
list($validate, $scene) = explode('.', $validate); list($validate, $scene) = explode('.', $validate);
} }
$v = Loader::validate($validate); $v = Loader::validate($validate);
if (!empty($scene)) {
$v->scene($scene); !empty($scene) && $v->scene($scene);
}
}
// 是否批量验证
if ($batch || $this->batchValidate) {
$v->batch(true);
}
if (is_array($message)) {
$v->message($message);
} }
// 批量验证
if ($batch || $this->batchValidate) $v->batch(true);
// 设置错误信息
if (is_array($message)) $v->message($message);
// 使用回调验证
if ($callback && is_callable($callback)) { if ($callback && is_callable($callback)) {
call_user_func_array($callback, [$v, &$data]); call_user_func_array($callback, [$v, &$data]);
} }
@@ -203,11 +213,11 @@ class Controller
if (!$v->check($data)) { if (!$v->check($data)) {
if ($this->failException) { if ($this->failException) {
throw new ValidateException($v->getError()); throw new ValidateException($v->getError());
} else { }
return $v->getError(); return $v->getError();
} }
} else {
return true; return true;
} }
} }
}

View File

@@ -13,68 +13,68 @@ namespace think;
class Cookie class Cookie
{ {
/**
* @var array cookie 设置参数
*/
protected static $config = [ protected static $config = [
// cookie 名称前缀 'prefix' => '', // cookie 名称前缀
'prefix' => '', 'expire' => 0, // cookie 保存时间
// cookie 保存时间 'path' => '/', // cookie 保存路径
'expire' => 0, 'domain' => '', // cookie 有效域名
// cookie 保存路径 'secure' => false, // cookie 启用安全传输
'path' => '/', 'httponly' => '', // httponly 设置
// cookie 有效域名 'setcookie' => true, // 是否使用 setcookie
'domain' => '',
// cookie 启用安全传输
'secure' => false,
// httponly设置
'httponly' => '',
// 是否使用 setcookie
'setcookie' => true,
]; ];
/**
* @var bool 是否完成初始化了
*/
protected static $init; protected static $init;
/** /**
* Cookie初始化 * Cookie初始化
* @param array $config * @access public
* @param array $config 配置参数
* @return void * @return void
*/ */
public static function init(array $config = []) public static function init(array $config = [])
{ {
if (empty($config)) { if (empty($config)) $config = Config::get('cookie');
$config = Config::get('cookie');
}
self::$config = array_merge(self::$config, array_change_key_case($config)); self::$config = array_merge(self::$config, array_change_key_case($config));
if (!empty(self::$config['httponly'])) { if (!empty(self::$config['httponly'])) {
ini_set('session.cookie_httponly', 1); ini_set('session.cookie_httponly', 1);
} }
self::$init = true; self::$init = true;
} }
/** /**
* 设置或者获取 cookie 作用域(前缀) * 设置或者获取 cookie 作用域(前缀)
* @param string $prefix * @access public
* @return string|void * @param string $prefix 前缀
* @return string|
*/ */
public static function prefix($prefix = '') public static function prefix($prefix = '')
{ {
if (empty($prefix)) { if (empty($prefix)) return self::$config['prefix'];
return self::$config['prefix'];
} return self::$config['prefix'] = $prefix;
self::$config['prefix'] = $prefix;
} }
/** /**
* Cookie 设置、获取、删除 * Cookie 设置、获取、删除
* * @access public
* @param string $name cookie 名称 * @param string $name cookie 名称
* @param mixed $value cookie 值 * @param mixed $value cookie 值
* @param mixed $option 可选参数 可能会是 null|integer|string * @param mixed $option 可选参数 可能会是 null|integer|string
* * @return void
* @return mixed
* @internal param mixed $options cookie参数
*/ */
public static function set($name, $value = '', $option = null) public static function set($name, $value = '', $option = null)
{ {
!isset(self::$init) && self::init(); !isset(self::$init) && self::init();
// 参数设置(会覆盖黙认设置) // 参数设置(会覆盖黙认设置)
if (!is_null($option)) { if (!is_null($option)) {
if (is_numeric($option)) { if (is_numeric($option)) {
@@ -82,25 +82,37 @@ class Cookie
} elseif (is_string($option)) { } elseif (is_string($option)) {
parse_str($option, $option); parse_str($option, $option);
} }
$config = array_merge(self::$config, array_change_key_case($option)); $config = array_merge(self::$config, array_change_key_case($option));
} else { } else {
$config = self::$config; $config = self::$config;
} }
$name = $config['prefix'] . $name; $name = $config['prefix'] . $name;
// 设置 cookie // 设置 cookie
if (is_array($value)) { if (is_array($value)) {
array_walk_recursive($value, 'self::jsonFormatProtect', 'encode'); array_walk_recursive($value, 'self::jsonFormatProtect', 'encode');
$value = 'think:' . json_encode($value); $value = 'think:' . json_encode($value);
} }
$expire = !empty($config['expire']) ? $_SERVER['REQUEST_TIME'] + intval($config['expire']) : 0;
$expire = !empty($config['expire']) ?
$_SERVER['REQUEST_TIME'] + intval($config['expire']) :
0;
if ($config['setcookie']) { if ($config['setcookie']) {
setcookie($name, $value, $expire, $config['path'], $config['domain'], $config['secure'], $config['httponly']); setcookie(
$name, $value, $expire, $config['path'], $config['domain'],
$config['secure'], $config['httponly']
);
} }
$_COOKIE[$name] = $value; $_COOKIE[$name] = $value;
} }
/** /**
* 永久保存 Cookie 数据 * 永久保存 Cookie 数据
* @access public
* @param string $name cookie 名称 * @param string $name cookie 名称
* @param mixed $value cookie 值 * @param mixed $value cookie 值
* @param mixed $option 可选参数 可能会是 null|integer|string * @param mixed $option 可选参数 可能会是 null|integer|string
@@ -108,15 +120,16 @@ class Cookie
*/ */
public static function forever($name, $value = '', $option = null) public static function forever($name, $value = '', $option = null)
{ {
if (is_null($option) || is_numeric($option)) { if (is_null($option) || is_numeric($option)) $option = [];
$option = [];
}
$option['expire'] = 315360000; $option['expire'] = 315360000;
self::set($name, $value, $option); self::set($name, $value, $option);
} }
/** /**
* 判断Cookie数据 * 判断是否有 Cookie 数据
* @access public
* @param string $name cookie 名称 * @param string $name cookie 名称
* @param string|null $prefix cookie 前缀 * @param string|null $prefix cookie 前缀
* @return bool * @return bool
@@ -124,13 +137,15 @@ class Cookie
public static function has($name, $prefix = null) public static function has($name, $prefix = null)
{ {
!isset(self::$init) && self::init(); !isset(self::$init) && self::init();
$prefix = !is_null($prefix) ? $prefix : self::$config['prefix']; $prefix = !is_null($prefix) ? $prefix : self::$config['prefix'];
$name = $prefix . $name;
return isset($_COOKIE[$name]); return isset($_COOKIE[$prefix . $name]);
} }
/** /**
* Cookie获取 * 获取 Cookie 的值
* @access public
* @param string $name cookie 名称 * @param string $name cookie 名称
* @param string|null $prefix cookie 前缀 * @param string|null $prefix cookie 前缀
* @return mixed * @return mixed
@@ -138,6 +153,7 @@ class Cookie
public static function get($name = '', $prefix = null) public static function get($name = '', $prefix = null)
{ {
!isset(self::$init) && self::init(); !isset(self::$init) && self::init();
$prefix = !is_null($prefix) ? $prefix : self::$config['prefix']; $prefix = !is_null($prefix) ? $prefix : self::$config['prefix'];
$key = $prefix . $name; $key = $prefix . $name;
@@ -145,80 +161,97 @@ class Cookie
// 获取全部 // 获取全部
if ($prefix) { if ($prefix) {
$value = []; $value = [];
foreach ($_COOKIE as $k => $val) { foreach ($_COOKIE as $k => $val) {
if (0 === strpos($k, $prefix)) { if (0 === strpos($k, $prefix)) $value[$k] = $val;
$value[$k] = $val;
}
} }
} else { } else {
$value = $_COOKIE; $value = $_COOKIE;
} }
} elseif (isset($_COOKIE[$key])) { } elseif (isset($_COOKIE[$key])) {
$value = $_COOKIE[$key]; $value = $_COOKIE[$key];
if (0 === strpos($value, 'think:')) { if (0 === strpos($value, 'think:')) {
$value = substr($value, 6); $value = json_decode(substr($value, 6), true);
$value = json_decode($value, true);
array_walk_recursive($value, 'self::jsonFormatProtect', 'decode'); array_walk_recursive($value, 'self::jsonFormatProtect', 'decode');
} }
} else { } else {
$value = null; $value = null;
} }
return $value; return $value;
} }
/** /**
* Cookie删除 * 删除 Cookie
* @access public
* @param string $name cookie 名称 * @param string $name cookie 名称
* @param string|null $prefix cookie 前缀 * @param string|null $prefix cookie 前缀
* @return mixed * @return void
*/ */
public static function delete($name, $prefix = null) public static function delete($name, $prefix = null)
{ {
!isset(self::$init) && self::init(); !isset(self::$init) && self::init();
$config = self::$config; $config = self::$config;
$prefix = !is_null($prefix) ? $prefix : $config['prefix']; $prefix = !is_null($prefix) ? $prefix : $config['prefix'];
$name = $prefix . $name; $name = $prefix . $name;
if ($config['setcookie']) { if ($config['setcookie']) {
setcookie($name, '', $_SERVER['REQUEST_TIME'] - 3600, $config['path'], $config['domain'], $config['secure'], $config['httponly']); setcookie(
$name, '', $_SERVER['REQUEST_TIME'] - 3600, $config['path'],
$config['domain'], $config['secure'], $config['httponly']
);
} }
// 删除指定 cookie // 删除指定 cookie
unset($_COOKIE[$name]); unset($_COOKIE[$name]);
} }
/** /**
* Cookie清空 * 清除指定前缀的所有 cookie
* @access public
* @param string|null $prefix cookie 前缀 * @param string|null $prefix cookie 前缀
* @return mixed * @return void
*/ */
public static function clear($prefix = null) public static function clear($prefix = null)
{ {
// 清除指定前缀的所有cookie if (empty($_COOKIE)) return;
if (empty($_COOKIE)) {
return;
}
!isset(self::$init) && self::init(); !isset(self::$init) && self::init();
// 要删除的 cookie 前缀,不指定则删除 config 设置的指定前缀 // 要删除的 cookie 前缀,不指定则删除 config 设置的指定前缀
$config = self::$config; $config = self::$config;
$prefix = !is_null($prefix) ? $prefix : $config['prefix']; $prefix = !is_null($prefix) ? $prefix : $config['prefix'];
if ($prefix) { if ($prefix) {
// 如果前缀为空字符串将不作处理直接返回
foreach ($_COOKIE as $key => $val) { foreach ($_COOKIE as $key => $val) {
if (0 === strpos($key, $prefix)) { if (0 === strpos($key, $prefix)) {
if ($config['setcookie']) { if ($config['setcookie']) {
setcookie($key, '', $_SERVER['REQUEST_TIME'] - 3600, $config['path'], $config['domain'], $config['secure'], $config['httponly']); setcookie(
$key, '', $_SERVER['REQUEST_TIME'] - 3600, $config['path'],
$config['domain'], $config['secure'], $config['httponly']
);
} }
unset($_COOKIE[$key]); unset($_COOKIE[$key]);
} }
} }
} }
return;
} }
private static function jsonFormatProtect(&$val, $key, $type = 'encode') /**
* json 转换时的格式保护
* @access protected
* @param mixed $val 要转换的值
* @param string $key 键名
* @param string $type 转换类别
* @return void
*/
protected static function jsonFormatProtect(&$val, $key, $type = 'encode')
{ {
if (!empty($val) && true !== $val) { if (!empty($val) && true !== $val) {
$val = 'decode' == $type ? urldecode($val) : urlencode($val); $val = 'decode' == $type ? urldecode($val) : urlencode($val);
} }
} }
} }