feat: 本次提交更新内容如下
数据同步
This commit is contained in:
1
Server/.user.ini
Normal file
1
Server/.user.ini
Normal file
@@ -0,0 +1 @@
|
||||
open_basedir="E:/WorkSpace/Maokaka/Server/;C:/Windows/Temp/;C:/Temp/;D:/Application/BtSoft/temp/session/"
|
||||
@@ -1,40 +1,40 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>恭喜,站点创建成功!</title>
|
||||
<style>
|
||||
|
||||
.container {
|
||||
width: 60%;
|
||||
margin: 10% auto 0;
|
||||
background-color: #f0f0f0;
|
||||
padding: 2% 5%;
|
||||
border-radius: 10px
|
||||
}
|
||||
|
||||
ul {
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
ul li {
|
||||
line-height: 2.3
|
||||
}
|
||||
|
||||
a {
|
||||
color: #20a53a
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>恭喜, 站点创建成功!</h1>
|
||||
<h3>这是默认index.html,本页面由系统自动生成</h3>
|
||||
<ul>
|
||||
<li>本页面在FTP根目录下的index.html</li>
|
||||
<li>您可以修改、删除或覆盖本页面</li>
|
||||
<li>FTP相关信息,请到“面板系统后台 > FTP” 查看</li>
|
||||
</ul>
|
||||
</div>
|
||||
</body>
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>恭喜,站点创建成功!</title>
|
||||
<style>
|
||||
|
||||
.container {
|
||||
width: 60%;
|
||||
margin: 10% auto 0;
|
||||
background-color: #f0f0f0;
|
||||
padding: 2% 5%;
|
||||
border-radius: 10px
|
||||
}
|
||||
|
||||
ul {
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
ul li {
|
||||
line-height: 2.3
|
||||
}
|
||||
|
||||
a {
|
||||
color: #20a53a
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>恭喜, 站点创建成功!</h1>
|
||||
<h3>这是默认index.html,本页面由系统自动生成</h3>
|
||||
<ul>
|
||||
<li>本页面在FTP根目录下的index.html</li>
|
||||
<li>您可以修改、删除或覆盖本页面</li>
|
||||
<li>FTP相关信息,请到“面板系统后台 > FTP” 查看</li>
|
||||
</ul>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
618
Server/thinkphp/library/think/Container.php
Normal file
618
Server/thinkphp/library/think/Container.php
Normal file
@@ -0,0 +1,618 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think;
|
||||
|
||||
use ArrayAccess;
|
||||
use ArrayIterator;
|
||||
use Closure;
|
||||
use Countable;
|
||||
use InvalidArgumentException;
|
||||
use IteratorAggregate;
|
||||
use ReflectionClass;
|
||||
use ReflectionException;
|
||||
use ReflectionFunction;
|
||||
use ReflectionMethod;
|
||||
use think\exception\ClassNotFoundException;
|
||||
|
||||
/**
|
||||
* @package think
|
||||
* @property Build $build
|
||||
* @property Cache $cache
|
||||
* @property Config $config
|
||||
* @property Cookie $cookie
|
||||
* @property Debug $debug
|
||||
* @property Env $env
|
||||
* @property Hook $hook
|
||||
* @property Lang $lang
|
||||
* @property Middleware $middleware
|
||||
* @property Request $request
|
||||
* @property Response $response
|
||||
* @property Route $route
|
||||
* @property Session $session
|
||||
* @property Template $template
|
||||
* @property Url $url
|
||||
* @property Validate $validate
|
||||
* @property View $view
|
||||
* @property route\RuleName $rule_name
|
||||
* @property Log $log
|
||||
*/
|
||||
class Container implements ArrayAccess, IteratorAggregate, Countable
|
||||
{
|
||||
/**
|
||||
* 容器对象实例
|
||||
* @var Container
|
||||
*/
|
||||
protected static $instance;
|
||||
|
||||
/**
|
||||
* 容器中的对象实例
|
||||
* @var array
|
||||
*/
|
||||
protected $instances = [];
|
||||
|
||||
/**
|
||||
* 容器绑定标识
|
||||
* @var array
|
||||
*/
|
||||
protected $bind = [
|
||||
'app' => App::class,
|
||||
'build' => Build::class,
|
||||
'cache' => Cache::class,
|
||||
'config' => Config::class,
|
||||
'cookie' => Cookie::class,
|
||||
'debug' => Debug::class,
|
||||
'env' => Env::class,
|
||||
'hook' => Hook::class,
|
||||
'lang' => Lang::class,
|
||||
'log' => Log::class,
|
||||
'middleware' => Middleware::class,
|
||||
'request' => Request::class,
|
||||
'response' => Response::class,
|
||||
'route' => Route::class,
|
||||
'session' => Session::class,
|
||||
'template' => Template::class,
|
||||
'url' => Url::class,
|
||||
'validate' => Validate::class,
|
||||
'view' => View::class,
|
||||
'rule_name' => route\RuleName::class,
|
||||
// 接口依赖注入
|
||||
'think\LoggerInterface' => Log::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* 容器标识别名
|
||||
* @var array
|
||||
*/
|
||||
protected $name = [];
|
||||
|
||||
/**
|
||||
* 获取当前容器的实例(单例)
|
||||
* @access public
|
||||
* @return static
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
if (is_null(static::$instance)) {
|
||||
static::$instance = new static;
|
||||
}
|
||||
|
||||
return static::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前容器的实例
|
||||
* @access public
|
||||
* @param object $instance
|
||||
* @return void
|
||||
*/
|
||||
public static function setInstance($instance)
|
||||
{
|
||||
static::$instance = $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取容器中的对象实例
|
||||
* @access public
|
||||
* @param string $abstract 类名或者标识
|
||||
* @param array|true $vars 变量
|
||||
* @param bool $newInstance 是否每次创建新的实例
|
||||
* @return object
|
||||
*/
|
||||
public static function get($abstract, $vars = [], $newInstance = false)
|
||||
{
|
||||
return static::getInstance()->make($abstract, $vars, $newInstance);
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定一个类、闭包、实例、接口实现到容器
|
||||
* @access public
|
||||
* @param string $abstract 类标识、接口
|
||||
* @param mixed $concrete 要绑定的类、闭包或者实例
|
||||
* @return Container
|
||||
*/
|
||||
public static function set($abstract, $concrete = null)
|
||||
{
|
||||
return static::getInstance()->bindTo($abstract, $concrete);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除容器中的对象实例
|
||||
* @access public
|
||||
* @param string $abstract 类标识、接口
|
||||
* @return void
|
||||
*/
|
||||
public static function remove($abstract)
|
||||
{
|
||||
return static::getInstance()->delete($abstract);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除容器中的对象实例
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public static function clear()
|
||||
{
|
||||
return static::getInstance()->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定一个类、闭包、实例、接口实现到容器
|
||||
* @access public
|
||||
* @param string|array $abstract 类标识、接口
|
||||
* @param mixed $concrete 要绑定的类、闭包或者实例
|
||||
* @return $this
|
||||
*/
|
||||
public function bindTo($abstract, $concrete = null)
|
||||
{
|
||||
if (is_array($abstract)) {
|
||||
$this->bind = array_merge($this->bind, $abstract);
|
||||
} elseif ($concrete instanceof Closure) {
|
||||
$this->bind[$abstract] = $concrete;
|
||||
} elseif (is_object($concrete)) {
|
||||
if (isset($this->bind[$abstract])) {
|
||||
$abstract = $this->bind[$abstract];
|
||||
}
|
||||
$this->instances[$abstract] = $concrete;
|
||||
} else {
|
||||
$this->bind[$abstract] = $concrete;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定一个类实例当容器
|
||||
* @access public
|
||||
* @param string $abstract 类名或者标识
|
||||
* @param object|\Closure $instance 类的实例
|
||||
* @return $this
|
||||
*/
|
||||
public function instance($abstract, $instance)
|
||||
{
|
||||
if ($instance instanceof \Closure) {
|
||||
$this->bind[$abstract] = $instance;
|
||||
} else {
|
||||
if (isset($this->bind[$abstract])) {
|
||||
$abstract = $this->bind[$abstract];
|
||||
}
|
||||
|
||||
$this->instances[$abstract] = $instance;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断容器中是否存在类及标识
|
||||
* @access public
|
||||
* @param string $abstract 类名或者标识
|
||||
* @return bool
|
||||
*/
|
||||
public function bound($abstract)
|
||||
{
|
||||
return isset($this->bind[$abstract]) || isset($this->instances[$abstract]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断容器中是否存在对象实例
|
||||
* @access public
|
||||
* @param string $abstract 类名或者标识
|
||||
* @return bool
|
||||
*/
|
||||
public function exists($abstract)
|
||||
{
|
||||
if (isset($this->bind[$abstract])) {
|
||||
$abstract = $this->bind[$abstract];
|
||||
}
|
||||
|
||||
return isset($this->instances[$abstract]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断容器中是否存在类及标识
|
||||
* @access public
|
||||
* @param string $name 类名或者标识
|
||||
* @return bool
|
||||
*/
|
||||
public function has($name)
|
||||
{
|
||||
return $this->bound($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建类的实例
|
||||
* @access public
|
||||
* @param string $abstract 类名或者标识
|
||||
* @param array|true $vars 变量
|
||||
* @param bool $newInstance 是否每次创建新的实例
|
||||
* @return object
|
||||
*/
|
||||
public function make($abstract, $vars = [], $newInstance = false)
|
||||
{
|
||||
if (true === $vars) {
|
||||
// 总是创建新的实例化对象
|
||||
$newInstance = true;
|
||||
$vars = [];
|
||||
}
|
||||
|
||||
$abstract = isset($this->name[$abstract]) ? $this->name[$abstract] : $abstract;
|
||||
|
||||
if (isset($this->instances[$abstract]) && !$newInstance) {
|
||||
return $this->instances[$abstract];
|
||||
}
|
||||
|
||||
if (isset($this->bind[$abstract])) {
|
||||
$concrete = $this->bind[$abstract];
|
||||
|
||||
if ($concrete instanceof Closure) {
|
||||
$object = $this->invokeFunction($concrete, $vars);
|
||||
} else {
|
||||
$this->name[$abstract] = $concrete;
|
||||
return $this->make($concrete, $vars, $newInstance);
|
||||
}
|
||||
} else {
|
||||
$object = $this->invokeClass($abstract, $vars);
|
||||
}
|
||||
|
||||
if (!$newInstance) {
|
||||
$this->instances[$abstract] = $object;
|
||||
}
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除容器中的对象实例
|
||||
* @access public
|
||||
* @param string|array $abstract 类名或者标识
|
||||
* @return void
|
||||
*/
|
||||
public function delete($abstract)
|
||||
{
|
||||
foreach ((array) $abstract as $name) {
|
||||
$name = isset($this->name[$name]) ? $this->name[$name] : $name;
|
||||
|
||||
if (isset($this->instances[$name])) {
|
||||
unset($this->instances[$name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取容器中的对象实例
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function all()
|
||||
{
|
||||
return $this->instances;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除容器中的对象实例
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function flush()
|
||||
{
|
||||
$this->instances = [];
|
||||
$this->bind = [];
|
||||
$this->name = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行函数或者闭包方法 支持参数调用
|
||||
* @access public
|
||||
* @param mixed $function 函数或者闭包
|
||||
* @param array $vars 参数
|
||||
* @return mixed
|
||||
*/
|
||||
public function invokeFunction($function, $vars = [])
|
||||
{
|
||||
try {
|
||||
$reflect = new ReflectionFunction($function);
|
||||
|
||||
$args = $this->bindParams($reflect, $vars);
|
||||
|
||||
return call_user_func_array($function, $args);
|
||||
} catch (ReflectionException $e) {
|
||||
throw new Exception('function not exists: ' . $function . '()');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用反射执行类的方法 支持参数绑定
|
||||
* @access public
|
||||
* @param mixed $method 方法
|
||||
* @param array $vars 参数
|
||||
* @return mixed
|
||||
*/
|
||||
public function invokeMethod($method, $vars = [])
|
||||
{
|
||||
try {
|
||||
if (is_array($method)) {
|
||||
$class = is_object($method[0]) ? $method[0] : $this->invokeClass($method[0]);
|
||||
$reflect = new ReflectionMethod($class, $method[1]);
|
||||
} else {
|
||||
// 静态方法
|
||||
$reflect = new ReflectionMethod($method);
|
||||
}
|
||||
|
||||
$args = $this->bindParams($reflect, $vars);
|
||||
|
||||
return $reflect->invokeArgs(isset($class) ? $class : null, $args);
|
||||
} catch (ReflectionException $e) {
|
||||
if (is_array($method) && is_object($method[0])) {
|
||||
$method[0] = get_class($method[0]);
|
||||
}
|
||||
|
||||
throw new Exception('method not exists: ' . (is_array($method) ? $method[0] . '::' . $method[1] : $method) . '()');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用反射执行类的方法 支持参数绑定
|
||||
* @access public
|
||||
* @param object $instance 对象实例
|
||||
* @param mixed $reflect 反射类
|
||||
* @param array $vars 参数
|
||||
* @return mixed
|
||||
*/
|
||||
public function invokeReflectMethod($instance, $reflect, $vars = [])
|
||||
{
|
||||
$args = $this->bindParams($reflect, $vars);
|
||||
|
||||
return $reflect->invokeArgs($instance, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用反射执行callable 支持参数绑定
|
||||
* @access public
|
||||
* @param mixed $callable
|
||||
* @param array $vars 参数
|
||||
* @return mixed
|
||||
*/
|
||||
public function invoke($callable, $vars = [])
|
||||
{
|
||||
if ($callable instanceof Closure) {
|
||||
return $this->invokeFunction($callable, $vars);
|
||||
}
|
||||
|
||||
return $this->invokeMethod($callable, $vars);
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用反射执行类的实例化 支持依赖注入
|
||||
* @access public
|
||||
* @param string $class 类名
|
||||
* @param array $vars 参数
|
||||
* @return mixed
|
||||
*/
|
||||
public function invokeClass($class, $vars = [])
|
||||
{
|
||||
try {
|
||||
$reflect = new ReflectionClass($class);
|
||||
|
||||
if ($reflect->hasMethod('__make')) {
|
||||
$method = new ReflectionMethod($class, '__make');
|
||||
|
||||
if ($method->isPublic() && $method->isStatic()) {
|
||||
$args = $this->bindParams($method, $vars);
|
||||
return $method->invokeArgs(null, $args);
|
||||
}
|
||||
}
|
||||
|
||||
$constructor = $reflect->getConstructor();
|
||||
|
||||
$args = $constructor ? $this->bindParams($constructor, $vars) : [];
|
||||
|
||||
return $reflect->newInstanceArgs($args);
|
||||
|
||||
} catch (ReflectionException $e) {
|
||||
throw new ClassNotFoundException('class not exists: ' . $class, $class);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定参数
|
||||
* @access protected
|
||||
* @param \ReflectionMethod|\ReflectionFunction $reflect 反射类
|
||||
* @param array $vars 参数
|
||||
* @return array
|
||||
*/
|
||||
protected function bindParams($reflect, $vars = [])
|
||||
{
|
||||
if ($reflect->getNumberOfParameters() == 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// 判断数组类型 数字数组时按顺序绑定参数
|
||||
reset($vars);
|
||||
$type = key($vars) === 0 ? 1 : 0;
|
||||
$params = $reflect->getParameters();
|
||||
|
||||
if (PHP_VERSION > 8.0) {
|
||||
$args = $this->parseParamsForPHP8($params, $vars, $type);
|
||||
} else {
|
||||
$args = $this->parseParams($params, $vars, $type);
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析参数
|
||||
* @access protected
|
||||
* @param array $params 参数列表
|
||||
* @param array $vars 参数数据
|
||||
* @param int $type 参数类别
|
||||
* @return array
|
||||
*/
|
||||
protected function parseParams($params, $vars, $type)
|
||||
{
|
||||
foreach ($params as $param) {
|
||||
$name = $param->getName();
|
||||
$lowerName = Loader::parseName($name);
|
||||
$class = $param->getClass();
|
||||
|
||||
if ($class) {
|
||||
$args[] = $this->getObjectParam($class->getName(), $vars);
|
||||
} elseif (1 == $type && !empty($vars)) {
|
||||
$args[] = array_shift($vars);
|
||||
} elseif (0 == $type && isset($vars[$name])) {
|
||||
$args[] = $vars[$name];
|
||||
} elseif (0 == $type && isset($vars[$lowerName])) {
|
||||
$args[] = $vars[$lowerName];
|
||||
} elseif ($param->isDefaultValueAvailable()) {
|
||||
$args[] = $param->getDefaultValue();
|
||||
} else {
|
||||
throw new InvalidArgumentException('method param miss:' . $name);
|
||||
}
|
||||
}
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析参数
|
||||
* @access protected
|
||||
* @param array $params 参数列表
|
||||
* @param array $vars 参数数据
|
||||
* @param int $type 参数类别
|
||||
* @return array
|
||||
*/
|
||||
protected function parseParamsForPHP8($params, $vars, $type)
|
||||
{
|
||||
foreach ($params as $param) {
|
||||
$name = $param->getName();
|
||||
$lowerName = Loader::parseName($name);
|
||||
$reflectionType = $param->getType();
|
||||
|
||||
if ($reflectionType && $reflectionType->isBuiltin() === false) {
|
||||
$args[] = $this->getObjectParam($reflectionType->getName(), $vars);
|
||||
} elseif (1 == $type && !empty($vars)) {
|
||||
$args[] = array_shift($vars);
|
||||
} elseif (0 == $type && array_key_exists($name, $vars)) {
|
||||
$args[] = $vars[$name];
|
||||
} elseif (0 == $type && array_key_exists($lowerName, $vars)) {
|
||||
$args[] = $vars[$lowerName];
|
||||
} elseif ($param->isDefaultValueAvailable()) {
|
||||
$args[] = $param->getDefaultValue();
|
||||
} else {
|
||||
throw new InvalidArgumentException('method param miss:' . $name);
|
||||
}
|
||||
}
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取对象类型的参数值
|
||||
* @access protected
|
||||
* @param string $className 类名
|
||||
* @param array $vars 参数
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getObjectParam($className, &$vars)
|
||||
{
|
||||
$array = $vars;
|
||||
$value = array_shift($array);
|
||||
|
||||
if ($value instanceof $className) {
|
||||
$result = $value;
|
||||
array_shift($vars);
|
||||
} else {
|
||||
$result = $this->make($className);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function __set($name, $value)
|
||||
{
|
||||
$this->bindTo($name, $value);
|
||||
}
|
||||
|
||||
public function __get($name)
|
||||
{
|
||||
return $this->make($name);
|
||||
}
|
||||
|
||||
public function __isset($name)
|
||||
{
|
||||
return $this->bound($name);
|
||||
}
|
||||
|
||||
public function __unset($name)
|
||||
{
|
||||
$this->delete($name);
|
||||
}
|
||||
|
||||
public function offsetExists($key)
|
||||
{
|
||||
return $this->__isset($key);
|
||||
}
|
||||
|
||||
public function offsetGet($key)
|
||||
{
|
||||
return $this->__get($key);
|
||||
}
|
||||
|
||||
public function offsetSet($key, $value)
|
||||
{
|
||||
$this->__set($key, $value);
|
||||
}
|
||||
|
||||
public function offsetUnset($key)
|
||||
{
|
||||
$this->__unset($key);
|
||||
}
|
||||
|
||||
//Countable
|
||||
public function count()
|
||||
{
|
||||
return count($this->instances);
|
||||
}
|
||||
|
||||
//IteratorAggregate
|
||||
public function getIterator()
|
||||
{
|
||||
return new ArrayIterator($this->instances);
|
||||
}
|
||||
|
||||
public function __debugInfo()
|
||||
{
|
||||
$data = get_object_vars($this);
|
||||
unset($data['instances'], $data['instance']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
125
Server/thinkphp/library/think/Facade.php
Normal file
125
Server/thinkphp/library/think/Facade.php
Normal file
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think;
|
||||
|
||||
class Facade
|
||||
{
|
||||
/**
|
||||
* 绑定对象
|
||||
* @var array
|
||||
*/
|
||||
protected static $bind = [];
|
||||
|
||||
/**
|
||||
* 始终创建新的对象实例
|
||||
* @var bool
|
||||
*/
|
||||
protected static $alwaysNewInstance;
|
||||
|
||||
/**
|
||||
* 绑定类的静态代理
|
||||
* @static
|
||||
* @access public
|
||||
* @param string|array $name 类标识
|
||||
* @param string $class 类名
|
||||
* @return object
|
||||
*/
|
||||
public static function bind($name, $class = null)
|
||||
{
|
||||
if (__CLASS__ != static::class) {
|
||||
return self::__callStatic('bind', func_get_args());
|
||||
}
|
||||
|
||||
if (is_array($name)) {
|
||||
self::$bind = array_merge(self::$bind, $name);
|
||||
} else {
|
||||
self::$bind[$name] = $class;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建Facade实例
|
||||
* @static
|
||||
* @access protected
|
||||
* @param string $class 类名或标识
|
||||
* @param array $args 变量
|
||||
* @param bool $newInstance 是否每次创建新的实例
|
||||
* @return object
|
||||
*/
|
||||
protected static function createFacade($class = '', $args = [], $newInstance = false)
|
||||
{
|
||||
$class = $class ?: static::class;
|
||||
|
||||
$facadeClass = static::getFacadeClass();
|
||||
|
||||
if ($facadeClass) {
|
||||
$class = $facadeClass;
|
||||
} elseif (isset(self::$bind[$class])) {
|
||||
$class = self::$bind[$class];
|
||||
}
|
||||
|
||||
if (static::$alwaysNewInstance) {
|
||||
$newInstance = true;
|
||||
}
|
||||
|
||||
return Container::getInstance()->make($class, $args, $newInstance);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前Facade对应类名(或者已经绑定的容器对象标识)
|
||||
* @access protected
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeClass()
|
||||
{}
|
||||
|
||||
/**
|
||||
* 带参数实例化当前Facade类
|
||||
* @access public
|
||||
* @return mixed
|
||||
*/
|
||||
public static function instance(...$args)
|
||||
{
|
||||
if (__CLASS__ != static::class) {
|
||||
return self::createFacade('', $args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用类的实例
|
||||
* @access public
|
||||
* @param string $class 类名或者标识
|
||||
* @param array|true $args 变量
|
||||
* @param bool $newInstance 是否每次创建新的实例
|
||||
* @return mixed
|
||||
*/
|
||||
public static function make($class, $args = [], $newInstance = false)
|
||||
{
|
||||
if (__CLASS__ != static::class) {
|
||||
return self::__callStatic('make', func_get_args());
|
||||
}
|
||||
|
||||
if (true === $args) {
|
||||
// 总是创建新的实例化对象
|
||||
$newInstance = true;
|
||||
$args = [];
|
||||
}
|
||||
|
||||
return self::createFacade($class, $args, $newInstance);
|
||||
}
|
||||
|
||||
// 调用实际类的方法
|
||||
public static function __callStatic($method, $params)
|
||||
{
|
||||
return call_user_func_array([static::createFacade(), $method], $params);
|
||||
}
|
||||
}
|
||||
205
Server/thinkphp/library/think/Middleware.php
Normal file
205
Server/thinkphp/library/think/Middleware.php
Normal file
@@ -0,0 +1,205 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Slince <taosikai@yeah.net>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use LogicException;
|
||||
use think\exception\HttpResponseException;
|
||||
|
||||
class Middleware
|
||||
{
|
||||
protected $queue = [];
|
||||
protected $app;
|
||||
protected $config = [
|
||||
'default_namespace' => 'app\\http\\middleware\\',
|
||||
];
|
||||
|
||||
public function __construct(App $app, array $config = [])
|
||||
{
|
||||
$this->app = $app;
|
||||
$this->config = array_merge($this->config, $config);
|
||||
}
|
||||
|
||||
public static function __make(App $app, Config $config)
|
||||
{
|
||||
return new static($app, $config->pull('middleware'));
|
||||
}
|
||||
|
||||
public function setConfig(array $config)
|
||||
{
|
||||
$this->config = array_merge($this->config, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导入中间件
|
||||
* @access public
|
||||
* @param array $middlewares
|
||||
* @param string $type 中间件类型
|
||||
*/
|
||||
public function import(array $middlewares = [], $type = 'route')
|
||||
{
|
||||
foreach ($middlewares as $middleware) {
|
||||
$this->add($middleware, $type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册中间件
|
||||
* @access public
|
||||
* @param mixed $middleware
|
||||
* @param string $type 中间件类型
|
||||
*/
|
||||
public function add($middleware, $type = 'route')
|
||||
{
|
||||
if (is_null($middleware)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$middleware = $this->buildMiddleware($middleware, $type);
|
||||
|
||||
if ($middleware) {
|
||||
$this->queue[$type][] = $middleware;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册控制器中间件
|
||||
* @access public
|
||||
* @param mixed $middleware
|
||||
*/
|
||||
public function controller($middleware)
|
||||
{
|
||||
return $this->add($middleware, 'controller');
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除中间件
|
||||
* @access public
|
||||
* @param mixed $middleware
|
||||
* @param string $type 中间件类型
|
||||
*/
|
||||
public function unshift($middleware, $type = 'route')
|
||||
{
|
||||
if (is_null($middleware)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$middleware = $this->buildMiddleware($middleware, $type);
|
||||
|
||||
if ($middleware) {
|
||||
array_unshift($this->queue[$type], $middleware);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取注册的中间件
|
||||
* @access public
|
||||
* @param string $type 中间件类型
|
||||
*/
|
||||
public function all($type = 'route')
|
||||
{
|
||||
return $this->queue[$type] ?: [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除中间件
|
||||
* @access public
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$this->queue = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 中间件调度
|
||||
* @access public
|
||||
* @param Request $request
|
||||
* @param string $type 中间件类型
|
||||
*/
|
||||
public function dispatch(Request $request, $type = 'route')
|
||||
{
|
||||
return call_user_func($this->resolve($type), $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析中间件
|
||||
* @access protected
|
||||
* @param mixed $middleware
|
||||
* @param string $type 中间件类型
|
||||
*/
|
||||
protected function buildMiddleware($middleware, $type = 'route')
|
||||
{
|
||||
if (is_array($middleware)) {
|
||||
list($middleware, $param) = $middleware;
|
||||
}
|
||||
|
||||
if ($middleware instanceof \Closure) {
|
||||
return [$middleware, isset($param) ? $param : null];
|
||||
}
|
||||
|
||||
if (!is_string($middleware)) {
|
||||
throw new InvalidArgumentException('The middleware is invalid');
|
||||
}
|
||||
|
||||
if (false === strpos($middleware, '\\')) {
|
||||
if (isset($this->config[$middleware])) {
|
||||
$middleware = $this->config[$middleware];
|
||||
} else {
|
||||
$middleware = $this->config['default_namespace'] . $middleware;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_array($middleware)) {
|
||||
return $this->import($middleware, $type);
|
||||
}
|
||||
|
||||
if (strpos($middleware, ':')) {
|
||||
list($middleware, $param) = explode(':', $middleware, 2);
|
||||
}
|
||||
|
||||
return [[$this->app->make($middleware), 'handle'], isset($param) ? $param : null];
|
||||
}
|
||||
|
||||
protected function resolve($type = 'route')
|
||||
{
|
||||
return function (Request $request) use ($type) {
|
||||
|
||||
$middleware = array_shift($this->queue[$type]);
|
||||
|
||||
if (null === $middleware) {
|
||||
throw new InvalidArgumentException('The queue was exhausted, with no response returned');
|
||||
}
|
||||
|
||||
list($call, $param) = $middleware;
|
||||
|
||||
try {
|
||||
$response = call_user_func_array($call, [$request, $this->resolve($type), $param]);
|
||||
} catch (HttpResponseException $exception) {
|
||||
$response = $exception->getResponse();
|
||||
}
|
||||
|
||||
if (!$response instanceof Response) {
|
||||
throw new LogicException('The middleware must return Response instance');
|
||||
}
|
||||
|
||||
return $response;
|
||||
};
|
||||
}
|
||||
|
||||
public function __debugInfo()
|
||||
{
|
||||
$data = get_object_vars($this);
|
||||
unset($data['app']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
281
Server/thinkphp/library/think/console/Table.php
Normal file
281
Server/thinkphp/library/think/console/Table.php
Normal file
@@ -0,0 +1,281 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\console;
|
||||
|
||||
class Table
|
||||
{
|
||||
const ALIGN_LEFT = 1;
|
||||
const ALIGN_RIGHT = 0;
|
||||
const ALIGN_CENTER = 2;
|
||||
|
||||
/**
|
||||
* 头信息数据
|
||||
* @var array
|
||||
*/
|
||||
protected $header = [];
|
||||
|
||||
/**
|
||||
* 头部对齐方式 默认1 ALGIN_LEFT 0 ALIGN_RIGHT 2 ALIGN_CENTER
|
||||
* @var int
|
||||
*/
|
||||
protected $headerAlign = 1;
|
||||
|
||||
/**
|
||||
* 表格数据(二维数组)
|
||||
* @var array
|
||||
*/
|
||||
protected $rows = [];
|
||||
|
||||
/**
|
||||
* 单元格对齐方式 默认1 ALGIN_LEFT 0 ALIGN_RIGHT 2 ALIGN_CENTER
|
||||
* @var int
|
||||
*/
|
||||
protected $cellAlign = 1;
|
||||
|
||||
/**
|
||||
* 单元格宽度信息
|
||||
* @var array
|
||||
*/
|
||||
protected $colWidth = [];
|
||||
|
||||
/**
|
||||
* 表格输出样式
|
||||
* @var string
|
||||
*/
|
||||
protected $style = 'default';
|
||||
|
||||
/**
|
||||
* 表格样式定义
|
||||
* @var array
|
||||
*/
|
||||
protected $format = [
|
||||
'compact' => [],
|
||||
'default' => [
|
||||
'top' => ['+', '-', '+', '+'],
|
||||
'cell' => ['|', ' ', '|', '|'],
|
||||
'middle' => ['+', '-', '+', '+'],
|
||||
'bottom' => ['+', '-', '+', '+'],
|
||||
'cross-top' => ['+', '-', '-', '+'],
|
||||
'cross-bottom' => ['+', '-', '-', '+'],
|
||||
],
|
||||
'markdown' => [
|
||||
'top' => [' ', ' ', ' ', ' '],
|
||||
'cell' => ['|', ' ', '|', '|'],
|
||||
'middle' => ['|', '-', '|', '|'],
|
||||
'bottom' => [' ', ' ', ' ', ' '],
|
||||
'cross-top' => ['|', ' ', ' ', '|'],
|
||||
'cross-bottom' => ['|', ' ', ' ', '|'],
|
||||
],
|
||||
'borderless' => [
|
||||
'top' => ['=', '=', ' ', '='],
|
||||
'cell' => [' ', ' ', ' ', ' '],
|
||||
'middle' => ['=', '=', ' ', '='],
|
||||
'bottom' => ['=', '=', ' ', '='],
|
||||
'cross-top' => ['=', '=', ' ', '='],
|
||||
'cross-bottom' => ['=', '=', ' ', '='],
|
||||
],
|
||||
'box' => [
|
||||
'top' => ['┌', '─', '┬', '┐'],
|
||||
'cell' => ['│', ' ', '│', '│'],
|
||||
'middle' => ['├', '─', '┼', '┤'],
|
||||
'bottom' => ['└', '─', '┴', '┘'],
|
||||
'cross-top' => ['├', '─', '┴', '┤'],
|
||||
'cross-bottom' => ['├', '─', '┬', '┤'],
|
||||
],
|
||||
'box-double' => [
|
||||
'top' => ['╔', '═', '╤', '╗'],
|
||||
'cell' => ['║', ' ', '│', '║'],
|
||||
'middle' => ['╠', '─', '╪', '╣'],
|
||||
'bottom' => ['╚', '═', '╧', '╝'],
|
||||
'cross-top' => ['╠', '═', '╧', '╣'],
|
||||
'cross-bottom' => ['╠', '═', '╤', '╣'],
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* 设置表格头信息 以及对齐方式
|
||||
* @access public
|
||||
* @param array $header 要输出的Header信息
|
||||
* @param int $align 对齐方式 默认1 ALGIN_LEFT 0 ALIGN_RIGHT 2 ALIGN_CENTER
|
||||
* @return void
|
||||
*/
|
||||
public function setHeader(array $header, $align = self::ALIGN_LEFT)
|
||||
{
|
||||
$this->header = $header;
|
||||
$this->headerAlign = $align;
|
||||
|
||||
$this->checkColWidth($header);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置输出表格数据 及对齐方式
|
||||
* @access public
|
||||
* @param array $rows 要输出的表格数据(二维数组)
|
||||
* @param int $align 对齐方式 默认1 ALGIN_LEFT 0 ALIGN_RIGHT 2 ALIGN_CENTER
|
||||
* @return void
|
||||
*/
|
||||
public function setRows(array $rows, $align = self::ALIGN_LEFT)
|
||||
{
|
||||
$this->rows = $rows;
|
||||
$this->cellAlign = $align;
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$this->checkColWidth($row);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查列数据的显示宽度
|
||||
* @access public
|
||||
* @param mixed $row 行数据
|
||||
* @return void
|
||||
*/
|
||||
protected function checkColWidth($row)
|
||||
{
|
||||
if (is_array($row)) {
|
||||
foreach ($row as $key => $cell) {
|
||||
if (!isset($this->colWidth[$key]) || strlen($cell) > $this->colWidth[$key]) {
|
||||
$this->colWidth[$key] = strlen($cell);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加一行表格数据
|
||||
* @access public
|
||||
* @param mixed $row 行数据
|
||||
* @param bool $first 是否在开头插入
|
||||
* @return void
|
||||
*/
|
||||
public function addRow($row, $first = false)
|
||||
{
|
||||
if ($first) {
|
||||
array_unshift($this->rows, $row);
|
||||
} else {
|
||||
$this->rows[] = $row;
|
||||
}
|
||||
|
||||
$this->checkColWidth($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置输出表格的样式
|
||||
* @access public
|
||||
* @param string $style 样式名
|
||||
* @return void
|
||||
*/
|
||||
public function setStyle($style)
|
||||
{
|
||||
$this->style = isset($this->format[$style]) ? $style : 'default';
|
||||
}
|
||||
|
||||
/**
|
||||
* 输出分隔行
|
||||
* @access public
|
||||
* @param string $pos 位置
|
||||
* @return string
|
||||
*/
|
||||
protected function renderSeparator($pos)
|
||||
{
|
||||
$style = $this->getStyle($pos);
|
||||
$array = [];
|
||||
|
||||
foreach ($this->colWidth as $width) {
|
||||
$array[] = str_repeat($style[1], $width + 2);
|
||||
}
|
||||
|
||||
return $style[0] . implode($style[2], $array) . $style[3] . PHP_EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* 输出表格头部
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
protected function renderHeader()
|
||||
{
|
||||
$style = $this->getStyle('cell');
|
||||
$content = $this->renderSeparator('top');
|
||||
|
||||
foreach ($this->header as $key => $header) {
|
||||
$array[] = ' ' . str_pad($header, $this->colWidth[$key], $style[1], $this->headerAlign);
|
||||
}
|
||||
|
||||
if (!empty($array)) {
|
||||
$content .= $style[0] . implode(' ' . $style[2], $array) . ' ' . $style[3] . PHP_EOL;
|
||||
|
||||
if ($this->rows) {
|
||||
$content .= $this->renderSeparator('middle');
|
||||
}
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
protected function getStyle($style)
|
||||
{
|
||||
if ($this->format[$this->style]) {
|
||||
$style = $this->format[$this->style][$style];
|
||||
} else {
|
||||
$style = [' ', ' ', ' ', ' '];
|
||||
}
|
||||
|
||||
return $style;
|
||||
}
|
||||
|
||||
/**
|
||||
* 输出表格
|
||||
* @access public
|
||||
* @param array $dataList 表格数据
|
||||
* @return string
|
||||
*/
|
||||
public function render($dataList = [])
|
||||
{
|
||||
if ($dataList) {
|
||||
$this->setRows($dataList);
|
||||
}
|
||||
|
||||
// 输出头部
|
||||
$content = $this->renderHeader();
|
||||
$style = $this->getStyle('cell');
|
||||
|
||||
if ($this->rows) {
|
||||
foreach ($this->rows as $row) {
|
||||
if (is_string($row) && '-' === $row) {
|
||||
$content .= $this->renderSeparator('middle');
|
||||
} elseif (is_scalar($row)) {
|
||||
$content .= $this->renderSeparator('cross-top');
|
||||
$array = str_pad($row, 3 * (count($this->colWidth) - 1) + array_reduce($this->colWidth, function ($a, $b) {
|
||||
return $a + $b;
|
||||
}));
|
||||
|
||||
$content .= $style[0] . ' ' . $array . ' ' . $style[3] . PHP_EOL;
|
||||
$content .= $this->renderSeparator('cross-bottom');
|
||||
} else {
|
||||
$array = [];
|
||||
|
||||
foreach ($row as $key => $val) {
|
||||
$array[] = ' ' . str_pad($val, $this->colWidth[$key], ' ', $this->cellAlign);
|
||||
}
|
||||
|
||||
$content .= $style[0] . implode(' ' . $style[2], $array) . ' ' . $style[3] . PHP_EOL;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$content .= $this->renderSeparator('bottom');
|
||||
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
130
Server/thinkphp/library/think/console/command/RouteList.php
Normal file
130
Server/thinkphp/library/think/console/command/RouteList.php
Normal file
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace think\console\command;
|
||||
|
||||
use think\console\Command;
|
||||
use think\console\Input;
|
||||
use think\console\input\Argument;
|
||||
use think\console\input\Option;
|
||||
use think\console\Output;
|
||||
use think\console\Table;
|
||||
use think\Container;
|
||||
|
||||
class RouteList extends Command
|
||||
{
|
||||
protected $sortBy = [
|
||||
'rule' => 0,
|
||||
'route' => 1,
|
||||
'method' => 2,
|
||||
'name' => 3,
|
||||
'domain' => 4,
|
||||
];
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('route:list')
|
||||
->addArgument('style', Argument::OPTIONAL, "the style of the table.", 'default')
|
||||
->addOption('sort', 's', Option::VALUE_OPTIONAL, 'order by rule name.', 0)
|
||||
->addOption('more', 'm', Option::VALUE_NONE, 'show route options.')
|
||||
->setDescription('show route list.');
|
||||
}
|
||||
|
||||
protected function execute(Input $input, Output $output)
|
||||
{
|
||||
$filename = Container::get('app')->getRuntimePath() . 'route_list.php';
|
||||
|
||||
if (is_file($filename)) {
|
||||
unlink($filename);
|
||||
}
|
||||
|
||||
$content = $this->getRouteList();
|
||||
file_put_contents($filename, 'Route List' . PHP_EOL . $content);
|
||||
}
|
||||
|
||||
protected function getRouteList()
|
||||
{
|
||||
Container::get('route')->setTestMode(true);
|
||||
// 路由检测
|
||||
$path = Container::get('app')->getRoutePath();
|
||||
|
||||
$files = is_dir($path) ? scandir($path) : [];
|
||||
|
||||
foreach ($files as $file) {
|
||||
if (strpos($file, '.php')) {
|
||||
$filename = $path . DIRECTORY_SEPARATOR . $file;
|
||||
// 导入路由配置
|
||||
$rules = include $filename;
|
||||
|
||||
if (is_array($rules)) {
|
||||
Container::get('route')->import($rules);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Container::get('config')->get('route_annotation')) {
|
||||
$suffix = Container::get('config')->get('controller_suffix') || Container::get('config')->get('class_suffix');
|
||||
|
||||
include Container::get('build')->buildRoute($suffix);
|
||||
}
|
||||
|
||||
$table = new Table();
|
||||
|
||||
if ($this->input->hasOption('more')) {
|
||||
$header = ['Rule', 'Route', 'Method', 'Name', 'Domain', 'Option', 'Pattern'];
|
||||
} else {
|
||||
$header = ['Rule', 'Route', 'Method', 'Name', 'Domain'];
|
||||
}
|
||||
|
||||
$table->setHeader($header);
|
||||
|
||||
$routeList = Container::get('route')->getRuleList();
|
||||
$rows = [];
|
||||
|
||||
foreach ($routeList as $domain => $items) {
|
||||
foreach ($items as $item) {
|
||||
$item['route'] = $item['route'] instanceof \Closure ? '<Closure>' : $item['route'];
|
||||
|
||||
if ($this->input->hasOption('more')) {
|
||||
$item = [$item['rule'], $item['route'], $item['method'], $item['name'], $domain, json_encode($item['option']), json_encode($item['pattern'])];
|
||||
} else {
|
||||
$item = [$item['rule'], $item['route'], $item['method'], $item['name'], $domain];
|
||||
}
|
||||
|
||||
$rows[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->input->getOption('sort')) {
|
||||
$sort = $this->input->getOption('sort');
|
||||
|
||||
if (isset($this->sortBy[$sort])) {
|
||||
$sort = $this->sortBy[$sort];
|
||||
}
|
||||
|
||||
uasort($rows, function ($a, $b) use ($sort) {
|
||||
$itemA = isset($a[$sort]) ? $a[$sort] : null;
|
||||
$itemB = isset($b[$sort]) ? $b[$sort] : null;
|
||||
|
||||
return strcasecmp($itemA, $itemB);
|
||||
});
|
||||
}
|
||||
|
||||
$table->setRows($rows);
|
||||
|
||||
if ($this->input->getArgument('style')) {
|
||||
$style = $this->input->getArgument('style');
|
||||
$table->setStyle($style);
|
||||
}
|
||||
|
||||
return $this->table($table);
|
||||
}
|
||||
|
||||
}
|
||||
53
Server/thinkphp/library/think/console/command/RunServer.php
Normal file
53
Server/thinkphp/library/think/console/command/RunServer.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Slince <taosikai@yeah.net>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace think\console\command;
|
||||
|
||||
use think\console\Command;
|
||||
use think\console\Input;
|
||||
use think\console\input\Option;
|
||||
use think\console\Output;
|
||||
use think\facade\App;
|
||||
|
||||
class RunServer extends Command
|
||||
{
|
||||
public function configure()
|
||||
{
|
||||
$this->setName('run')
|
||||
->addOption('host', 'H', Option::VALUE_OPTIONAL,
|
||||
'The host to server the application on', '127.0.0.1')
|
||||
->addOption('port', 'p', Option::VALUE_OPTIONAL,
|
||||
'The port to server the application on', 8000)
|
||||
->addOption('root', 'r', Option::VALUE_OPTIONAL,
|
||||
'The document root of the application', App::getRootPath() . 'public')
|
||||
->setDescription('PHP Built-in Server for ThinkPHP');
|
||||
}
|
||||
|
||||
public function execute(Input $input, Output $output)
|
||||
{
|
||||
$host = $input->getOption('host');
|
||||
$port = $input->getOption('port');
|
||||
$root = $input->getOption('root');
|
||||
|
||||
$command = sprintf(
|
||||
'php -S %s:%d -t %s %s',
|
||||
$host,
|
||||
$port,
|
||||
escapeshellarg($root),
|
||||
escapeshellarg($root . DIRECTORY_SEPARATOR . 'router.php')
|
||||
);
|
||||
|
||||
$output->writeln(sprintf('ThinkPHP Development server is started On <http://%s:%s/>', $host, $port));
|
||||
$output->writeln(sprintf('You can exit with <info>`CTRL-C`</info>'));
|
||||
$output->writeln(sprintf('Document root is: %s', $root));
|
||||
passthru($command);
|
||||
}
|
||||
|
||||
}
|
||||
31
Server/thinkphp/library/think/console/command/Version.php
Normal file
31
Server/thinkphp/library/think/console/command/Version.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace think\console\command;
|
||||
|
||||
use think\console\Command;
|
||||
use think\console\Input;
|
||||
use think\console\Output;
|
||||
use think\facade\App;
|
||||
|
||||
class Version extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
// 指令配置
|
||||
$this->setName('version')
|
||||
->setDescription('show thinkphp framework version');
|
||||
}
|
||||
|
||||
protected function execute(Input $input, Output $output)
|
||||
{
|
||||
$output->writeln('v' . App::version());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: 刘志淳 <chun@engineer.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\console\command\make;
|
||||
|
||||
use think\console\command\Make;
|
||||
use think\console\input\Argument;
|
||||
use think\facade\App;
|
||||
|
||||
class Command extends Make
|
||||
{
|
||||
protected $type = "Command";
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
parent::configure();
|
||||
$this->setName('make:command')
|
||||
->addArgument('commandName', Argument::OPTIONAL, "The name of the command")
|
||||
->setDescription('Create a new command class');
|
||||
}
|
||||
|
||||
protected function buildClass($name)
|
||||
{
|
||||
$commandName = $this->input->getArgument('commandName') ?: strtolower(basename($name));
|
||||
$namespace = trim(implode('\\', array_slice(explode('\\', $name), 0, -1)), '\\');
|
||||
|
||||
$class = str_replace($namespace . '\\', '', $name);
|
||||
$stub = file_get_contents($this->getStub());
|
||||
|
||||
return str_replace(['{%commandName%}', '{%className%}', '{%namespace%}', '{%app_namespace%}'], [
|
||||
$commandName,
|
||||
$class,
|
||||
$namespace,
|
||||
App::getNamespace(),
|
||||
], $stub);
|
||||
}
|
||||
|
||||
protected function getStub()
|
||||
{
|
||||
return __DIR__ . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR . 'command.stub';
|
||||
}
|
||||
|
||||
protected function getNamespace($appNamespace, $module)
|
||||
{
|
||||
return $appNamespace . '\\command';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: 刘志淳 <chun@engineer.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\console\command\make;
|
||||
|
||||
use think\console\command\Make;
|
||||
|
||||
class Middleware extends Make
|
||||
{
|
||||
protected $type = "Middleware";
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
parent::configure();
|
||||
$this->setName('make:middleware')
|
||||
->setDescription('Create a new middleware class');
|
||||
}
|
||||
|
||||
protected function getStub()
|
||||
{
|
||||
return __DIR__ . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR . 'middleware.stub';
|
||||
}
|
||||
|
||||
protected function getNamespace($appNamespace, $module)
|
||||
{
|
||||
return parent::getNamespace($appNamespace, 'http') . '\middleware';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: 刘志淳 <chun@engineer.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\console\command\make;
|
||||
|
||||
use think\console\command\Make;
|
||||
|
||||
class Validate extends Make
|
||||
{
|
||||
protected $type = "Validate";
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
parent::configure();
|
||||
$this->setName('make:validate')
|
||||
->setDescription('Create a validate class');
|
||||
}
|
||||
|
||||
protected function getStub()
|
||||
{
|
||||
$stubPath = __DIR__ . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR;
|
||||
|
||||
return $stubPath . 'validate.stub';
|
||||
}
|
||||
|
||||
protected function getNamespace($appNamespace, $module)
|
||||
{
|
||||
return parent::getNamespace($appNamespace, $module) . '\validate';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace {%namespace%};
|
||||
|
||||
use think\console\Command;
|
||||
use think\console\Input;
|
||||
use think\console\Output;
|
||||
|
||||
class {%className%} extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
// 指令配置
|
||||
$this->setName('{%commandName%}');
|
||||
// 设置参数
|
||||
|
||||
}
|
||||
|
||||
protected function execute(Input $input, Output $output)
|
||||
{
|
||||
// 指令输出
|
||||
$output->writeln('{%commandName%}');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace {%namespace%};
|
||||
|
||||
use think\Controller;
|
||||
use think\Request;
|
||||
|
||||
class {%className%} extends Controller
|
||||
{
|
||||
/**
|
||||
* 显示资源列表
|
||||
*
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function index{%actionSuffix%}()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存新建的资源
|
||||
*
|
||||
* @param \think\Request $request
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function save{%actionSuffix%}(Request $request)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示指定的资源
|
||||
*
|
||||
* @param int $id
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function read{%actionSuffix%}($id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存更新的资源
|
||||
*
|
||||
* @param \think\Request $request
|
||||
* @param int $id
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function update{%actionSuffix%}(Request $request, $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除指定资源
|
||||
*
|
||||
* @param int $id
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function delete{%actionSuffix%}($id)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace {%namespace%};
|
||||
|
||||
class {%className%}
|
||||
{
|
||||
public function handle($request, \Closure $next)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace {%namespace%};
|
||||
|
||||
use think\Validate;
|
||||
|
||||
class {%className%} extends Validate
|
||||
{
|
||||
/**
|
||||
* 定义验证规则
|
||||
* 格式:'字段名' => ['规则1','规则2'...]
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $rule = [];
|
||||
|
||||
/**
|
||||
* 定义错误信息
|
||||
* 格式:'字段名.规则名' => '错误信息'
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $message = [];
|
||||
}
|
||||
178
Server/thinkphp/library/think/db/Where.php
Normal file
178
Server/thinkphp/library/think/db/Where.php
Normal file
@@ -0,0 +1,178 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\db;
|
||||
|
||||
use ArrayAccess;
|
||||
|
||||
class Where implements ArrayAccess
|
||||
{
|
||||
/**
|
||||
* 查询表达式
|
||||
* @var array
|
||||
*/
|
||||
protected $where = [];
|
||||
|
||||
/**
|
||||
* 是否需要增加括号
|
||||
* @var bool
|
||||
*/
|
||||
protected $enclose = false;
|
||||
|
||||
/**
|
||||
* 创建一个查询表达式
|
||||
*
|
||||
* @param array $where 查询条件数组
|
||||
* @param bool $enclose 是否增加括号
|
||||
*/
|
||||
public function __construct(array $where = [], $enclose = false)
|
||||
{
|
||||
$this->where = $where;
|
||||
$this->enclose = $enclose;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置是否添加括号
|
||||
* @access public
|
||||
* @param bool $enclose
|
||||
* @return $this
|
||||
*/
|
||||
public function enclose($enclose = true)
|
||||
{
|
||||
$this->enclose = $enclose;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析为Query对象可识别的查询条件数组
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function parse()
|
||||
{
|
||||
$where = [];
|
||||
|
||||
foreach ($this->where as $key => $val) {
|
||||
if ($val instanceof Expression) {
|
||||
$where[] = [$key, 'exp', $val];
|
||||
} elseif (is_null($val)) {
|
||||
$where[] = [$key, 'NULL', ''];
|
||||
} elseif (is_array($val)) {
|
||||
$where[] = $this->parseItem($key, $val);
|
||||
} else {
|
||||
$where[] = [$key, '=', $val];
|
||||
}
|
||||
}
|
||||
|
||||
return $this->enclose ? [$where] : $where;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分析查询表达式
|
||||
* @access protected
|
||||
* @param string $field 查询字段
|
||||
* @param array $where 查询条件
|
||||
* @return array
|
||||
*/
|
||||
protected function parseItem($field, $where = [])
|
||||
{
|
||||
$op = $where[0];
|
||||
$condition = isset($where[1]) ? $where[1] : null;
|
||||
|
||||
if (is_array($op)) {
|
||||
// 同一字段多条件查询
|
||||
array_unshift($where, $field);
|
||||
} elseif (is_null($condition)) {
|
||||
if (in_array(strtoupper($op), ['NULL', 'NOTNULL', 'NOT NULL'], true)) {
|
||||
// null查询
|
||||
$where = [$field, $op, ''];
|
||||
} elseif (in_array($op, ['=', 'eq', 'EQ', null], true)) {
|
||||
$where = [$field, 'NULL', ''];
|
||||
} elseif (in_array($op, ['<>', 'neq', 'NEQ'], true)) {
|
||||
$where = [$field, 'NOTNULL', ''];
|
||||
} else {
|
||||
// 字段相等查询
|
||||
$where = [$field, '=', $op];
|
||||
}
|
||||
} else {
|
||||
$where = [$field, $op, $condition];
|
||||
}
|
||||
|
||||
return $where;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改器 设置数据对象的值
|
||||
* @access public
|
||||
* @param string $name 名称
|
||||
* @param mixed $value 值
|
||||
* @return void
|
||||
*/
|
||||
public function __set($name, $value)
|
||||
{
|
||||
$this->where[$name] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取器 获取数据对象的值
|
||||
* @access public
|
||||
* @param string $name 名称
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
return isset($this->where[$name]) ? $this->where[$name] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测数据对象的值
|
||||
* @access public
|
||||
* @param string $name 名称
|
||||
* @return boolean
|
||||
*/
|
||||
public function __isset($name)
|
||||
{
|
||||
return isset($this->where[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 销毁数据对象的值
|
||||
* @access public
|
||||
* @param string $name 名称
|
||||
* @return void
|
||||
*/
|
||||
public function __unset($name)
|
||||
{
|
||||
unset($this->where[$name]);
|
||||
}
|
||||
|
||||
// ArrayAccess
|
||||
public function offsetSet($name, $value)
|
||||
{
|
||||
$this->__set($name, $value);
|
||||
}
|
||||
|
||||
public function offsetExists($name)
|
||||
{
|
||||
return $this->__isset($name);
|
||||
}
|
||||
|
||||
public function offsetUnset($name)
|
||||
{
|
||||
$this->__unset($name);
|
||||
}
|
||||
|
||||
public function offsetGet($name)
|
||||
{
|
||||
return $this->__get($name);
|
||||
}
|
||||
|
||||
}
|
||||
63
Server/thinkphp/library/think/facade/App.php
Normal file
63
Server/thinkphp/library/think/facade/App.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\facade;
|
||||
|
||||
use think\Facade;
|
||||
|
||||
/**
|
||||
* @see \think\App
|
||||
* @mixin \think\App
|
||||
* @method \think\App bind(string $bind) static 绑定模块或者控制器
|
||||
* @method void initialize() static 初始化应用
|
||||
* @method void init(string $module='') static 初始化模块
|
||||
* @method \think\Response run() static 执行应用
|
||||
* @method \think\App dispatch(\think\route\Dispatch $dispatch) static 设置当前请求的调度信息
|
||||
* @method void log(mixed $log, string $type = 'info') static 记录调试信息
|
||||
* @method mixed config(string $name='') static 获取配置参数
|
||||
* @method \think\route\Dispatch routeCheck() static URL路由检测(根据PATH_INFO)
|
||||
* @method \think\App routeMust(bool $must = false) static 设置应用的路由检测机制
|
||||
* @method \think\Model model(string $name = '', string $layer = 'model', bool $appendSuffix = false, string $common = 'common') static 实例化模型
|
||||
* @method object controller(string $name, string $layer = 'controller', bool $appendSuffix = false, string $empty = '') static 实例化控制器
|
||||
* @method \think\Validate validate(string $name = '', string $layer = 'validate', bool $appendSuffix = false, string $common = 'common') static 实例化验证器类
|
||||
* @method \think\db\Query db(mixed $config = [], mixed $name = false) static 数据库初始化
|
||||
* @method mixed action(string $url, $vars = [], $layer = 'controller', $appendSuffix = false) static 调用模块的操作方法
|
||||
* @method string parseClass(string $module, string $layer, string $name, bool $appendSuffix = false) static 解析应用类的类名
|
||||
* @method string version() static 获取框架版本
|
||||
* @method bool isDebug() static 是否为调试模式
|
||||
* @method string getModulePath() static 获取当前模块路径
|
||||
* @method void setModulePath(string $path) static 设置当前模块路径
|
||||
* @method string getRootPath() static 获取应用根目录
|
||||
* @method string getAppPath() static 获取应用类库目录
|
||||
* @method string getRuntimePath() static 获取应用运行时目录
|
||||
* @method string getThinkPath() static 获取核心框架目录
|
||||
* @method string getRoutePath() static 获取路由目录
|
||||
* @method string getConfigPath() static 获取应用配置目录
|
||||
* @method string getConfigExt() static 获取配置后缀
|
||||
* @method string setNamespace(string $namespace) static 设置应用类库命名空间
|
||||
* @method string getNamespace() static 获取应用类库命名空间
|
||||
* @method string getSuffix() static 是否启用类库后缀
|
||||
* @method float getBeginTime() static 获取应用开启时间
|
||||
* @method integer getBeginMem() static 获取应用初始内存占用
|
||||
* @method \think\Container container() static 获取容器实例
|
||||
*/
|
||||
class App extends Facade
|
||||
{
|
||||
/**
|
||||
* 获取当前Facade对应类名(或者已经绑定的容器对象标识)
|
||||
* @access protected
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeClass()
|
||||
{
|
||||
return 'app';
|
||||
}
|
||||
}
|
||||
33
Server/thinkphp/library/think/facade/Build.php
Normal file
33
Server/thinkphp/library/think/facade/Build.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\facade;
|
||||
|
||||
use think\Facade;
|
||||
|
||||
/**
|
||||
* @see \think\Build
|
||||
* @mixin \think\Build
|
||||
* @method void run(array $build = [], string $namespace = 'app', bool $suffix = false) static 根据传入的build资料创建目录和文件
|
||||
* @method void module(string $module = '', array $list = [], string $namespace = 'app', bool $suffix = false) static 创建模块
|
||||
*/
|
||||
class Build extends Facade
|
||||
{
|
||||
/**
|
||||
* 获取当前Facade对应类名(或者已经绑定的容器对象标识)
|
||||
* @access protected
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeClass()
|
||||
{
|
||||
return 'build';
|
||||
}
|
||||
}
|
||||
45
Server/thinkphp/library/think/facade/Cache.php
Normal file
45
Server/thinkphp/library/think/facade/Cache.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\facade;
|
||||
|
||||
use think\Facade;
|
||||
|
||||
/**
|
||||
* @see \think\Cache
|
||||
* @mixin \think\Cache
|
||||
* @method \think\cache\Driver connect(array $options = [], mixed $name = false) static 连接缓存
|
||||
* @method \think\cache\Driver init(array $options = []) static 初始化缓存
|
||||
* @method \think\cache\Driver store(string $name = '') static 切换缓存类型
|
||||
* @method bool has(string $name) static 判断缓存是否存在
|
||||
* @method mixed get(string $name, mixed $default = false) static 读取缓存
|
||||
* @method mixed pull(string $name) static 读取缓存并删除
|
||||
* @method mixed set(string $name, mixed $value, int $expire = null) static 设置缓存
|
||||
* @method mixed remember(string $name, mixed $value, int $expire = null) static 如果不存在则写入缓存
|
||||
* @method mixed inc(string $name, int $step = 1) static 自增缓存(针对数值缓存)
|
||||
* @method mixed dec(string $name, int $step = 1) static 自减缓存(针对数值缓存)
|
||||
* @method bool rm(string $name) static 删除缓存
|
||||
* @method bool clear(string $tag = null) static 清除缓存
|
||||
* @method mixed tag(string $name, mixed $keys = null, bool $overlay = false) static 缓存标签
|
||||
* @method object handler() static 返回句柄对象,可执行其它高级方法
|
||||
*/
|
||||
class Cache extends Facade
|
||||
{
|
||||
/**
|
||||
* 获取当前Facade对应类名(或者已经绑定的容器对象标识)
|
||||
* @access protected
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeClass()
|
||||
{
|
||||
return 'cache';
|
||||
}
|
||||
}
|
||||
39
Server/thinkphp/library/think/facade/Config.php
Normal file
39
Server/thinkphp/library/think/facade/Config.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\facade;
|
||||
|
||||
use think\Facade;
|
||||
|
||||
/**
|
||||
* @see \think\Config
|
||||
* @mixin \think\Config
|
||||
* @method array load(string $file, string $name = '') static 加载配置文件
|
||||
* @method bool has(string $name) static 检测配置是否存在
|
||||
* @method array pull(string $name) static 获取一级配置参数
|
||||
* @method mixed get(string $name,mixed $default = null) static 获取配置参数
|
||||
* @method array set(mixed $name, mixed $value = null) static 设置配置参数
|
||||
* @method array reset(string $name ='') static 重置配置参数
|
||||
* @method void remove(string $name = '') static 移除配置
|
||||
* @method void setYaconf(mixed $yaconf) static 设置开启Yaconf 或者指定配置文件名
|
||||
*/
|
||||
class Config extends Facade
|
||||
{
|
||||
/**
|
||||
* 获取当前Facade对应类名(或者已经绑定的容器对象标识)
|
||||
* @access protected
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeClass()
|
||||
{
|
||||
return 'config';
|
||||
}
|
||||
}
|
||||
39
Server/thinkphp/library/think/facade/Cookie.php
Normal file
39
Server/thinkphp/library/think/facade/Cookie.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\facade;
|
||||
|
||||
use think\Facade;
|
||||
|
||||
/**
|
||||
* @see \think\Cookie
|
||||
* @mixin \think\Cookie
|
||||
* @method void init(array $config = []) static 初始化
|
||||
* @method bool has(string $name,string $prefix = null) static 判断Cookie数据
|
||||
* @method mixed prefix(string $prefix = '') static 设置或者获取cookie作用域(前缀)
|
||||
* @method mixed get(string $name,string $prefix = null) static Cookie获取
|
||||
* @method mixed set(string $name, mixed $value = null, mixed $option = null) static 设置Cookie
|
||||
* @method void forever(string $name, mixed $value = null, mixed $option = null) static 永久保存Cookie数据
|
||||
* @method void delete(string $name, string $prefix = null) static Cookie删除
|
||||
* @method void clear($prefix = null) static Cookie清空
|
||||
*/
|
||||
class Cookie extends Facade
|
||||
{
|
||||
/**
|
||||
* 获取当前Facade对应类名(或者已经绑定的容器对象标识)
|
||||
* @access protected
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeClass()
|
||||
{
|
||||
return 'cookie';
|
||||
}
|
||||
}
|
||||
40
Server/thinkphp/library/think/facade/Debug.php
Normal file
40
Server/thinkphp/library/think/facade/Debug.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\facade;
|
||||
|
||||
use think\Facade;
|
||||
|
||||
/**
|
||||
* @see \think\Debug
|
||||
* @mixin \think\Debug
|
||||
* @method void remark(string $name, mixed $value = '') static 记录时间(微秒)和内存使用情况
|
||||
* @method int getRangeTime(string $start, string $end, mixed $dec = 6) static 统计某个区间的时间(微秒)使用情况
|
||||
* @method int getUseTime(int $dec = 6) static 统计从开始到统计时的时间(微秒)使用情况
|
||||
* @method string getThroughputRate(string $start, string $end, mixed $dec = 6) static 获取当前访问的吞吐率情况
|
||||
* @method string getRangeMem(string $start, string $end, mixed $dec = 2) static 记录区间的内存使用情况
|
||||
* @method int getUseMem(int $dec = 2) static 统计从开始到统计时的内存使用情况
|
||||
* @method string getMemPeak(string $start, string $end, mixed $dec = 2) static 统计区间的内存峰值情况
|
||||
* @method mixed getFile(bool $detail = false) static 获取文件加载信息
|
||||
* @method mixed dump(mixed $var, bool $echo = true, string $label = null, int $flags = ENT_SUBSTITUTE) static 浏览器友好的变量输出
|
||||
*/
|
||||
class Debug extends Facade
|
||||
{
|
||||
/**
|
||||
* 获取当前Facade对应类名(或者已经绑定的容器对象标识)
|
||||
* @access protected
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeClass()
|
||||
{
|
||||
return 'debug';
|
||||
}
|
||||
}
|
||||
34
Server/thinkphp/library/think/facade/Env.php
Normal file
34
Server/thinkphp/library/think/facade/Env.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\facade;
|
||||
|
||||
use think\Facade;
|
||||
|
||||
/**
|
||||
* @see \think\Env
|
||||
* @mixin \think\Env
|
||||
* @method void load(string $file) static 读取环境变量定义文件
|
||||
* @method mixed get(string $name = null, mixed $default = null) static 获取环境变量值
|
||||
* @method void set(mixed $env, string $value = null) static 设置环境变量值
|
||||
*/
|
||||
class Env extends Facade
|
||||
{
|
||||
/**
|
||||
* 获取当前Facade对应类名(或者已经绑定的容器对象标识)
|
||||
* @access protected
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeClass()
|
||||
{
|
||||
return 'env';
|
||||
}
|
||||
}
|
||||
37
Server/thinkphp/library/think/facade/Hook.php
Normal file
37
Server/thinkphp/library/think/facade/Hook.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\facade;
|
||||
|
||||
use think\Facade;
|
||||
|
||||
/**
|
||||
* @see \think\Hook
|
||||
* @mixin \think\Hook
|
||||
* @method \think\Hook alias(mixed $name, mixed $behavior = null) static 指定行为标识
|
||||
* @method void add(string $tag, mixed $behavior, bool $first = false) static 动态添加行为扩展到某个标签
|
||||
* @method void import(array $tags, bool $recursive = true) static 批量导入插件
|
||||
* @method array get(string $tag = '') static 获取插件信息
|
||||
* @method mixed listen(string $tag, mixed $params = null, bool $once = false) static 监听标签的行为
|
||||
* @method mixed exec(mixed $class, mixed $params = null) static 执行行为
|
||||
*/
|
||||
class Hook extends Facade
|
||||
{
|
||||
/**
|
||||
* 获取当前Facade对应类名(或者已经绑定的容器对象标识)
|
||||
* @access protected
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeClass()
|
||||
{
|
||||
return 'hook';
|
||||
}
|
||||
}
|
||||
41
Server/thinkphp/library/think/facade/Lang.php
Normal file
41
Server/thinkphp/library/think/facade/Lang.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\facade;
|
||||
|
||||
use think\Facade;
|
||||
|
||||
/**
|
||||
* @see \think\Lang
|
||||
* @mixin \think\Lang
|
||||
* @method mixed range($range = '') static 设定当前的语言
|
||||
* @method mixed set(mixed $name, string $value = null, string $range = '') static 设置语言定义
|
||||
* @method array load(mixed $file, string $range = '') static 加载语言定义
|
||||
* @method mixed get(string $name = null, array $vars = [], string $range = '') static 获取语言定义
|
||||
* @method mixed has(string $name, string $range = '') static 获取语言定义
|
||||
* @method string detect() static 自动侦测设置获取语言选择
|
||||
* @method void saveToCookie(string $lang = null) static 设置当前语言到Cookie
|
||||
* @method void setLangDetectVar(string $var) static 设置语言自动侦测的变量
|
||||
* @method void setLangCookieVar(string $var) static 设置语言的cookie保存变量
|
||||
* @method void setAllowLangList(array $list) static 设置允许的语言列表
|
||||
*/
|
||||
class Lang extends Facade
|
||||
{
|
||||
/**
|
||||
* 获取当前Facade对应类名(或者已经绑定的容器对象标识)
|
||||
* @access protected
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeClass()
|
||||
{
|
||||
return 'lang';
|
||||
}
|
||||
}
|
||||
50
Server/thinkphp/library/think/facade/Log.php
Normal file
50
Server/thinkphp/library/think/facade/Log.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\facade;
|
||||
|
||||
use think\Facade;
|
||||
|
||||
/**
|
||||
* @see \think\Log
|
||||
* @mixin \think\Log
|
||||
* @method \think\Log init(array $config = []) static 日志初始化
|
||||
* @method mixed getLog(string $type = '') static 获取日志信息
|
||||
* @method \think\Log record(mixed $msg, string $type = 'info', array $context = []) static 记录日志信息
|
||||
* @method \think\Log clear() static 清空日志信息
|
||||
* @method \think\Log key(string $key) static 当前日志记录的授权key
|
||||
* @method \think\Log close() static 关闭本次请求日志写入
|
||||
* @method bool check(array $config) static 检查日志写入权限
|
||||
* @method bool save() static 保存调试信息
|
||||
* @method void write(mixed $msg, string $type = 'info', bool $force = false) static 实时写入日志信息
|
||||
* @method void log(string $level,mixed $message, array $context = []) static 记录日志信息
|
||||
* @method void emergency(mixed $message, array $context = []) static 记录emergency信息
|
||||
* @method void alert(mixed $message, array $context = []) static 记录alert信息
|
||||
* @method void critical(mixed $message, array $context = []) static 记录critical信息
|
||||
* @method void error(mixed $message, array $context = []) static 记录error信息
|
||||
* @method void warning(mixed $message, array $context = []) static 记录warning信息
|
||||
* @method void notice(mixed $message, array $context = []) static 记录notice信息
|
||||
* @method void info(mixed $message, array $context = []) static 记录info信息
|
||||
* @method void debug(mixed $message, array $context = []) static 记录debug信息
|
||||
* @method void sql(mixed $message, array $context = []) static 记录sql信息
|
||||
*/
|
||||
class Log extends Facade
|
||||
{
|
||||
/**
|
||||
* 获取当前Facade对应类名(或者已经绑定的容器对象标识)
|
||||
* @access protected
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeClass()
|
||||
{
|
||||
return 'log';
|
||||
}
|
||||
}
|
||||
36
Server/thinkphp/library/think/facade/Middleware.php
Normal file
36
Server/thinkphp/library/think/facade/Middleware.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\facade;
|
||||
|
||||
use think\Facade;
|
||||
|
||||
/**
|
||||
* @see \think\Middleware
|
||||
* @mixin \think\Middleware
|
||||
* @method void import(array $middlewares = []) static 批量设置中间件
|
||||
* @method void add(mixed $middleware) static 添加中间件到队列
|
||||
* @method void unshift(mixed $middleware) static 添加中间件到队列开头
|
||||
* @method array all() static 获取中间件队列
|
||||
* @method \think\Response dispatch(\think\Request $request) static 执行中间件调度
|
||||
*/
|
||||
class Middleware extends Facade
|
||||
{
|
||||
/**
|
||||
* 获取当前Facade对应类名(或者已经绑定的容器对象标识)
|
||||
* @access protected
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeClass()
|
||||
{
|
||||
return 'middleware';
|
||||
}
|
||||
}
|
||||
97
Server/thinkphp/library/think/facade/Request.php
Normal file
97
Server/thinkphp/library/think/facade/Request.php
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\facade;
|
||||
|
||||
use think\Facade;
|
||||
|
||||
/**
|
||||
* @see \think\Request
|
||||
* @mixin \think\Request
|
||||
* @method void hook(mixed $method, mixed $callback = null) static Hook 方法注入
|
||||
* @method \think\Request create(string $uri, string $method = 'GET', array $params = [], array $cookie = [], array $files = [], array $server = [], string $content = null) static 创建一个URL请求
|
||||
* @method mixed domain(bool $port = false) static 获取当前包含协议、端口的域名
|
||||
* @method mixed url(bool $domain = false) static 获取当前完整URL
|
||||
* @method mixed baseUrl(bool $domain = false) static 获取当前URL
|
||||
* @method mixed baseFile(bool $domain = false) static 获取当前执行的文件
|
||||
* @method mixed root(bool $domain = false) static 获取URL访问根地址
|
||||
* @method string rootUrl() static 获取URL访问根目录
|
||||
* @method string pathinfo() static 获取当前请求URL的pathinfo信息(含URL后缀)
|
||||
* @method string path() static 获取当前请求URL的pathinfo信息(不含URL后缀)
|
||||
* @method string ext() static 当前URL的访问后缀
|
||||
* @method float time(bool $float = false) static 获取当前请求的时间
|
||||
* @method mixed type() static 当前请求的资源类型
|
||||
* @method void mimeType(mixed $type, string $val = '') static 设置资源类型
|
||||
* @method string method(bool $method = false) static 当前的请求类型
|
||||
* @method bool isGet() static 是否为GET请求
|
||||
* @method bool isPost() static 是否为POST请求
|
||||
* @method bool isPut() static 是否为PUT请求
|
||||
* @method bool isDelete() static 是否为DELTE请求
|
||||
* @method bool isHead() static 是否为HEAD请求
|
||||
* @method bool isPatch() static 是否为PATCH请求
|
||||
* @method bool isOptions() static 是否为OPTIONS请求
|
||||
* @method bool isCli() static 是否为cli
|
||||
* @method bool isCgi() static 是否为cgi
|
||||
* @method mixed param(string $name = '', mixed $default = null, mixed $filter = '') static 获取当前请求的参数
|
||||
* @method mixed route(string $name = '', mixed $default = null, mixed $filter = '') static 设置获取路由参数
|
||||
* @method mixed get(string $name = '', mixed $default = null, mixed $filter = '') static 设置获取GET参数
|
||||
* @method mixed post(string $name = '', mixed $default = null, mixed $filter = '') static 设置获取POST参数
|
||||
* @method mixed put(string $name = '', mixed $default = null, mixed $filter = '') static 设置获取PUT参数
|
||||
* @method mixed delete(string $name = '', mixed $default = null, mixed $filter = '') static 设置获取DELETE参数
|
||||
* @method mixed patch(string $name = '', mixed $default = null, mixed $filter = '') static 设置获取PATCH参数
|
||||
* @method mixed request(string $name = '', mixed $default = null, mixed $filter = '') static 获取request变量
|
||||
* @method mixed session(string $name = '', mixed $default = null, mixed $filter = '') static 获取session数据
|
||||
* @method mixed cookie(string $name = '', mixed $default = null, mixed $filter = '') static 获取cookie参数
|
||||
* @method mixed server(string $name = '', mixed $default = null, mixed $filter = '') static 获取server参数
|
||||
* @method mixed env(string $name = '', mixed $default = null, mixed $filter = '') static 获取环境变量
|
||||
* @method mixed file(string $name = '') static 获取上传的文件信息
|
||||
* @method mixed header(string $name = '', mixed $default = null) static 设置或者获取当前的Header
|
||||
* @method mixed input(array $data,mixed $name = '', mixed $default = null, mixed $filter = '') static 获取变量 支持过滤和默认值
|
||||
* @method mixed filter(mixed $filter = null) static 设置或获取当前的过滤规则
|
||||
* @method mixed has(string $name, string $type = 'param', bool $checkEmpty = false) static 是否存在某个请求参数
|
||||
* @method mixed only(mixed $name, string $type = 'param') static 获取指定的参数
|
||||
* @method mixed except(mixed $name, string $type = 'param') static 排除指定参数获取
|
||||
* @method bool isSsl() static 当前是否ssl
|
||||
* @method bool isAjax(bool $ajax = false) static 当前是否Ajax请求
|
||||
* @method bool isPjax(bool $pjax = false) static 当前是否Pjax请求
|
||||
* @method mixed ip(int $type = 0, bool $adv = true) static 获取客户端IP地址
|
||||
* @method bool isMobile() static 检测是否使用手机访问
|
||||
* @method string scheme() static 当前URL地址中的scheme参数
|
||||
* @method string query() static 当前请求URL地址中的query参数
|
||||
* @method string host(bool $stric = false) static 当前请求的host
|
||||
* @method string port() static 当前请求URL地址中的port参数
|
||||
* @method string protocol() static 当前请求 SERVER_PROTOCOL
|
||||
* @method string remotePort() static 当前请求 REMOTE_PORT
|
||||
* @method string contentType() static 当前请求 HTTP_CONTENT_TYPE
|
||||
* @method array routeInfo() static 获取当前请求的路由信息
|
||||
* @method array dispatch() static 获取当前请求的调度信息
|
||||
* @method string module() static 获取当前的模块名
|
||||
* @method string controller(bool $convert = false) static 获取当前的控制器名
|
||||
* @method string action(bool $convert = false) static 获取当前的操作名
|
||||
* @method string langset() static 获取当前的语言
|
||||
* @method string getContent() static 设置或者获取当前请求的content
|
||||
* @method string getInput() static 获取当前请求的php://input
|
||||
* @method string token(string $name = '__token__', mixed $type = 'md5') static 生成请求令牌
|
||||
* @method string cache(string $key, mixed $expire = null, array $except = [], string $tag = null) static 设置当前地址的请求缓存
|
||||
* @method string getCache() static 读取请求缓存设置
|
||||
*/
|
||||
class Request extends Facade
|
||||
{
|
||||
/**
|
||||
* 获取当前Facade对应类名(或者已经绑定的容器对象标识)
|
||||
* @access protected
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeClass()
|
||||
{
|
||||
return 'request';
|
||||
}
|
||||
}
|
||||
47
Server/thinkphp/library/think/facade/Response.php
Normal file
47
Server/thinkphp/library/think/facade/Response.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\facade;
|
||||
|
||||
use think\Facade;
|
||||
|
||||
/**
|
||||
* @see \think\Response
|
||||
* @mixin \think\Response
|
||||
* @method \think\response create(mixed $data = '', string $type = '', int $code = 200, array $header = [], array $options = []) static 创建Response对象
|
||||
* @method void send() static 发送数据到客户端
|
||||
* @method \think\Response options(mixed $options = []) static 输出的参数
|
||||
* @method \think\Response data(mixed $data) static 输出数据设置
|
||||
* @method \think\Response header(mixed $name, string $value = null) static 设置响应头
|
||||
* @method \think\Response content(mixed $content) static 设置页面输出内容
|
||||
* @method \think\Response code(int $code) static 发送HTTP状态
|
||||
* @method \think\Response lastModified(string $time) static LastModified
|
||||
* @method \think\Response expires(string $time) static expires
|
||||
* @method \think\Response eTag(string $eTag) static eTag
|
||||
* @method \think\Response cacheControl(string $cache) static 页面缓存控制
|
||||
* @method \think\Response contentType(string $contentType, string $charset = 'utf-8') static 页面输出类型
|
||||
* @method mixed getHeader(string $name) static 获取头部信息
|
||||
* @method mixed getData() static 获取原始数据
|
||||
* @method mixed getContent() static 获取输出数据
|
||||
* @method int getCode() static 获取状态码
|
||||
*/
|
||||
class Response extends Facade
|
||||
{
|
||||
/**
|
||||
* 获取当前Facade对应类名(或者已经绑定的容器对象标识)
|
||||
* @access protected
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeClass()
|
||||
{
|
||||
return 'response';
|
||||
}
|
||||
}
|
||||
57
Server/thinkphp/library/think/facade/Route.php
Normal file
57
Server/thinkphp/library/think/facade/Route.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\facade;
|
||||
|
||||
use think\Facade;
|
||||
|
||||
/**
|
||||
* @see \think\Route
|
||||
* @mixin \think\Route
|
||||
* @method \think\route\Domain domain(mixed $name, mixed $rule = '', array $option = [], array $pattern = []) static 注册域名路由
|
||||
* @method \think\Route pattern(mixed $name, string $rule = '') static 注册变量规则
|
||||
* @method \think\Route option(mixed $name, mixed $value = '') static 注册路由参数
|
||||
* @method \think\Route bind(string $bind) static 设置路由绑定
|
||||
* @method mixed getBind(string $bind) static 读取路由绑定
|
||||
* @method \think\Route name(string $name) static 设置当前路由标识
|
||||
* @method mixed getName(string $name) static 读取路由标识
|
||||
* @method void setName(string $name) static 批量导入路由标识
|
||||
* @method void import(array $rules, string $type = '*') static 导入配置文件的路由规则
|
||||
* @method \think\route\RuleItem rule(string $rule, mixed $route, string $method = '*', array $option = [], array $pattern = []) static 注册路由规则
|
||||
* @method void rules(array $rules, string $method = '*', array $option = [], array $pattern = []) static 批量注册路由规则
|
||||
* @method \think\route\RuleGroup group(string|array $name, array|\Closure $route, array $method = '*', array $option = [], array $pattern = []) static 注册路由分组
|
||||
* @method \think\route\RuleItem any(string $rule, mixed $route, array $option = [], array $pattern = []) static 注册路由
|
||||
* @method \think\route\RuleItem get(string $rule, mixed $route, array $option = [], array $pattern = []) static 注册路由
|
||||
* @method \think\route\RuleItem post(string $rule, mixed $route, array $option = [], array $pattern = []) static 注册路由
|
||||
* @method \think\route\RuleItem put(string $rule, mixed $route, array $option = [], array $pattern = []) static 注册路由
|
||||
* @method \think\route\RuleItem delete(string $rule, mixed $route, array $option = [], array $pattern = []) static 注册路由
|
||||
* @method \think\route\RuleItem patch(string $rule, mixed $route, array $option = [], array $pattern = []) static 注册路由
|
||||
* @method \think\route\Resource resource(string $rule, mixed $route, array $option = [], array $pattern = []) static 注册资源路由
|
||||
* @method \think\Route controller(string $rule, mixed $route, array $option = [], array $pattern = []) static 注册控制器路由
|
||||
* @method \think\Route alias(string $rule, mixed $route, array $option = [], array $pattern = []) static 注册别名路由
|
||||
* @method \think\Route setMethodPrefix(mixed $method, string $prefix = '') static 设置不同请求类型下面的方法前缀
|
||||
* @method \think\Route rest(string $name, array $resource = []) static rest方法定义和修改
|
||||
* @method \think\Route\RuleItem miss(string $route, string $method = '*', array $option = []) static 注册未匹配路由规则后的处理
|
||||
* @method \think\Route\RuleItem auto(string $route) static 注册一个自动解析的URL路由
|
||||
* @method \think\Route\Dispatch check(string $url, string $depr = '/', bool $must = false, bool $completeMatch = false) static 检测URL路由
|
||||
*/
|
||||
class Route extends Facade
|
||||
{
|
||||
/**
|
||||
* 获取当前Facade对应类名(或者已经绑定的容器对象标识)
|
||||
* @access protected
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeClass()
|
||||
{
|
||||
return 'route';
|
||||
}
|
||||
}
|
||||
46
Server/thinkphp/library/think/facade/Session.php
Normal file
46
Server/thinkphp/library/think/facade/Session.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\facade;
|
||||
|
||||
use think\Facade;
|
||||
|
||||
/**
|
||||
* @see \think\Session
|
||||
* @mixin \think\Session
|
||||
* @method void init(array $config = []) static session初始化
|
||||
* @method bool has(string $name,string $prefix = null) static 判断session数据
|
||||
* @method mixed prefix(string $prefix = '') static 设置或者获取session作用域(前缀)
|
||||
* @method mixed get(string $name = '',string $prefix = null) static session获取
|
||||
* @method mixed pull(string $name,string $prefix = null) static session获取并删除
|
||||
* @method void push(string $key, mixed $value) static 添加数据到一个session数组
|
||||
* @method void set(string $name, mixed $value , string $prefix = null) static 设置session数据
|
||||
* @method void flash(string $name, mixed $value = null) static session设置 下一次请求有效
|
||||
* @method void flush() static 清空当前请求的session数据
|
||||
* @method void delete(string $name, string $prefix = null) static 删除session数据
|
||||
* @method void clear($prefix = null) static 清空session数据
|
||||
* @method void start() static 启动session
|
||||
* @method void destroy() static 销毁session
|
||||
* @method void pause() static 暂停session
|
||||
* @method void regenerate(bool $delete = false) static 重新生成session_id
|
||||
*/
|
||||
class Session extends Facade
|
||||
{
|
||||
/**
|
||||
* 获取当前Facade对应类名(或者已经绑定的容器对象标识)
|
||||
* @access protected
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeClass()
|
||||
{
|
||||
return 'session';
|
||||
}
|
||||
}
|
||||
36
Server/thinkphp/library/think/facade/Template.php
Normal file
36
Server/thinkphp/library/think/facade/Template.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\facade;
|
||||
|
||||
use think\Facade;
|
||||
|
||||
/**
|
||||
* @see \think\Template
|
||||
* @mixin \think\Template
|
||||
* @method void assign(mixed $name, mixed $value = '') static 模板变量赋值
|
||||
* @method mixed get(string $name = '') static 获取模板变量
|
||||
* @method void fetch(string $template, array $vars = [], array $config = []) static 渲染模板文件
|
||||
* @method void display(string $content, array $vars = [], array $config = []) static 渲染模板内容
|
||||
* @method mixed layout(string $name, string $replace = '') static 设置模板布局
|
||||
*/
|
||||
class Template extends Facade
|
||||
{
|
||||
/**
|
||||
* 获取当前Facade对应类名(或者已经绑定的容器对象标识)
|
||||
* @access protected
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeClass()
|
||||
{
|
||||
return 'template';
|
||||
}
|
||||
}
|
||||
33
Server/thinkphp/library/think/facade/Url.php
Normal file
33
Server/thinkphp/library/think/facade/Url.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\facade;
|
||||
|
||||
use think\Facade;
|
||||
|
||||
/**
|
||||
* @see \think\Url
|
||||
* @mixin \think\Url
|
||||
* @method string build(string $url = '', mixed $vars = '', mixed $suffix = true, mixed $domain = false) static URL生成 支持路由反射
|
||||
* @method void root(string $root) static 指定当前生成URL地址的root
|
||||
*/
|
||||
class Url extends Facade
|
||||
{
|
||||
/**
|
||||
* 获取当前Facade对应类名(或者已经绑定的容器对象标识)
|
||||
* @access protected
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeClass()
|
||||
{
|
||||
return 'url';
|
||||
}
|
||||
}
|
||||
75
Server/thinkphp/library/think/facade/Validate.php
Normal file
75
Server/thinkphp/library/think/facade/Validate.php
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\facade;
|
||||
|
||||
use think\Facade;
|
||||
|
||||
/**
|
||||
* @see \think\Validate
|
||||
* @mixin \think\Validate
|
||||
* @method \think\Validate make(array $rules = [], array $message = [], array $field = []) static 创建一个验证器类
|
||||
* @method \think\Validate rule(mixed $name, mixed $rule = '') static 添加字段验证规则
|
||||
* @method void extend(string $type, mixed $callback = null) static 注册扩展验证(类型)规则
|
||||
* @method void setTypeMsg(mixed $type, string $msg = null) static 设置验证规则的默认提示信息
|
||||
* @method \think\Validate message(mixed $name, string $message = '') static 设置提示信息
|
||||
* @method \think\Validate scene(string $name) static 设置验证场景
|
||||
* @method bool hasScene(string $name) static 判断是否存在某个验证场景
|
||||
* @method \think\Validate batch(bool $batch = true) static 设置批量验证
|
||||
* @method \think\Validate only(array $fields) static 指定需要验证的字段列表
|
||||
* @method \think\Validate remove(mixed $field, mixed $rule = true) static 移除某个字段的验证规则
|
||||
* @method \think\Validate append(mixed $field, mixed $rule = null) static 追加某个字段的验证规则
|
||||
* @method bool confirm(mixed $value, mixed $rule, array $data = [], string $field = '') static 验证是否和某个字段的值一致
|
||||
* @method bool different(mixed $value, mixed $rule, array $data = []) static 验证是否和某个字段的值是否不同
|
||||
* @method bool egt(mixed $value, mixed $rule, array $data = []) static 验证是否大于等于某个值
|
||||
* @method bool gt(mixed $value, mixed $rule, array $data = []) static 验证是否大于某个值
|
||||
* @method bool elt(mixed $value, mixed $rule, array $data = []) static 验证是否小于等于某个值
|
||||
* @method bool lt(mixed $value, mixed $rule, array $data = []) static 验证是否小于某个值
|
||||
* @method bool eq(mixed $value, mixed $rule) static 验证是否等于某个值
|
||||
* @method bool must(mixed $value, mixed $rule) static 必须验证
|
||||
* @method bool is(mixed $value, mixed $rule, array $data = []) static 验证字段值是否为有效格式
|
||||
* @method bool ip(mixed $value, mixed $rule) static 验证是否有效IP
|
||||
* @method bool requireIf(mixed $value, mixed $rule) static 验证某个字段等于某个值的时候必须
|
||||
* @method bool requireCallback(mixed $value, mixed $rule,array $data) static 通过回调方法验证某个字段是否必须
|
||||
* @method bool requireWith(mixed $value, mixed $rule, array $data) static 验证某个字段有值的情况下必须
|
||||
* @method bool filter(mixed $value, mixed $rule) static 使用filter_var方式验证
|
||||
* @method bool in(mixed $value, mixed $rule) static 验证是否在范围内
|
||||
* @method bool notIn(mixed $value, mixed $rule) static 验证是否不在范围内
|
||||
* @method bool between(mixed $value, mixed $rule) static between验证数据
|
||||
* @method bool notBetween(mixed $value, mixed $rule) static 使用notbetween验证数据
|
||||
* @method bool length(mixed $value, mixed $rule) static 验证数据长度
|
||||
* @method bool max(mixed $value, mixed $rule) static 验证数据最大长度
|
||||
* @method bool min(mixed $value, mixed $rule) static 验证数据最小长度
|
||||
* @method bool after(mixed $value, mixed $rule) static 验证日期
|
||||
* @method bool before(mixed $value, mixed $rule) static 验证日期
|
||||
* @method bool expire(mixed $value, mixed $rule) static 验证有效期
|
||||
* @method bool allowIp(mixed $value, mixed $rule) static 验证IP许可
|
||||
* @method bool denyIp(mixed $value, mixed $rule) static 验证IP禁用
|
||||
* @method bool regex(mixed $value, mixed $rule) static 使用正则验证数据
|
||||
* @method bool token(mixed $value, mixed $rule) static 验证表单令牌
|
||||
* @method bool dateFormat(mixed $value, mixed $rule) static 验证时间和日期是否符合指定格式
|
||||
* @method bool unique(mixed $value, mixed $rule, array $data = [], string $field = '') static 验证是否唯一
|
||||
* @method bool check(array $data, mixed $rules = [], string $scene = '') static 数据自动验证
|
||||
* @method mixed getError(mixed $value, mixed $rule) static 获取错误信息
|
||||
*/
|
||||
class Validate extends Facade
|
||||
{
|
||||
/**
|
||||
* 获取当前Facade对应类名(或者已经绑定的容器对象标识)
|
||||
* @access protected
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeClass()
|
||||
{
|
||||
return 'validate';
|
||||
}
|
||||
|
||||
}
|
||||
40
Server/thinkphp/library/think/facade/View.php
Normal file
40
Server/thinkphp/library/think/facade/View.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\facade;
|
||||
|
||||
use think\Facade;
|
||||
|
||||
/**
|
||||
* @see \think\View
|
||||
* @mixin \think\View
|
||||
* @method \think\View init(mixed $engine = [], array $replace = []) static 初始化
|
||||
* @method \think\View share(mixed $name, mixed $value = '') static 模板变量静态赋值
|
||||
* @method \think\View assign(mixed $name, mixed $value = '') static 模板变量赋值
|
||||
* @method \think\View config(mixed $name, mixed $value = '') static 配置模板引擎
|
||||
* @method \think\View exists(mixed $name) static 检查模板是否存在
|
||||
* @method \think\View filter(Callable $filter) static 视图内容过滤
|
||||
* @method \think\View engine(mixed $engine = []) static 设置当前模板解析的引擎
|
||||
* @method string fetch(string $template = '', array $vars = [], array $config = [], bool $renderContent = false) static 解析和获取模板内容
|
||||
* @method string display(string $content = '', array $vars = [], array $config = []) static 渲染内容输出
|
||||
*/
|
||||
class View extends Facade
|
||||
{
|
||||
/**
|
||||
* 获取当前Facade对应类名(或者已经绑定的容器对象标识)
|
||||
* @access protected
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeClass()
|
||||
{
|
||||
return 'view';
|
||||
}
|
||||
}
|
||||
656
Server/thinkphp/library/think/model/concern/Attribute.php
Normal file
656
Server/thinkphp/library/think/model/concern/Attribute.php
Normal file
@@ -0,0 +1,656 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\model\concern;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use think\db\Expression;
|
||||
use think\Exception;
|
||||
use think\Loader;
|
||||
use think\model\Relation;
|
||||
|
||||
trait Attribute
|
||||
{
|
||||
/**
|
||||
* 数据表主键 复合主键使用数组定义
|
||||
* @var string|array
|
||||
*/
|
||||
protected $pk = 'id';
|
||||
|
||||
/**
|
||||
* 数据表字段信息 留空则自动获取
|
||||
* @var array
|
||||
*/
|
||||
protected $field = [];
|
||||
|
||||
/**
|
||||
* JSON数据表字段
|
||||
* @var array
|
||||
*/
|
||||
protected $json = [];
|
||||
|
||||
/**
|
||||
* JSON数据取出是否需要转换为数组
|
||||
* @var bool
|
||||
*/
|
||||
protected $jsonAssoc = false;
|
||||
|
||||
/**
|
||||
* JSON数据表字段类型
|
||||
* @var array
|
||||
*/
|
||||
protected $jsonType = [];
|
||||
|
||||
/**
|
||||
* 数据表废弃字段
|
||||
* @var array
|
||||
*/
|
||||
protected $disuse = [];
|
||||
|
||||
/**
|
||||
* 数据表只读字段
|
||||
* @var array
|
||||
*/
|
||||
protected $readonly = [];
|
||||
|
||||
/**
|
||||
* 数据表字段类型
|
||||
* @var array
|
||||
*/
|
||||
protected $type = [];
|
||||
|
||||
/**
|
||||
* 当前模型数据
|
||||
* @var array
|
||||
*/
|
||||
private $data = [];
|
||||
|
||||
/**
|
||||
* 修改器执行记录
|
||||
* @var array
|
||||
*/
|
||||
private $set = [];
|
||||
|
||||
/**
|
||||
* 原始数据
|
||||
* @var array
|
||||
*/
|
||||
private $origin = [];
|
||||
|
||||
/**
|
||||
* 动态获取器
|
||||
* @var array
|
||||
*/
|
||||
private $withAttr = [];
|
||||
|
||||
/**
|
||||
* 获取模型对象的主键
|
||||
* @access public
|
||||
* @return string|array
|
||||
*/
|
||||
public function getPk()
|
||||
{
|
||||
return $this->pk;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断一个字段名是否为主键字段
|
||||
* @access public
|
||||
* @param string $key 名称
|
||||
* @return bool
|
||||
*/
|
||||
protected function isPk($key)
|
||||
{
|
||||
$pk = $this->getPk();
|
||||
if (is_string($pk) && $pk == $key) {
|
||||
return true;
|
||||
} elseif (is_array($pk) && in_array($key, $pk)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取模型对象的主键值
|
||||
* @access public
|
||||
* @return integer
|
||||
*/
|
||||
public function getKey()
|
||||
{
|
||||
$pk = $this->getPk();
|
||||
if (is_string($pk) && array_key_exists($pk, $this->data)) {
|
||||
return $this->data[$pk];
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置允许写入的字段
|
||||
* @access public
|
||||
* @param array|string|true $field 允许写入的字段 如果为true只允许写入数据表字段
|
||||
* @return $this
|
||||
*/
|
||||
public function allowField($field)
|
||||
{
|
||||
if (is_string($field)) {
|
||||
$field = explode(',', $field);
|
||||
}
|
||||
|
||||
$this->field = $field;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置只读字段
|
||||
* @access public
|
||||
* @param array|string $field 只读字段
|
||||
* @return $this
|
||||
*/
|
||||
public function readonly($field)
|
||||
{
|
||||
if (is_string($field)) {
|
||||
$field = explode(',', $field);
|
||||
}
|
||||
|
||||
$this->readonly = $field;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置数据对象值
|
||||
* @access public
|
||||
* @param mixed $data 数据或者属性名
|
||||
* @param mixed $value 值
|
||||
* @return $this
|
||||
*/
|
||||
public function data($data, $value = null)
|
||||
{
|
||||
if (is_string($data)) {
|
||||
$this->data[$data] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
// 清空数据
|
||||
$this->data = [];
|
||||
|
||||
if (is_object($data)) {
|
||||
$data = get_object_vars($data);
|
||||
}
|
||||
|
||||
if ($this->disuse) {
|
||||
// 废弃字段
|
||||
foreach ((array) $this->disuse as $key) {
|
||||
if (array_key_exists($key, $data)) {
|
||||
unset($data[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (true === $value) {
|
||||
// 数据对象赋值
|
||||
foreach ($data as $key => $value) {
|
||||
$this->setAttr($key, $value, $data);
|
||||
}
|
||||
} elseif (is_array($value)) {
|
||||
foreach ($value as $name) {
|
||||
if (isset($data[$name])) {
|
||||
$this->data[$name] = $data[$name];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量设置数据对象值
|
||||
* @access public
|
||||
* @param mixed $data 数据
|
||||
* @param bool $set 是否需要进行数据处理
|
||||
* @return $this
|
||||
*/
|
||||
public function appendData($data, $set = false)
|
||||
{
|
||||
if ($set) {
|
||||
// 进行数据处理
|
||||
foreach ($data as $key => $value) {
|
||||
$this->setAttr($key, $value, $data);
|
||||
}
|
||||
} else {
|
||||
if (is_object($data)) {
|
||||
$data = get_object_vars($data);
|
||||
}
|
||||
|
||||
$this->data = array_merge($this->data, $data);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取对象原始数据 如果不存在指定字段返回null
|
||||
* @access public
|
||||
* @param string $name 字段名 留空获取全部
|
||||
* @return mixed
|
||||
*/
|
||||
public function getOrigin($name = null)
|
||||
{
|
||||
if (is_null($name)) {
|
||||
return $this->origin;
|
||||
}
|
||||
return array_key_exists($name, $this->origin) ? $this->origin[$name] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取对象原始数据 如果不存在指定字段返回false
|
||||
* @access public
|
||||
* @param string $name 字段名 留空获取全部
|
||||
* @return mixed
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function getData($name = null)
|
||||
{
|
||||
if (is_null($name)) {
|
||||
return $this->data;
|
||||
} elseif (array_key_exists($name, $this->data)) {
|
||||
return $this->data[$name];
|
||||
} elseif (array_key_exists($name, $this->relation)) {
|
||||
return $this->relation[$name];
|
||||
}
|
||||
throw new InvalidArgumentException('property not exists:' . static::class . '->' . $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取变化的数据 并排除只读数据
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getChangedData()
|
||||
{
|
||||
if ($this->force) {
|
||||
$data = $this->data;
|
||||
} else {
|
||||
$data = array_udiff_assoc($this->data, $this->origin, function ($a, $b) {
|
||||
if ((empty($a) || empty($b)) && $a !== $b) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return is_object($a) || $a != $b ? 1 : 0;
|
||||
});
|
||||
}
|
||||
|
||||
if (!empty($this->readonly)) {
|
||||
// 只读字段不允许更新
|
||||
foreach ($this->readonly as $key => $field) {
|
||||
if (isset($data[$field])) {
|
||||
unset($data[$field]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改器 设置数据对象值
|
||||
* @access public
|
||||
* @param string $name 属性名
|
||||
* @param mixed $value 属性值
|
||||
* @param array $data 数据
|
||||
* @return void
|
||||
*/
|
||||
public function setAttr($name, $value, $data = [])
|
||||
{
|
||||
if (isset($this->set[$name])) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_null($value) && $this->autoWriteTimestamp && in_array($name, [$this->createTime, $this->updateTime])) {
|
||||
// 自动写入的时间戳字段
|
||||
$value = $this->autoWriteTimestamp($name);
|
||||
} else {
|
||||
// 检测修改器
|
||||
$method = 'set' . Loader::parseName($name, 1) . 'Attr';
|
||||
|
||||
if (method_exists($this, $method)) {
|
||||
$origin = $this->data;
|
||||
$value = $this->$method($value, array_merge($this->data, $data));
|
||||
|
||||
$this->set[$name] = true;
|
||||
if (is_null($value) && $origin !== $this->data) {
|
||||
return;
|
||||
}
|
||||
} elseif (isset($this->type[$name])) {
|
||||
// 类型转换
|
||||
$value = $this->writeTransform($value, $this->type[$name]);
|
||||
}
|
||||
}
|
||||
|
||||
// 设置数据对象属性
|
||||
$this->data[$name] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否需要自动写入时间字段
|
||||
* @access public
|
||||
* @param bool $auto
|
||||
* @return $this
|
||||
*/
|
||||
public function isAutoWriteTimestamp($auto)
|
||||
{
|
||||
$this->autoWriteTimestamp = $auto;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动写入时间戳
|
||||
* @access protected
|
||||
* @param string $name 时间戳字段
|
||||
* @return mixed
|
||||
*/
|
||||
protected function autoWriteTimestamp($name)
|
||||
{
|
||||
if (isset($this->type[$name])) {
|
||||
$type = $this->type[$name];
|
||||
|
||||
if (strpos($type, ':')) {
|
||||
list($type, $param) = explode(':', $type, 2);
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
case 'datetime':
|
||||
case 'date':
|
||||
$value = $this->formatDateTime('Y-m-d H:i:s.u');
|
||||
break;
|
||||
case 'timestamp':
|
||||
case 'integer':
|
||||
default:
|
||||
$value = time();
|
||||
break;
|
||||
}
|
||||
} elseif (is_string($this->autoWriteTimestamp) && in_array(strtolower($this->autoWriteTimestamp), [
|
||||
'datetime',
|
||||
'date',
|
||||
'timestamp',
|
||||
])) {
|
||||
$value = $this->formatDateTime('Y-m-d H:i:s.u');
|
||||
} else {
|
||||
$value = time();
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据写入 类型转换
|
||||
* @access protected
|
||||
* @param mixed $value 值
|
||||
* @param string|array $type 要转换的类型
|
||||
* @return mixed
|
||||
*/
|
||||
protected function writeTransform($value, $type)
|
||||
{
|
||||
if (is_null($value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($value instanceof Expression) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
if (is_array($type)) {
|
||||
list($type, $param) = $type;
|
||||
} elseif (strpos($type, ':')) {
|
||||
list($type, $param) = explode(':', $type, 2);
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
case 'integer':
|
||||
$value = (int) $value;
|
||||
break;
|
||||
case 'float':
|
||||
if (empty($param)) {
|
||||
$value = (float) $value;
|
||||
} else {
|
||||
$value = (float) number_format($value, $param, '.', '');
|
||||
}
|
||||
break;
|
||||
case 'boolean':
|
||||
$value = (bool) $value;
|
||||
break;
|
||||
case 'timestamp':
|
||||
if (!is_numeric($value)) {
|
||||
$value = strtotime($value);
|
||||
}
|
||||
break;
|
||||
case 'datetime':
|
||||
$value = is_numeric($value) ? $value : strtotime($value);
|
||||
$value = $this->formatDateTime('Y-m-d H:i:s.u', $value);
|
||||
break;
|
||||
case 'object':
|
||||
if (is_object($value)) {
|
||||
$value = json_encode($value, JSON_FORCE_OBJECT);
|
||||
}
|
||||
break;
|
||||
case 'array':
|
||||
$value = (array) $value;
|
||||
case 'json':
|
||||
$option = !empty($param) ? (int) $param : JSON_UNESCAPED_UNICODE;
|
||||
$value = json_encode($value, $option);
|
||||
break;
|
||||
case 'serialize':
|
||||
$value = serialize($value);
|
||||
break;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取器 获取数据对象的值
|
||||
* @access public
|
||||
* @param string $name 名称
|
||||
* @param array $item 数据
|
||||
* @return mixed
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function getAttr($name, &$item = null)
|
||||
{
|
||||
try {
|
||||
$notFound = false;
|
||||
$value = $this->getData($name);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
$notFound = true;
|
||||
$value = null;
|
||||
}
|
||||
|
||||
// 检测属性获取器
|
||||
$fieldName = Loader::parseName($name);
|
||||
$method = 'get' . Loader::parseName($name, 1) . 'Attr';
|
||||
|
||||
if (isset($this->withAttr[$fieldName])) {
|
||||
if ($notFound && $relation = $this->isRelationAttr($name)) {
|
||||
$modelRelation = $this->$relation();
|
||||
$value = $this->getRelationData($modelRelation);
|
||||
}
|
||||
|
||||
$closure = $this->withAttr[$fieldName];
|
||||
$value = $closure($value, $this->data);
|
||||
} elseif (method_exists($this, $method)) {
|
||||
if ($notFound && $relation = $this->isRelationAttr($name)) {
|
||||
$modelRelation = $this->$relation();
|
||||
$value = $this->getRelationData($modelRelation);
|
||||
}
|
||||
|
||||
$value = $this->$method($value, $this->data);
|
||||
} elseif (isset($this->type[$name])) {
|
||||
// 类型转换
|
||||
$value = $this->readTransform($value, $this->type[$name]);
|
||||
} elseif ($this->autoWriteTimestamp && in_array($name, [$this->createTime, $this->updateTime])) {
|
||||
if (is_string($this->autoWriteTimestamp) && in_array(strtolower($this->autoWriteTimestamp), [
|
||||
'datetime',
|
||||
'date',
|
||||
'timestamp',
|
||||
])) {
|
||||
$value = $this->formatDateTime($this->dateFormat, $value);
|
||||
} else {
|
||||
$value = $this->formatDateTime($this->dateFormat, $value, true);
|
||||
}
|
||||
} elseif ($notFound) {
|
||||
$value = $this->getRelationAttribute($name, $item);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取关联属性值
|
||||
* @access protected
|
||||
* @param string $name 属性名
|
||||
* @param array $item 数据
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getRelationAttribute($name, &$item)
|
||||
{
|
||||
$relation = $this->isRelationAttr($name);
|
||||
|
||||
if ($relation) {
|
||||
$modelRelation = $this->$relation();
|
||||
if ($modelRelation instanceof Relation) {
|
||||
$value = $this->getRelationData($modelRelation);
|
||||
|
||||
if ($item && method_exists($modelRelation, 'getBindAttr') && $bindAttr = $modelRelation->getBindAttr()) {
|
||||
|
||||
foreach ($bindAttr as $key => $attr) {
|
||||
$key = is_numeric($key) ? $attr : $key;
|
||||
|
||||
if (isset($item[$key])) {
|
||||
throw new Exception('bind attr has exists:' . $key);
|
||||
} else {
|
||||
$item[$key] = $value ? $value->getAttr($attr) : null;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// 保存关联对象值
|
||||
$this->relation[$name] = $value;
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException('property not exists:' . static::class . '->' . $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据读取 类型转换
|
||||
* @access protected
|
||||
* @param mixed $value 值
|
||||
* @param string|array $type 要转换的类型
|
||||
* @return mixed
|
||||
*/
|
||||
protected function readTransform($value, $type)
|
||||
{
|
||||
if (is_null($value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_array($type)) {
|
||||
list($type, $param) = $type;
|
||||
} elseif (strpos($type, ':')) {
|
||||
list($type, $param) = explode(':', $type, 2);
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
case 'integer':
|
||||
$value = (int) $value;
|
||||
break;
|
||||
case 'float':
|
||||
if (empty($param)) {
|
||||
$value = (float) $value;
|
||||
} else {
|
||||
$value = (float) number_format($value, $param, '.', '');
|
||||
}
|
||||
break;
|
||||
case 'boolean':
|
||||
$value = (bool) $value;
|
||||
break;
|
||||
case 'timestamp':
|
||||
if (!is_null($value)) {
|
||||
$format = !empty($param) ? $param : $this->dateFormat;
|
||||
$value = $this->formatDateTime($format, $value, true);
|
||||
}
|
||||
break;
|
||||
case 'datetime':
|
||||
if (!is_null($value)) {
|
||||
$format = !empty($param) ? $param : $this->dateFormat;
|
||||
$value = $this->formatDateTime($format, $value);
|
||||
}
|
||||
break;
|
||||
case 'json':
|
||||
$value = json_decode($value, true);
|
||||
break;
|
||||
case 'array':
|
||||
$value = empty($value) ? [] : json_decode($value, true);
|
||||
break;
|
||||
case 'object':
|
||||
$value = empty($value) ? new \stdClass() : json_decode($value);
|
||||
break;
|
||||
case 'serialize':
|
||||
try {
|
||||
$value = unserialize($value);
|
||||
} catch (\Exception $e) {
|
||||
$value = null;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (false !== strpos($type, '\\')) {
|
||||
// 对象类型
|
||||
$value = new $type($value);
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置数据字段获取器
|
||||
* @access public
|
||||
* @param string|array $name 字段名
|
||||
* @param callable $callback 闭包获取器
|
||||
* @return $this
|
||||
*/
|
||||
public function withAttribute($name, $callback = null)
|
||||
{
|
||||
if (is_array($name)) {
|
||||
foreach ($name as $key => $val) {
|
||||
$key = Loader::parseName($key);
|
||||
|
||||
$this->withAttr[$key] = $val;
|
||||
}
|
||||
} else {
|
||||
$name = Loader::parseName($name);
|
||||
|
||||
$this->withAttr[$name] = $callback;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
273
Server/thinkphp/library/think/model/concern/Conversion.php
Normal file
273
Server/thinkphp/library/think/model/concern/Conversion.php
Normal file
@@ -0,0 +1,273 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\model\concern;
|
||||
|
||||
use think\Collection;
|
||||
use think\Exception;
|
||||
use think\Loader;
|
||||
use think\Model;
|
||||
use think\model\Collection as ModelCollection;
|
||||
|
||||
/**
|
||||
* 模型数据转换处理
|
||||
*/
|
||||
trait Conversion
|
||||
{
|
||||
/**
|
||||
* 数据输出显示的属性
|
||||
* @var array
|
||||
*/
|
||||
protected $visible = [];
|
||||
|
||||
/**
|
||||
* 数据输出隐藏的属性
|
||||
* @var array
|
||||
*/
|
||||
protected $hidden = [];
|
||||
|
||||
/**
|
||||
* 数据输出需要追加的属性
|
||||
* @var array
|
||||
*/
|
||||
protected $append = [];
|
||||
|
||||
/**
|
||||
* 数据集对象名
|
||||
* @var string
|
||||
*/
|
||||
protected $resultSetType;
|
||||
|
||||
/**
|
||||
* 设置需要附加的输出属性
|
||||
* @access public
|
||||
* @param array $append 属性列表
|
||||
* @param bool $override 是否覆盖
|
||||
* @return $this
|
||||
*/
|
||||
public function append(array $append = [], $override = false)
|
||||
{
|
||||
$this->append = $override ? $append : array_merge($this->append, $append);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置附加关联对象的属性
|
||||
* @access public
|
||||
* @param string $attr 关联属性
|
||||
* @param string|array $append 追加属性名
|
||||
* @return $this
|
||||
* @throws Exception
|
||||
*/
|
||||
public function appendRelationAttr($attr, $append)
|
||||
{
|
||||
if (is_string($append)) {
|
||||
$append = explode(',', $append);
|
||||
}
|
||||
|
||||
$relation = Loader::parseName($attr, 1, false);
|
||||
if (isset($this->relation[$relation])) {
|
||||
$model = $this->relation[$relation];
|
||||
} else {
|
||||
$model = $this->getRelationData($this->$relation());
|
||||
}
|
||||
|
||||
if ($model instanceof Model) {
|
||||
foreach ($append as $key => $attr) {
|
||||
$key = is_numeric($key) ? $attr : $key;
|
||||
if (isset($this->data[$key])) {
|
||||
throw new Exception('bind attr has exists:' . $key);
|
||||
} else {
|
||||
$this->data[$key] = $model->getAttr($attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置需要隐藏的输出属性
|
||||
* @access public
|
||||
* @param array $hidden 属性列表
|
||||
* @param bool $override 是否覆盖
|
||||
* @return $this
|
||||
*/
|
||||
public function hidden(array $hidden = [], $override = false)
|
||||
{
|
||||
$this->hidden = $override ? $hidden : array_merge($this->hidden, $hidden);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置需要输出的属性
|
||||
* @access public
|
||||
* @param array $visible
|
||||
* @param bool $override 是否覆盖
|
||||
* @return $this
|
||||
*/
|
||||
public function visible(array $visible = [], $override = false)
|
||||
{
|
||||
$this->visible = $override ? $visible : array_merge($this->visible, $visible);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换当前模型对象为数组
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
$item = [];
|
||||
$hasVisible = false;
|
||||
|
||||
foreach ($this->visible as $key => $val) {
|
||||
if (is_string($val)) {
|
||||
if (strpos($val, '.')) {
|
||||
list($relation, $name) = explode('.', $val);
|
||||
$this->visible[$relation][] = $name;
|
||||
} else {
|
||||
$this->visible[$val] = true;
|
||||
$hasVisible = true;
|
||||
}
|
||||
unset($this->visible[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->hidden as $key => $val) {
|
||||
if (is_string($val)) {
|
||||
if (strpos($val, '.')) {
|
||||
list($relation, $name) = explode('.', $val);
|
||||
$this->hidden[$relation][] = $name;
|
||||
} else {
|
||||
$this->hidden[$val] = true;
|
||||
}
|
||||
unset($this->hidden[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
// 合并关联数据
|
||||
$data = array_merge($this->data, $this->relation);
|
||||
|
||||
foreach ($data as $key => $val) {
|
||||
if ($val instanceof Model || $val instanceof ModelCollection) {
|
||||
// 关联模型对象
|
||||
if (isset($this->visible[$key]) && is_array($this->visible[$key])) {
|
||||
$val->visible($this->visible[$key]);
|
||||
} elseif (isset($this->hidden[$key]) && is_array($this->hidden[$key])) {
|
||||
$val->hidden($this->hidden[$key]);
|
||||
}
|
||||
// 关联模型对象
|
||||
if (!isset($this->hidden[$key]) || true !== $this->hidden[$key]) {
|
||||
$item[$key] = $val->toArray();
|
||||
}
|
||||
} elseif (isset($this->visible[$key])) {
|
||||
$item[$key] = $this->getAttr($key);
|
||||
} elseif (!isset($this->hidden[$key]) && !$hasVisible) {
|
||||
$item[$key] = $this->getAttr($key);
|
||||
}
|
||||
}
|
||||
|
||||
// 追加属性(必须定义获取器)
|
||||
if (!empty($this->append)) {
|
||||
foreach ($this->append as $key => $name) {
|
||||
if (is_array($name)) {
|
||||
// 追加关联对象属性
|
||||
$relation = $this->getRelation($key);
|
||||
|
||||
if (!$relation) {
|
||||
$relation = $this->getAttr($key);
|
||||
if ($relation) {
|
||||
$relation->visible($name);
|
||||
}
|
||||
}
|
||||
|
||||
$item[$key] = $relation ? $relation->append($name)->toArray() : [];
|
||||
} elseif (strpos($name, '.')) {
|
||||
list($key, $attr) = explode('.', $name);
|
||||
// 追加关联对象属性
|
||||
$relation = $this->getRelation($key);
|
||||
|
||||
if (!$relation) {
|
||||
$relation = $this->getAttr($key);
|
||||
if ($relation) {
|
||||
$relation->visible([$attr]);
|
||||
}
|
||||
}
|
||||
|
||||
$item[$key] = $relation ? $relation->append([$attr])->toArray() : [];
|
||||
} else {
|
||||
$item[$name] = $this->getAttr($name, $item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换当前模型对象为JSON字符串
|
||||
* @access public
|
||||
* @param integer $options json参数
|
||||
* @return string
|
||||
*/
|
||||
public function toJson($options = JSON_UNESCAPED_UNICODE)
|
||||
{
|
||||
return json_encode($this->toArray(), $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除当前模型的关联属性
|
||||
* @access public
|
||||
* @return $this
|
||||
*/
|
||||
public function removeRelation()
|
||||
{
|
||||
$this->relation = [];
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->toJson();
|
||||
}
|
||||
|
||||
// JsonSerializable
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return $this->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换数据集为数据集对象
|
||||
* @access public
|
||||
* @param array|Collection $collection 数据集
|
||||
* @param string $resultSetType 数据集类
|
||||
* @return Collection
|
||||
*/
|
||||
public function toCollection($collection, $resultSetType = null)
|
||||
{
|
||||
$resultSetType = $resultSetType ?: $this->resultSetType;
|
||||
|
||||
if ($resultSetType && false !== strpos($resultSetType, '\\')) {
|
||||
$collection = new $resultSetType($collection);
|
||||
} else {
|
||||
$collection = new ModelCollection($collection);
|
||||
}
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
}
|
||||
238
Server/thinkphp/library/think/model/concern/ModelEvent.php
Normal file
238
Server/thinkphp/library/think/model/concern/ModelEvent.php
Normal file
@@ -0,0 +1,238 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\model\concern;
|
||||
|
||||
use think\Container;
|
||||
use think\Loader;
|
||||
|
||||
/**
|
||||
* 模型事件处理
|
||||
*/
|
||||
trait ModelEvent
|
||||
{
|
||||
/**
|
||||
* 模型回调
|
||||
* @var array
|
||||
*/
|
||||
private static $event = [];
|
||||
|
||||
/**
|
||||
* 模型事件观察
|
||||
* @var array
|
||||
*/
|
||||
protected static $observe = ['before_write', 'after_write', 'before_insert', 'after_insert', 'before_update', 'after_update', 'before_delete', 'after_delete', 'before_restore', 'after_restore'];
|
||||
|
||||
/**
|
||||
* 绑定模型事件观察者类
|
||||
* @var array
|
||||
*/
|
||||
protected $observerClass;
|
||||
|
||||
/**
|
||||
* 是否需要事件响应
|
||||
* @var bool
|
||||
*/
|
||||
private $withEvent = true;
|
||||
|
||||
/**
|
||||
* 注册回调方法
|
||||
* @access public
|
||||
* @param string $event 事件名
|
||||
* @param callable $callback 回调方法
|
||||
* @param bool $override 是否覆盖
|
||||
* @return void
|
||||
*/
|
||||
public static function event($event, $callback, $override = false)
|
||||
{
|
||||
$class = static::class;
|
||||
|
||||
if ($override) {
|
||||
self::$event[$class][$event] = [];
|
||||
}
|
||||
|
||||
self::$event[$class][$event][] = $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除回调方法
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public static function flushEvent()
|
||||
{
|
||||
self::$event[static::class] = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册一个模型观察者
|
||||
*
|
||||
* @param object|string $class
|
||||
* @return void
|
||||
*/
|
||||
public static function observe($class)
|
||||
{
|
||||
self::flushEvent();
|
||||
|
||||
foreach (static::$observe as $event) {
|
||||
$eventFuncName = Loader::parseName($event, 1, false);
|
||||
|
||||
if (method_exists($class, $eventFuncName)) {
|
||||
static::event($event, [$class, $eventFuncName]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前操作的事件响应
|
||||
* @access protected
|
||||
* @param bool $event 是否需要事件响应
|
||||
* @return $this
|
||||
*/
|
||||
public function withEvent($event)
|
||||
{
|
||||
$this->withEvent = $event;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 触发事件
|
||||
* @access protected
|
||||
* @param string $event 事件名
|
||||
* @return bool
|
||||
*/
|
||||
protected function trigger($event)
|
||||
{
|
||||
$class = static::class;
|
||||
|
||||
if ($this->withEvent && isset(self::$event[$class][$event])) {
|
||||
foreach (self::$event[$class][$event] as $callback) {
|
||||
$result = Container::getInstance()->invoke($callback, [$this]);
|
||||
|
||||
if (false === $result) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 模型before_insert事件快捷方法
|
||||
* @access protected
|
||||
* @param callable $callback
|
||||
* @param bool $override
|
||||
*/
|
||||
protected static function beforeInsert($callback, $override = false)
|
||||
{
|
||||
self::event('before_insert', $callback, $override);
|
||||
}
|
||||
|
||||
/**
|
||||
* 模型after_insert事件快捷方法
|
||||
* @access protected
|
||||
* @param callable $callback
|
||||
* @param bool $override
|
||||
*/
|
||||
protected static function afterInsert($callback, $override = false)
|
||||
{
|
||||
self::event('after_insert', $callback, $override);
|
||||
}
|
||||
|
||||
/**
|
||||
* 模型before_update事件快捷方法
|
||||
* @access protected
|
||||
* @param callable $callback
|
||||
* @param bool $override
|
||||
*/
|
||||
protected static function beforeUpdate($callback, $override = false)
|
||||
{
|
||||
self::event('before_update', $callback, $override);
|
||||
}
|
||||
|
||||
/**
|
||||
* 模型after_update事件快捷方法
|
||||
* @access protected
|
||||
* @param callable $callback
|
||||
* @param bool $override
|
||||
*/
|
||||
protected static function afterUpdate($callback, $override = false)
|
||||
{
|
||||
self::event('after_update', $callback, $override);
|
||||
}
|
||||
|
||||
/**
|
||||
* 模型before_write事件快捷方法
|
||||
* @access protected
|
||||
* @param callable $callback
|
||||
* @param bool $override
|
||||
*/
|
||||
protected static function beforeWrite($callback, $override = false)
|
||||
{
|
||||
self::event('before_write', $callback, $override);
|
||||
}
|
||||
|
||||
/**
|
||||
* 模型after_write事件快捷方法
|
||||
* @access protected
|
||||
* @param callable $callback
|
||||
* @param bool $override
|
||||
*/
|
||||
protected static function afterWrite($callback, $override = false)
|
||||
{
|
||||
self::event('after_write', $callback, $override);
|
||||
}
|
||||
|
||||
/**
|
||||
* 模型before_delete事件快捷方法
|
||||
* @access protected
|
||||
* @param callable $callback
|
||||
* @param bool $override
|
||||
*/
|
||||
protected static function beforeDelete($callback, $override = false)
|
||||
{
|
||||
self::event('before_delete', $callback, $override);
|
||||
}
|
||||
|
||||
/**
|
||||
* 模型after_delete事件快捷方法
|
||||
* @access protected
|
||||
* @param callable $callback
|
||||
* @param bool $override
|
||||
*/
|
||||
protected static function afterDelete($callback, $override = false)
|
||||
{
|
||||
self::event('after_delete', $callback, $override);
|
||||
}
|
||||
|
||||
/**
|
||||
* 模型before_restore事件快捷方法
|
||||
* @access protected
|
||||
* @param callable $callback
|
||||
* @param bool $override
|
||||
*/
|
||||
protected static function beforeRestore($callback, $override = false)
|
||||
{
|
||||
self::event('before_restore', $callback, $override);
|
||||
}
|
||||
|
||||
/**
|
||||
* 模型after_restore事件快捷方法
|
||||
* @access protected
|
||||
* @param callable $callback
|
||||
* @param bool $override
|
||||
*/
|
||||
protected static function afterRestore($callback, $override = false)
|
||||
{
|
||||
self::event('after_restore', $callback, $override);
|
||||
}
|
||||
}
|
||||
697
Server/thinkphp/library/think/model/concern/RelationShip.php
Normal file
697
Server/thinkphp/library/think/model/concern/RelationShip.php
Normal file
@@ -0,0 +1,697 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\model\concern;
|
||||
|
||||
use think\Collection;
|
||||
use think\db\Query;
|
||||
use think\Exception;
|
||||
use think\Loader;
|
||||
use think\Model;
|
||||
use think\model\Relation;
|
||||
use think\model\relation\BelongsTo;
|
||||
use think\model\relation\BelongsToMany;
|
||||
use think\model\relation\HasMany;
|
||||
use think\model\relation\HasManyThrough;
|
||||
use think\model\relation\HasOne;
|
||||
use think\model\relation\MorphMany;
|
||||
use think\model\relation\MorphOne;
|
||||
use think\model\relation\MorphTo;
|
||||
|
||||
/**
|
||||
* 模型关联处理
|
||||
*/
|
||||
trait RelationShip
|
||||
{
|
||||
/**
|
||||
* 父关联模型对象
|
||||
* @var object
|
||||
*/
|
||||
private $parent;
|
||||
|
||||
/**
|
||||
* 模型关联数据
|
||||
* @var array
|
||||
*/
|
||||
private $relation = [];
|
||||
|
||||
/**
|
||||
* 关联写入定义信息
|
||||
* @var array
|
||||
*/
|
||||
private $together;
|
||||
|
||||
/**
|
||||
* 关联自动写入信息
|
||||
* @var array
|
||||
*/
|
||||
protected $relationWrite;
|
||||
|
||||
/**
|
||||
* 设置父关联对象
|
||||
* @access public
|
||||
* @param Model $model 模型对象
|
||||
* @return $this
|
||||
*/
|
||||
public function setParent($model)
|
||||
{
|
||||
$this->parent = $model;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取父关联对象
|
||||
* @access public
|
||||
* @return Model
|
||||
*/
|
||||
public function getParent()
|
||||
{
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前模型的关联模型数据
|
||||
* @access public
|
||||
* @param string $name 关联方法名
|
||||
* @return mixed
|
||||
*/
|
||||
public function getRelation($name = null)
|
||||
{
|
||||
if (is_null($name)) {
|
||||
return $this->relation;
|
||||
} elseif (array_key_exists($name, $this->relation)) {
|
||||
return $this->relation[$name];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置关联数据对象值
|
||||
* @access public
|
||||
* @param string $name 属性名
|
||||
* @param mixed $value 属性值
|
||||
* @param array $data 数据
|
||||
* @return $this
|
||||
*/
|
||||
public function setRelation($name, $value, $data = [])
|
||||
{
|
||||
// 检测修改器
|
||||
$method = 'set' . Loader::parseName($name, 1) . 'Attr';
|
||||
|
||||
if (method_exists($this, $method)) {
|
||||
$value = $this->$method($value, array_merge($this->data, $data));
|
||||
}
|
||||
|
||||
$this->relation[$name] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定(一对一)关联属性到当前模型
|
||||
* @access protected
|
||||
* @param string $relation 关联名称
|
||||
* @param array $attrs 绑定属性
|
||||
* @return $this
|
||||
* @throws Exception
|
||||
*/
|
||||
public function bindAttr($relation, array $attrs = [])
|
||||
{
|
||||
$relation = $this->getRelation($relation);
|
||||
|
||||
foreach ($attrs as $key => $attr) {
|
||||
$key = is_numeric($key) ? $attr : $key;
|
||||
$value = $this->getOrigin($key);
|
||||
|
||||
if (!is_null($value)) {
|
||||
throw new Exception('bind attr has exists:' . $key);
|
||||
}
|
||||
|
||||
$this->setAttr($key, $relation ? $relation->getAttr($attr) : null);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 关联数据写入
|
||||
* @access public
|
||||
* @param array|string $relation 关联
|
||||
* @return $this
|
||||
*/
|
||||
public function together($relation)
|
||||
{
|
||||
if (is_string($relation)) {
|
||||
$relation = explode(',', $relation);
|
||||
}
|
||||
|
||||
$this->together = $relation;
|
||||
|
||||
$this->checkAutoRelationWrite();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据关联条件查询当前模型
|
||||
* @access public
|
||||
* @param string $relation 关联方法名
|
||||
* @param mixed $operator 比较操作符
|
||||
* @param integer $count 个数
|
||||
* @param string $id 关联表的统计字段
|
||||
* @param string $joinType JOIN类型
|
||||
* @return Query
|
||||
*/
|
||||
public static function has($relation, $operator = '>=', $count = 1, $id = '*', $joinType = 'INNER')
|
||||
{
|
||||
$relation = (new static())->$relation();
|
||||
|
||||
if (is_array($operator) || $operator instanceof \Closure) {
|
||||
return $relation->hasWhere($operator);
|
||||
}
|
||||
|
||||
return $relation->has($operator, $count, $id, $joinType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据关联条件查询当前模型
|
||||
* @access public
|
||||
* @param string $relation 关联方法名
|
||||
* @param mixed $where 查询条件(数组或者闭包)
|
||||
* @param mixed $fields 字段
|
||||
* @return Query
|
||||
*/
|
||||
public static function hasWhere($relation, $where = [], $fields = '*')
|
||||
{
|
||||
return (new static())->$relation()->hasWhere($where, $fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询当前模型的关联数据
|
||||
* @access public
|
||||
* @param string|array $relations 关联名
|
||||
* @param array $withRelationAttr 关联获取器
|
||||
* @return $this
|
||||
*/
|
||||
public function relationQuery($relations, $withRelationAttr = [])
|
||||
{
|
||||
if (is_string($relations)) {
|
||||
$relations = explode(',', $relations);
|
||||
}
|
||||
|
||||
foreach ($relations as $key => $relation) {
|
||||
$subRelation = '';
|
||||
$closure = null;
|
||||
|
||||
if ($relation instanceof \Closure) {
|
||||
// 支持闭包查询过滤关联条件
|
||||
$closure = $relation;
|
||||
$relation = $key;
|
||||
}
|
||||
|
||||
if (is_array($relation)) {
|
||||
$subRelation = $relation;
|
||||
$relation = $key;
|
||||
} elseif (strpos($relation, '.')) {
|
||||
list($relation, $subRelation) = explode('.', $relation, 2);
|
||||
}
|
||||
|
||||
$method = Loader::parseName($relation, 1, false);
|
||||
$relationName = Loader::parseName($relation);
|
||||
|
||||
$relationResult = $this->$method();
|
||||
|
||||
if (isset($withRelationAttr[$relationName])) {
|
||||
$relationResult->getQuery()->withAttr($withRelationAttr[$relationName]);
|
||||
}
|
||||
|
||||
$this->relation[$relation] = $relationResult->getRelation($subRelation, $closure);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 预载入关联查询 返回数据集
|
||||
* @access public
|
||||
* @param array $resultSet 数据集
|
||||
* @param string $relation 关联名
|
||||
* @param array $withRelationAttr 关联获取器
|
||||
* @param bool $join 是否为JOIN方式
|
||||
* @return array
|
||||
*/
|
||||
public function eagerlyResultSet(&$resultSet, $relation, $withRelationAttr = [], $join = false)
|
||||
{
|
||||
$relations = is_string($relation) ? explode(',', $relation) : $relation;
|
||||
|
||||
foreach ($relations as $key => $relation) {
|
||||
$subRelation = '';
|
||||
$closure = null;
|
||||
|
||||
if ($relation instanceof \Closure) {
|
||||
$closure = $relation;
|
||||
$relation = $key;
|
||||
}
|
||||
|
||||
if (is_array($relation)) {
|
||||
$subRelation = $relation;
|
||||
$relation = $key;
|
||||
} elseif (strpos($relation, '.')) {
|
||||
list($relation, $subRelation) = explode('.', $relation, 2);
|
||||
}
|
||||
|
||||
$relation = Loader::parseName($relation, 1, false);
|
||||
$relationName = Loader::parseName($relation);
|
||||
|
||||
$relationResult = $this->$relation();
|
||||
|
||||
if (isset($withRelationAttr[$relationName])) {
|
||||
$relationResult->getQuery()->withAttr($withRelationAttr[$relationName]);
|
||||
}
|
||||
|
||||
$relationResult->eagerlyResultSet($resultSet, $relation, $subRelation, $closure, $join);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 预载入关联查询 返回模型对象
|
||||
* @access public
|
||||
* @param Model $result 数据对象
|
||||
* @param string $relation 关联名
|
||||
* @param array $withRelationAttr 关联获取器
|
||||
* @param bool $join 是否为JOIN方式
|
||||
* @return Model
|
||||
*/
|
||||
public function eagerlyResult(&$result, $relation, $withRelationAttr = [], $join = false)
|
||||
{
|
||||
$relations = is_string($relation) ? explode(',', $relation) : $relation;
|
||||
|
||||
foreach ($relations as $key => $relation) {
|
||||
$subRelation = '';
|
||||
$closure = null;
|
||||
|
||||
if ($relation instanceof \Closure) {
|
||||
$closure = $relation;
|
||||
$relation = $key;
|
||||
}
|
||||
|
||||
if (is_array($relation)) {
|
||||
$subRelation = $relation;
|
||||
$relation = $key;
|
||||
} elseif (strpos($relation, '.')) {
|
||||
list($relation, $subRelation) = explode('.', $relation, 2);
|
||||
}
|
||||
|
||||
$relation = Loader::parseName($relation, 1, false);
|
||||
$relationName = Loader::parseName($relation);
|
||||
|
||||
$relationResult = $this->$relation();
|
||||
|
||||
if (isset($withRelationAttr[$relationName])) {
|
||||
$relationResult->getQuery()->withAttr($withRelationAttr[$relationName]);
|
||||
}
|
||||
|
||||
$relationResult->eagerlyResult($result, $relation, $subRelation, $closure, $join);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 关联统计
|
||||
* @access public
|
||||
* @param Model $result 数据对象
|
||||
* @param array $relations 关联名
|
||||
* @param string $aggregate 聚合查询方法
|
||||
* @param string $field 字段
|
||||
* @return void
|
||||
*/
|
||||
public function relationCount(&$result, $relations, $aggregate = 'sum', $field = '*')
|
||||
{
|
||||
foreach ($relations as $key => $relation) {
|
||||
$closure = $name = null;
|
||||
|
||||
if ($relation instanceof \Closure) {
|
||||
$closure = $relation;
|
||||
$relation = $key;
|
||||
} elseif (is_string($key)) {
|
||||
$name = $relation;
|
||||
$relation = $key;
|
||||
}
|
||||
|
||||
$relation = Loader::parseName($relation, 1, false);
|
||||
|
||||
$count = $this->$relation()->relationCount($result, $closure, $aggregate, $field, $name);
|
||||
|
||||
if (empty($name)) {
|
||||
$name = Loader::parseName($relation) . '_' . $aggregate;
|
||||
}
|
||||
|
||||
$result->setAttr($name, $count);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* HAS ONE 关联定义
|
||||
* @access public
|
||||
* @param string $model 模型名
|
||||
* @param string $foreignKey 关联外键
|
||||
* @param string $localKey 当前主键
|
||||
* @return HasOne
|
||||
*/
|
||||
public function hasOne($model, $foreignKey = '', $localKey = '')
|
||||
{
|
||||
// 记录当前关联信息
|
||||
$model = $this->parseModel($model);
|
||||
$localKey = $localKey ?: $this->getPk();
|
||||
$foreignKey = $foreignKey ?: $this->getForeignKey($this->name);
|
||||
|
||||
return new HasOne($this, $model, $foreignKey, $localKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* BELONGS TO 关联定义
|
||||
* @access public
|
||||
* @param string $model 模型名
|
||||
* @param string $foreignKey 关联外键
|
||||
* @param string $localKey 关联主键
|
||||
* @return BelongsTo
|
||||
*/
|
||||
public function belongsTo($model, $foreignKey = '', $localKey = '')
|
||||
{
|
||||
// 记录当前关联信息
|
||||
$model = $this->parseModel($model);
|
||||
$foreignKey = $foreignKey ?: $this->getForeignKey((new $model)->getName());
|
||||
$localKey = $localKey ?: (new $model)->getPk();
|
||||
$trace = debug_backtrace(false, 2);
|
||||
$relation = Loader::parseName($trace[1]['function']);
|
||||
|
||||
return new BelongsTo($this, $model, $foreignKey, $localKey, $relation);
|
||||
}
|
||||
|
||||
/**
|
||||
* HAS MANY 关联定义
|
||||
* @access public
|
||||
* @param string $model 模型名
|
||||
* @param string $foreignKey 关联外键
|
||||
* @param string $localKey 当前主键
|
||||
* @return HasMany
|
||||
*/
|
||||
public function hasMany($model, $foreignKey = '', $localKey = '')
|
||||
{
|
||||
// 记录当前关联信息
|
||||
$model = $this->parseModel($model);
|
||||
$localKey = $localKey ?: $this->getPk();
|
||||
$foreignKey = $foreignKey ?: $this->getForeignKey($this->name);
|
||||
|
||||
return new HasMany($this, $model, $foreignKey, $localKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* HAS MANY 远程关联定义
|
||||
* @access public
|
||||
* @param string $model 模型名
|
||||
* @param string $through 中间模型名
|
||||
* @param string $foreignKey 关联外键
|
||||
* @param string $throughKey 关联外键
|
||||
* @param string $localKey 当前主键
|
||||
* @return HasManyThrough
|
||||
*/
|
||||
public function hasManyThrough($model, $through, $foreignKey = '', $throughKey = '', $localKey = '')
|
||||
{
|
||||
// 记录当前关联信息
|
||||
$model = $this->parseModel($model);
|
||||
$through = $this->parseModel($through);
|
||||
$localKey = $localKey ?: $this->getPk();
|
||||
$foreignKey = $foreignKey ?: $this->getForeignKey($this->name);
|
||||
$throughKey = $throughKey ?: $this->getForeignKey((new $through)->getName());
|
||||
|
||||
return new HasManyThrough($this, $model, $through, $foreignKey, $throughKey, $localKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* BELONGS TO MANY 关联定义
|
||||
* @access public
|
||||
* @param string $model 模型名
|
||||
* @param string $table 中间表名
|
||||
* @param string $foreignKey 关联外键
|
||||
* @param string $localKey 当前模型关联键
|
||||
* @return BelongsToMany
|
||||
*/
|
||||
public function belongsToMany($model, $table = '', $foreignKey = '', $localKey = '')
|
||||
{
|
||||
// 记录当前关联信息
|
||||
$model = $this->parseModel($model);
|
||||
$name = Loader::parseName(basename(str_replace('\\', '/', $model)));
|
||||
$table = $table ?: Loader::parseName($this->name) . '_' . $name;
|
||||
$foreignKey = $foreignKey ?: $name . '_id';
|
||||
$localKey = $localKey ?: $this->getForeignKey($this->name);
|
||||
|
||||
return new BelongsToMany($this, $model, $table, $foreignKey, $localKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* MORPH One 关联定义
|
||||
* @access public
|
||||
* @param string $model 模型名
|
||||
* @param string|array $morph 多态字段信息
|
||||
* @param string $type 多态类型
|
||||
* @return MorphOne
|
||||
*/
|
||||
public function morphOne($model, $morph = null, $type = '')
|
||||
{
|
||||
// 记录当前关联信息
|
||||
$model = $this->parseModel($model);
|
||||
|
||||
if (is_null($morph)) {
|
||||
$trace = debug_backtrace(false, 2);
|
||||
$morph = Loader::parseName($trace[1]['function']);
|
||||
}
|
||||
|
||||
if (is_array($morph)) {
|
||||
list($morphType, $foreignKey) = $morph;
|
||||
} else {
|
||||
$morphType = $morph . '_type';
|
||||
$foreignKey = $morph . '_id';
|
||||
}
|
||||
|
||||
$type = $type ?: get_class($this);
|
||||
|
||||
return new MorphOne($this, $model, $foreignKey, $morphType, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* MORPH MANY 关联定义
|
||||
* @access public
|
||||
* @param string $model 模型名
|
||||
* @param string|array $morph 多态字段信息
|
||||
* @param string $type 多态类型
|
||||
* @return MorphMany
|
||||
*/
|
||||
public function morphMany($model, $morph = null, $type = '')
|
||||
{
|
||||
// 记录当前关联信息
|
||||
$model = $this->parseModel($model);
|
||||
|
||||
if (is_null($morph)) {
|
||||
$trace = debug_backtrace(false, 2);
|
||||
$morph = Loader::parseName($trace[1]['function']);
|
||||
}
|
||||
|
||||
$type = $type ?: get_class($this);
|
||||
|
||||
if (is_array($morph)) {
|
||||
list($morphType, $foreignKey) = $morph;
|
||||
} else {
|
||||
$morphType = $morph . '_type';
|
||||
$foreignKey = $morph . '_id';
|
||||
}
|
||||
|
||||
return new MorphMany($this, $model, $foreignKey, $morphType, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* MORPH TO 关联定义
|
||||
* @access public
|
||||
* @param string|array $morph 多态字段信息
|
||||
* @param array $alias 多态别名定义
|
||||
* @return MorphTo
|
||||
*/
|
||||
public function morphTo($morph = null, $alias = [])
|
||||
{
|
||||
$trace = debug_backtrace(false, 2);
|
||||
$relation = Loader::parseName($trace[1]['function']);
|
||||
|
||||
if (is_null($morph)) {
|
||||
$morph = $relation;
|
||||
}
|
||||
|
||||
// 记录当前关联信息
|
||||
if (is_array($morph)) {
|
||||
list($morphType, $foreignKey) = $morph;
|
||||
} else {
|
||||
$morphType = $morph . '_type';
|
||||
$foreignKey = $morph . '_id';
|
||||
}
|
||||
|
||||
return new MorphTo($this, $morphType, $foreignKey, $alias, $relation);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析模型的完整命名空间
|
||||
* @access protected
|
||||
* @param string $model 模型名(或者完整类名)
|
||||
* @return string
|
||||
*/
|
||||
protected function parseModel($model)
|
||||
{
|
||||
if (false === strpos($model, '\\')) {
|
||||
$path = explode('\\', static::class);
|
||||
array_pop($path);
|
||||
array_push($path, Loader::parseName($model, 1));
|
||||
$model = implode('\\', $path);
|
||||
}
|
||||
|
||||
return $model;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取模型的默认外键名
|
||||
* @access protected
|
||||
* @param string $name 模型名
|
||||
* @return string
|
||||
*/
|
||||
protected function getForeignKey($name)
|
||||
{
|
||||
if (strpos($name, '\\')) {
|
||||
$name = basename(str_replace('\\', '/', $name));
|
||||
}
|
||||
|
||||
return Loader::parseName($name) . '_id';
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查属性是否为关联属性 如果是则返回关联方法名
|
||||
* @access protected
|
||||
* @param string $attr 关联属性名
|
||||
* @return string|false
|
||||
*/
|
||||
protected function isRelationAttr($attr)
|
||||
{
|
||||
$relation = Loader::parseName($attr, 1, false);
|
||||
|
||||
if (method_exists($this, $relation) && !method_exists('think\Model', $relation)) {
|
||||
return $relation;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 智能获取关联模型数据
|
||||
* @access protected
|
||||
* @param Relation $modelRelation 模型关联对象
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getRelationData(Relation $modelRelation)
|
||||
{
|
||||
if ($this->parent && !$modelRelation->isSelfRelation() && get_class($this->parent) == get_class($modelRelation->getModel())) {
|
||||
$value = $this->parent;
|
||||
} else {
|
||||
// 获取关联数据
|
||||
$value = $modelRelation->getRelation();
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 关联数据自动写入检查
|
||||
* @access protected
|
||||
* @return void
|
||||
*/
|
||||
protected function checkAutoRelationWrite()
|
||||
{
|
||||
foreach ($this->together as $key => $name) {
|
||||
if (is_array($name)) {
|
||||
if (key($name) === 0) {
|
||||
$this->relationWrite[$key] = [];
|
||||
// 绑定关联属性
|
||||
foreach ((array) $name as $val) {
|
||||
if (isset($this->data[$val])) {
|
||||
$this->relationWrite[$key][$val] = $this->data[$val];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 直接传入关联数据
|
||||
$this->relationWrite[$key] = $name;
|
||||
}
|
||||
} elseif (isset($this->relation[$name])) {
|
||||
$this->relationWrite[$name] = $this->relation[$name];
|
||||
} elseif (isset($this->data[$name])) {
|
||||
$this->relationWrite[$name] = $this->data[$name];
|
||||
unset($this->data[$name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动关联数据更新(针对一对一关联)
|
||||
* @access protected
|
||||
* @return void
|
||||
*/
|
||||
protected function autoRelationUpdate()
|
||||
{
|
||||
foreach ($this->relationWrite as $name => $val) {
|
||||
if ($val instanceof Model) {
|
||||
$val->isUpdate()->save();
|
||||
} else {
|
||||
$model = $this->getRelation($name);
|
||||
if ($model instanceof Model) {
|
||||
$model->isUpdate()->save($val);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动关联数据写入(针对一对一关联)
|
||||
* @access protected
|
||||
* @return void
|
||||
*/
|
||||
protected function autoRelationInsert()
|
||||
{
|
||||
foreach ($this->relationWrite as $name => $val) {
|
||||
$method = Loader::parseName($name, 1, false);
|
||||
$this->$method()->save($val);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动关联数据删除(支持一对一及一对多关联)
|
||||
* @access protected
|
||||
* @return void
|
||||
*/
|
||||
protected function autoRelationDelete()
|
||||
{
|
||||
foreach ($this->relationWrite as $key => $name) {
|
||||
$name = is_numeric($key) ? $name : $key;
|
||||
$result = $this->getRelation($name);
|
||||
|
||||
if ($result instanceof Model) {
|
||||
$result->delete();
|
||||
} elseif ($result instanceof Collection) {
|
||||
foreach ($result as $model) {
|
||||
$model->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
246
Server/thinkphp/library/think/model/concern/SoftDelete.php
Normal file
246
Server/thinkphp/library/think/model/concern/SoftDelete.php
Normal file
@@ -0,0 +1,246 @@
|
||||
<?php
|
||||
|
||||
namespace think\model\concern;
|
||||
|
||||
use think\db\Query;
|
||||
|
||||
/**
|
||||
* 数据软删除
|
||||
*/
|
||||
trait SoftDelete
|
||||
{
|
||||
|
||||
/**
|
||||
* 是否包含软删除数据
|
||||
* @var bool
|
||||
*/
|
||||
protected $withTrashed = false;
|
||||
|
||||
/**
|
||||
* 判断当前实例是否被软删除
|
||||
* @access public
|
||||
* @return boolean
|
||||
*/
|
||||
public function trashed()
|
||||
{
|
||||
$field = $this->getDeleteTimeField();
|
||||
|
||||
if ($field && !empty($this->getOrigin($field))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询软删除数据
|
||||
* @access public
|
||||
* @return Query
|
||||
*/
|
||||
public static function withTrashed()
|
||||
{
|
||||
$model = new static();
|
||||
|
||||
return $model->withTrashedData(true)->db(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否包含软删除数据
|
||||
* @access protected
|
||||
* @param bool $withTrashed 是否包含软删除数据
|
||||
* @return $this
|
||||
*/
|
||||
protected function withTrashedData($withTrashed)
|
||||
{
|
||||
$this->withTrashed = $withTrashed;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 只查询软删除数据
|
||||
* @access public
|
||||
* @return Query
|
||||
*/
|
||||
public static function onlyTrashed()
|
||||
{
|
||||
$model = new static();
|
||||
$field = $model->getDeleteTimeField(true);
|
||||
|
||||
if ($field) {
|
||||
return $model
|
||||
->db(false)
|
||||
->useSoftDelete($field, $model->getWithTrashedExp());
|
||||
}
|
||||
|
||||
return $model->db(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取软删除数据的查询条件
|
||||
* @access protected
|
||||
* @return array
|
||||
*/
|
||||
protected function getWithTrashedExp()
|
||||
{
|
||||
return is_null($this->defaultSoftDelete) ?
|
||||
['notnull', ''] : ['<>', $this->defaultSoftDelete];
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除当前的记录
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function delete($force = false)
|
||||
{
|
||||
if (!$this->isExists() || false === $this->trigger('before_delete', $this)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$force = $force ?: $this->isForce();
|
||||
$name = $this->getDeleteTimeField();
|
||||
|
||||
if ($name && !$force) {
|
||||
// 软删除
|
||||
$this->data($name, $this->autoWriteTimestamp($name));
|
||||
|
||||
$result = $this->isUpdate()->withEvent(false)->save();
|
||||
|
||||
$this->withEvent(true);
|
||||
} else {
|
||||
// 读取更新条件
|
||||
$where = $this->getWhere();
|
||||
|
||||
// 删除当前模型数据
|
||||
$result = $this->db(false)
|
||||
->where($where)
|
||||
->removeOption('soft_delete')
|
||||
->delete();
|
||||
}
|
||||
|
||||
// 关联删除
|
||||
if (!empty($this->relationWrite)) {
|
||||
$this->autoRelationDelete();
|
||||
}
|
||||
|
||||
$this->trigger('after_delete', $this);
|
||||
|
||||
$this->exists(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除记录
|
||||
* @access public
|
||||
* @param mixed $data 主键列表 支持闭包查询条件
|
||||
* @param bool $force 是否强制删除
|
||||
* @return bool
|
||||
*/
|
||||
public static function destroy($data, $force = false)
|
||||
{
|
||||
// 传入空不执行删除,但是0可以删除
|
||||
if (empty($data) && 0 !== $data) {
|
||||
return false;
|
||||
}
|
||||
// 包含软删除数据
|
||||
$query = (new static())->db(false);
|
||||
|
||||
if (is_array($data) && key($data) !== 0) {
|
||||
$query->where($data);
|
||||
$data = null;
|
||||
} elseif ($data instanceof \Closure) {
|
||||
call_user_func_array($data, [ & $query]);
|
||||
$data = null;
|
||||
} elseif (is_null($data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$resultSet = $query->select($data);
|
||||
|
||||
if ($resultSet) {
|
||||
foreach ($resultSet as $data) {
|
||||
$data->force($force)->delete();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复被软删除的记录
|
||||
* @access public
|
||||
* @param array $where 更新条件
|
||||
* @return bool
|
||||
*/
|
||||
public function restore($where = [])
|
||||
{
|
||||
$name = $this->getDeleteTimeField();
|
||||
|
||||
if ($name) {
|
||||
if (false === $this->trigger('before_restore')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (empty($where)) {
|
||||
$pk = $this->getPk();
|
||||
|
||||
$where[] = [$pk, '=', $this->getData($pk)];
|
||||
}
|
||||
|
||||
// 恢复删除
|
||||
$this->db(false)
|
||||
->where($where)
|
||||
->useSoftDelete($name, $this->getWithTrashedExp())
|
||||
->update([$name => $this->defaultSoftDelete]);
|
||||
|
||||
$this->trigger('after_restore');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取软删除字段
|
||||
* @access protected
|
||||
* @param bool $read 是否查询操作 写操作的时候会自动去掉表别名
|
||||
* @return string|false
|
||||
*/
|
||||
protected function getDeleteTimeField($read = false)
|
||||
{
|
||||
$field = property_exists($this, 'deleteTime') && isset($this->deleteTime) ? $this->deleteTime : 'delete_time';
|
||||
|
||||
if (false === $field) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (false === strpos($field, '.')) {
|
||||
$field = '__TABLE__.' . $field;
|
||||
}
|
||||
|
||||
if (!$read && strpos($field, '.')) {
|
||||
$array = explode('.', $field);
|
||||
$field = array_pop($array);
|
||||
}
|
||||
|
||||
return $field;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询的时候默认排除软删除数据
|
||||
* @access protected
|
||||
* @param Query $query
|
||||
* @return void
|
||||
*/
|
||||
protected function withNoTrashed($query)
|
||||
{
|
||||
$field = $this->getDeleteTimeField(true);
|
||||
|
||||
if ($field) {
|
||||
$condition = is_null($this->defaultSoftDelete) ? ['null', ''] : ['=', $this->defaultSoftDelete];
|
||||
$query->useSoftDelete($field, $condition);
|
||||
}
|
||||
}
|
||||
}
|
||||
92
Server/thinkphp/library/think/model/concern/TimeStamp.php
Normal file
92
Server/thinkphp/library/think/model/concern/TimeStamp.php
Normal file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\model\concern;
|
||||
|
||||
use DateTime;
|
||||
|
||||
/**
|
||||
* 自动时间戳
|
||||
*/
|
||||
trait TimeStamp
|
||||
{
|
||||
/**
|
||||
* 是否需要自动写入时间戳 如果设置为字符串 则表示时间字段的类型
|
||||
* @var bool|string
|
||||
*/
|
||||
protected $autoWriteTimestamp;
|
||||
|
||||
/**
|
||||
* 创建时间字段 false表示关闭
|
||||
* @var false|string
|
||||
*/
|
||||
protected $createTime = 'create_time';
|
||||
|
||||
/**
|
||||
* 更新时间字段 false表示关闭
|
||||
* @var false|string
|
||||
*/
|
||||
protected $updateTime = 'update_time';
|
||||
|
||||
/**
|
||||
* 时间字段显示格式
|
||||
* @var string
|
||||
*/
|
||||
protected $dateFormat;
|
||||
|
||||
/**
|
||||
* 时间日期字段格式化处理
|
||||
* @access protected
|
||||
* @param mixed $format 日期格式
|
||||
* @param mixed $time 时间日期表达式
|
||||
* @param bool $timestamp 是否进行时间戳转换
|
||||
* @return mixed
|
||||
*/
|
||||
protected function formatDateTime($format, $time = 'now', $timestamp = false)
|
||||
{
|
||||
if (empty($time)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (false === $format) {
|
||||
return $time;
|
||||
} elseif (false !== strpos($format, '\\')) {
|
||||
return new $format($time);
|
||||
}
|
||||
|
||||
if ($timestamp) {
|
||||
$dateTime = new DateTime();
|
||||
$dateTime->setTimestamp($time);
|
||||
} else {
|
||||
$dateTime = new DateTime($time);
|
||||
}
|
||||
|
||||
return $dateTime->format($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查时间字段写入
|
||||
* @access protected
|
||||
* @return void
|
||||
*/
|
||||
protected function checkTimeStampWrite()
|
||||
{
|
||||
// 自动写入创建时间和更新时间
|
||||
if ($this->autoWriteTimestamp) {
|
||||
if ($this->createTime && !isset($this->data[$this->createTime])) {
|
||||
$this->data[$this->createTime] = $this->autoWriteTimestamp($this->createTime);
|
||||
}
|
||||
if ($this->updateTime && !isset($this->data[$this->updateTime])) {
|
||||
$this->data[$this->updateTime] = $this->autoWriteTimestamp($this->updateTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
42
Server/thinkphp/library/think/process/exception/Faild.php
Normal file
42
Server/thinkphp/library/think/process/exception/Faild.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\process\exception;
|
||||
|
||||
use think\Process;
|
||||
|
||||
class Faild extends \RuntimeException
|
||||
{
|
||||
|
||||
private $process;
|
||||
|
||||
public function __construct(Process $process)
|
||||
{
|
||||
if ($process->isSuccessful()) {
|
||||
throw new \InvalidArgumentException('Expected a failed process, but the given process was successful.');
|
||||
}
|
||||
|
||||
$error = sprintf('The command "%s" failed.' . "\nExit Code: %s(%s)", $process->getCommandLine(), $process->getExitCode(), $process->getExitCodeText());
|
||||
|
||||
if (!$process->isOutputDisabled()) {
|
||||
$error .= sprintf("\n\nOutput:\n================\n%s\n\nError Output:\n================\n%s", $process->getOutput(), $process->getErrorOutput());
|
||||
}
|
||||
|
||||
parent::__construct($error);
|
||||
|
||||
$this->process = $process;
|
||||
}
|
||||
|
||||
public function getProcess()
|
||||
{
|
||||
return $this->process;
|
||||
}
|
||||
}
|
||||
148
Server/thinkphp/library/think/response/Download.php
Normal file
148
Server/thinkphp/library/think/response/Download.php
Normal file
@@ -0,0 +1,148 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\response;
|
||||
|
||||
use think\Exception;
|
||||
use think\Response;
|
||||
|
||||
class Download extends Response
|
||||
{
|
||||
protected $expire = 360;
|
||||
protected $name;
|
||||
protected $mimeType;
|
||||
protected $isContent = false;
|
||||
protected $openinBrowser = false;
|
||||
/**
|
||||
* 处理数据
|
||||
* @access protected
|
||||
* @param mixed $data 要处理的数据
|
||||
* @return mixed
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function output($data)
|
||||
{
|
||||
if (!$this->isContent && !is_file($data)) {
|
||||
throw new Exception('file not exists:' . $data);
|
||||
}
|
||||
|
||||
ob_end_clean();
|
||||
|
||||
if (!empty($this->name)) {
|
||||
$name = $this->name;
|
||||
} else {
|
||||
$name = !$this->isContent ? pathinfo($data, PATHINFO_BASENAME) : '';
|
||||
}
|
||||
|
||||
if ($this->isContent) {
|
||||
$mimeType = $this->mimeType;
|
||||
$size = strlen($data);
|
||||
} else {
|
||||
$mimeType = $this->getMimeType($data);
|
||||
$size = filesize($data);
|
||||
}
|
||||
|
||||
$this->header['Pragma'] = 'public';
|
||||
$this->header['Content-Type'] = $mimeType ?: 'application/octet-stream';
|
||||
$this->header['Cache-control'] = 'max-age=' . $this->expire;
|
||||
$this->header['Content-Disposition'] = $this->openinBrowser ? 'inline' : 'attachment; filename="' . $name . '"';
|
||||
$this->header['Content-Length'] = $size;
|
||||
$this->header['Content-Transfer-Encoding'] = 'binary';
|
||||
$this->header['Expires'] = gmdate("D, d M Y H:i:s", time() + $this->expire) . ' GMT';
|
||||
|
||||
$this->lastModified(gmdate('D, d M Y H:i:s', time()) . ' GMT');
|
||||
|
||||
$data = $this->isContent ? $data : file_get_contents($data);
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置是否为内容 必须配合mimeType方法使用
|
||||
* @access public
|
||||
* @param bool $content
|
||||
* @return $this
|
||||
*/
|
||||
public function isContent($content = true)
|
||||
{
|
||||
$this->isContent = $content;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置有效期
|
||||
* @access public
|
||||
* @param integer $expire 有效期
|
||||
* @return $this
|
||||
*/
|
||||
public function expire($expire)
|
||||
{
|
||||
$this->expire = $expire;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置文件类型
|
||||
* @access public
|
||||
* @param string $filename 文件名
|
||||
* @return $this
|
||||
*/
|
||||
public function mimeType($mimeType)
|
||||
{
|
||||
$this->mimeType = $mimeType;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件类型信息
|
||||
* @access public
|
||||
* @param string $filename 文件名
|
||||
* @return string
|
||||
*/
|
||||
protected function getMimeType($filename)
|
||||
{
|
||||
if (!empty($this->mimeType)) {
|
||||
return $this->mimeType;
|
||||
}
|
||||
|
||||
$finfo = finfo_open(FILEINFO_MIME_TYPE);
|
||||
|
||||
return finfo_file($finfo, $filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置下载文件的显示名称
|
||||
* @access public
|
||||
* @param string $filename 文件名
|
||||
* @param bool $extension 后缀自动识别
|
||||
* @return $this
|
||||
*/
|
||||
public function name($filename, $extension = true)
|
||||
{
|
||||
$this->name = $filename;
|
||||
|
||||
if ($extension && false === strpos($filename, '.')) {
|
||||
$this->name .= '.' . pathinfo($this->data, PATHINFO_EXTENSION);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置是否在浏览器中显示文件
|
||||
* @access public
|
||||
* @param bool $openinBrowser 是否在浏览器中显示文件
|
||||
* @return $this
|
||||
*/
|
||||
public function openinBrowser($openinBrowser) {
|
||||
$this->openinBrowser = $openinBrowser;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
32
Server/thinkphp/library/think/response/Jump.php
Normal file
32
Server/thinkphp/library/think/response/Jump.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\response;
|
||||
|
||||
use think\Response;
|
||||
|
||||
class Jump extends Response
|
||||
{
|
||||
protected $contentType = 'text/html';
|
||||
|
||||
/**
|
||||
* 处理数据
|
||||
* @access protected
|
||||
* @param mixed $data 要处理的数据
|
||||
* @return mixed
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function output($data)
|
||||
{
|
||||
$data = $this->app['view']->fetch($this->options['jump_template'], $data);
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
119
Server/thinkphp/library/think/route/AliasRule.php
Normal file
119
Server/thinkphp/library/think/route/AliasRule.php
Normal file
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\route;
|
||||
|
||||
use think\Route;
|
||||
|
||||
class AliasRule extends Domain
|
||||
{
|
||||
/**
|
||||
* 架构函数
|
||||
* @access public
|
||||
* @param Route $router 路由实例
|
||||
* @param RuleGroup $parent 上级对象
|
||||
* @param string $name 路由别名
|
||||
* @param string $route 路由绑定
|
||||
* @param array $option 路由参数
|
||||
*/
|
||||
public function __construct(Route $router, RuleGroup $parent, $name, $route, $option = [])
|
||||
{
|
||||
$this->router = $router;
|
||||
$this->parent = $parent;
|
||||
$this->name = $name;
|
||||
$this->route = $route;
|
||||
$this->option = $option;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测路由别名
|
||||
* @access public
|
||||
* @param Request $request 请求对象
|
||||
* @param string $url 访问地址
|
||||
* @param bool $completeMatch 路由是否完全匹配
|
||||
* @return Dispatch|false
|
||||
*/
|
||||
public function check($request, $url, $completeMatch = false)
|
||||
{
|
||||
if ($dispatch = $this->checkCrossDomain($request)) {
|
||||
// 允许跨域
|
||||
return $dispatch;
|
||||
}
|
||||
|
||||
// 检查参数有效性
|
||||
if (!$this->checkOption($this->option, $request)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
list($action, $bind) = array_pad(explode('|', $url, 2), 2, '');
|
||||
|
||||
if (isset($this->option['allow']) && !in_array($action, $this->option['allow'])) {
|
||||
// 允许操作
|
||||
return false;
|
||||
} elseif (isset($this->option['except']) && in_array($action, $this->option['except'])) {
|
||||
// 排除操作
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($this->option['method'][$action])) {
|
||||
$this->option['method'] = $this->option['method'][$action];
|
||||
}
|
||||
|
||||
// 匹配后执行的行为
|
||||
$this->afterMatchGroup($request);
|
||||
|
||||
if ($this->parent) {
|
||||
// 合并分组参数
|
||||
$this->mergeGroupOptions();
|
||||
}
|
||||
|
||||
if (isset($this->option['ext'])) {
|
||||
// 路由ext参数 优先于系统配置的URL伪静态后缀参数
|
||||
$bind = preg_replace('/\.(' . $request->ext() . ')$/i', '', $bind);
|
||||
}
|
||||
|
||||
$this->parseBindAppendParam($this->route);
|
||||
|
||||
if (0 === strpos($this->route, '\\')) {
|
||||
// 路由到类
|
||||
return $this->bindToClass($request, $bind, substr($this->route, 1));
|
||||
} elseif (0 === strpos($this->route, '@')) {
|
||||
// 路由到控制器类
|
||||
return $this->bindToController($request, $bind, substr($this->route, 1));
|
||||
} else {
|
||||
// 路由到模块/控制器
|
||||
return $this->bindToModule($request, $bind, $this->route);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置允许的操作方法
|
||||
* @access public
|
||||
* @param array $action 操作方法
|
||||
* @return $this
|
||||
*/
|
||||
public function allow($action = [])
|
||||
{
|
||||
return $this->option('allow', $action);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置排除的操作方法
|
||||
* @access public
|
||||
* @param array $action 操作方法
|
||||
* @return $this
|
||||
*/
|
||||
public function except($action = [])
|
||||
{
|
||||
return $this->option('except', $action);
|
||||
}
|
||||
|
||||
}
|
||||
366
Server/thinkphp/library/think/route/Dispatch.php
Normal file
366
Server/thinkphp/library/think/route/Dispatch.php
Normal file
@@ -0,0 +1,366 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\route;
|
||||
|
||||
use think\App;
|
||||
use think\Container;
|
||||
use think\exception\ValidateException;
|
||||
use think\Request;
|
||||
use think\Response;
|
||||
|
||||
abstract class Dispatch
|
||||
{
|
||||
/**
|
||||
* 应用对象
|
||||
* @var App
|
||||
*/
|
||||
protected $app;
|
||||
|
||||
/**
|
||||
* 请求对象
|
||||
* @var Request
|
||||
*/
|
||||
protected $request;
|
||||
|
||||
/**
|
||||
* 路由规则
|
||||
* @var Rule
|
||||
*/
|
||||
protected $rule;
|
||||
|
||||
/**
|
||||
* 调度信息
|
||||
* @var mixed
|
||||
*/
|
||||
protected $dispatch;
|
||||
|
||||
/**
|
||||
* 调度参数
|
||||
* @var array
|
||||
*/
|
||||
protected $param;
|
||||
|
||||
/**
|
||||
* 状态码
|
||||
* @var string
|
||||
*/
|
||||
protected $code;
|
||||
|
||||
/**
|
||||
* 是否进行大小写转换
|
||||
* @var bool
|
||||
*/
|
||||
protected $convert;
|
||||
|
||||
public function __construct(Request $request, Rule $rule, $dispatch, $param = [], $code = null)
|
||||
{
|
||||
$this->request = $request;
|
||||
$this->rule = $rule;
|
||||
$this->app = Container::get('app');
|
||||
$this->dispatch = $dispatch;
|
||||
$this->param = $param;
|
||||
$this->code = $code;
|
||||
|
||||
if (isset($param['convert'])) {
|
||||
$this->convert = $param['convert'];
|
||||
}
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
// 执行路由后置操作
|
||||
if ($this->rule->doAfter()) {
|
||||
// 设置请求的路由信息
|
||||
|
||||
// 设置当前请求的参数
|
||||
$this->request->setRouteVars($this->rule->getVars());
|
||||
$this->request->routeInfo([
|
||||
'rule' => $this->rule->getRule(),
|
||||
'route' => $this->rule->getRoute(),
|
||||
'option' => $this->rule->getOption(),
|
||||
'var' => $this->rule->getVars(),
|
||||
]);
|
||||
|
||||
$this->doRouteAfter();
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查路由后置操作
|
||||
* @access protected
|
||||
* @return void
|
||||
*/
|
||||
protected function doRouteAfter()
|
||||
{
|
||||
// 记录匹配的路由信息
|
||||
$option = $this->rule->getOption();
|
||||
$matches = $this->rule->getVars();
|
||||
|
||||
// 添加中间件
|
||||
if (!empty($option['middleware'])) {
|
||||
$this->app['middleware']->import($option['middleware']);
|
||||
}
|
||||
|
||||
// 绑定模型数据
|
||||
if (!empty($option['model'])) {
|
||||
$this->createBindModel($option['model'], $matches);
|
||||
}
|
||||
|
||||
// 指定Header数据
|
||||
if (!empty($option['header'])) {
|
||||
$header = $option['header'];
|
||||
$this->app['hook']->add('response_send', function ($response) use ($header) {
|
||||
$response->header($header);
|
||||
});
|
||||
}
|
||||
|
||||
// 指定Response响应数据
|
||||
if (!empty($option['response'])) {
|
||||
foreach ($option['response'] as $response) {
|
||||
$this->app['hook']->add('response_send', $response);
|
||||
}
|
||||
}
|
||||
|
||||
// 开启请求缓存
|
||||
if (isset($option['cache']) && $this->request->isGet()) {
|
||||
$this->parseRequestCache($option['cache']);
|
||||
}
|
||||
|
||||
if (!empty($option['append'])) {
|
||||
$this->request->setRouteVars($option['append']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行路由调度
|
||||
* @access public
|
||||
* @return mixed
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$option = $this->rule->getOption();
|
||||
|
||||
// 检测路由after行为
|
||||
if (!empty($option['after'])) {
|
||||
$dispatch = $this->checkAfter($option['after']);
|
||||
|
||||
if ($dispatch instanceof Response) {
|
||||
return $dispatch;
|
||||
}
|
||||
}
|
||||
|
||||
// 数据自动验证
|
||||
if (isset($option['validate'])) {
|
||||
$this->autoValidate($option['validate']);
|
||||
}
|
||||
|
||||
$data = $this->exec();
|
||||
|
||||
return $this->autoResponse($data);
|
||||
}
|
||||
|
||||
protected function autoResponse($data)
|
||||
{
|
||||
if ($data instanceof Response) {
|
||||
$response = $data;
|
||||
} elseif (!is_null($data)) {
|
||||
// 默认自动识别响应输出类型
|
||||
$isAjax = $this->request->isAjax();
|
||||
$type = $isAjax ? $this->rule->getConfig('default_ajax_return') : $this->rule->getConfig('default_return_type');
|
||||
|
||||
$response = Response::create($data, $type);
|
||||
} else {
|
||||
$data = ob_get_clean();
|
||||
$content = false === $data ? '' : $data;
|
||||
$status = '' === $content && $this->request->isJson() ? 204 : 200;
|
||||
|
||||
$response = Response::create($content, '', $status);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查路由后置行为
|
||||
* @access protected
|
||||
* @param mixed $after 后置行为
|
||||
* @return mixed
|
||||
*/
|
||||
protected function checkAfter($after)
|
||||
{
|
||||
$this->app['log']->notice('路由后置行为建议使用中间件替代!');
|
||||
|
||||
$hook = $this->app['hook'];
|
||||
|
||||
$result = null;
|
||||
|
||||
foreach ((array) $after as $behavior) {
|
||||
$result = $hook->exec($behavior);
|
||||
|
||||
if (!is_null($result)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 路由规则重定向
|
||||
if ($result instanceof Response) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证数据
|
||||
* @access protected
|
||||
* @param array $option
|
||||
* @return void
|
||||
* @throws ValidateException
|
||||
*/
|
||||
protected function autoValidate($option)
|
||||
{
|
||||
list($validate, $scene, $message, $batch) = $option;
|
||||
|
||||
if (is_array($validate)) {
|
||||
// 指定验证规则
|
||||
$v = $this->app->validate();
|
||||
$v->rule($validate);
|
||||
} else {
|
||||
// 调用验证器
|
||||
$v = $this->app->validate($validate);
|
||||
if (!empty($scene)) {
|
||||
$v->scene($scene);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($message)) {
|
||||
$v->message($message);
|
||||
}
|
||||
|
||||
// 批量验证
|
||||
if ($batch) {
|
||||
$v->batch(true);
|
||||
}
|
||||
|
||||
if (!$v->check($this->request->param())) {
|
||||
throw new ValidateException($v->getError());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理路由请求缓存
|
||||
* @access protected
|
||||
* @param Request $request 请求对象
|
||||
* @param string|array $cache 路由缓存
|
||||
* @return void
|
||||
*/
|
||||
protected function parseRequestCache($cache)
|
||||
{
|
||||
if (is_array($cache)) {
|
||||
list($key, $expire, $tag) = array_pad($cache, 3, null);
|
||||
} else {
|
||||
$key = str_replace('|', '/', $this->request->url());
|
||||
$expire = $cache;
|
||||
$tag = null;
|
||||
}
|
||||
|
||||
$cache = $this->request->cache($key, $expire, $tag);
|
||||
$this->app->setResponseCache($cache);
|
||||
}
|
||||
|
||||
/**
|
||||
* 路由绑定模型实例
|
||||
* @access protected
|
||||
* @param array|\Clousre $bindModel 绑定模型
|
||||
* @param array $matches 路由变量
|
||||
* @return void
|
||||
*/
|
||||
protected function createBindModel($bindModel, $matches)
|
||||
{
|
||||
foreach ($bindModel as $key => $val) {
|
||||
if ($val instanceof \Closure) {
|
||||
$result = $this->app->invokeFunction($val, $matches);
|
||||
} else {
|
||||
$fields = explode('&', $key);
|
||||
|
||||
if (is_array($val)) {
|
||||
list($model, $exception) = $val;
|
||||
} else {
|
||||
$model = $val;
|
||||
$exception = true;
|
||||
}
|
||||
|
||||
$where = [];
|
||||
$match = true;
|
||||
|
||||
foreach ($fields as $field) {
|
||||
if (!isset($matches[$field])) {
|
||||
$match = false;
|
||||
break;
|
||||
} else {
|
||||
$where[] = [$field, '=', $matches[$field]];
|
||||
}
|
||||
}
|
||||
|
||||
if ($match) {
|
||||
$query = strpos($model, '\\') ? $model::where($where) : $this->app->model($model)->where($where);
|
||||
$result = $query->failException($exception)->find();
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($result)) {
|
||||
// 注入容器
|
||||
$this->app->instance(get_class($result), $result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function convert($convert)
|
||||
{
|
||||
$this->convert = $convert;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDispatch()
|
||||
{
|
||||
return $this->dispatch;
|
||||
}
|
||||
|
||||
public function getParam()
|
||||
{
|
||||
return $this->param;
|
||||
}
|
||||
|
||||
abstract public function exec();
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
return ['rule', 'dispatch', 'convert', 'param', 'code', 'controller', 'actionName'];
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
$this->app = Container::get('app');
|
||||
$this->request = $this->app['request'];
|
||||
}
|
||||
|
||||
public function __debugInfo()
|
||||
{
|
||||
$data = get_object_vars($this);
|
||||
unset($data['app'], $data['request'], $data['rule']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
237
Server/thinkphp/library/think/route/Domain.php
Normal file
237
Server/thinkphp/library/think/route/Domain.php
Normal file
@@ -0,0 +1,237 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\route;
|
||||
|
||||
use think\Container;
|
||||
use think\Loader;
|
||||
use think\Request;
|
||||
use think\Route;
|
||||
use think\route\dispatch\Callback as CallbackDispatch;
|
||||
use think\route\dispatch\Controller as ControllerDispatch;
|
||||
use think\route\dispatch\Module as ModuleDispatch;
|
||||
|
||||
class Domain extends RuleGroup
|
||||
{
|
||||
/**
|
||||
* 架构函数
|
||||
* @access public
|
||||
* @param Route $router 路由对象
|
||||
* @param string $name 路由域名
|
||||
* @param mixed $rule 域名路由
|
||||
* @param array $option 路由参数
|
||||
* @param array $pattern 变量规则
|
||||
*/
|
||||
public function __construct(Route $router, $name = '', $rule = null, $option = [], $pattern = [])
|
||||
{
|
||||
$this->router = $router;
|
||||
$this->domain = $name;
|
||||
$this->option = $option;
|
||||
$this->rule = $rule;
|
||||
$this->pattern = $pattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测域名路由
|
||||
* @access public
|
||||
* @param Request $request 请求对象
|
||||
* @param string $url 访问地址
|
||||
* @param bool $completeMatch 路由是否完全匹配
|
||||
* @return Dispatch|false
|
||||
*/
|
||||
public function check($request, $url, $completeMatch = false)
|
||||
{
|
||||
// 检测别名路由
|
||||
$result = $this->checkRouteAlias($request, $url);
|
||||
|
||||
if (false !== $result) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
// 检测URL绑定
|
||||
$result = $this->checkUrlBind($request, $url);
|
||||
|
||||
if (!empty($this->option['append'])) {
|
||||
$request->setRouteVars($this->option['append']);
|
||||
unset($this->option['append']);
|
||||
}
|
||||
|
||||
if (false !== $result) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
// 添加域名中间件
|
||||
if (!empty($this->option['middleware'])) {
|
||||
Container::get('middleware')->import($this->option['middleware']);
|
||||
unset($this->option['middleware']);
|
||||
}
|
||||
|
||||
return parent::check($request, $url, $completeMatch);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置路由绑定
|
||||
* @access public
|
||||
* @param string $bind 绑定信息
|
||||
* @return $this
|
||||
*/
|
||||
public function bind($bind)
|
||||
{
|
||||
$this->router->bind($bind, $this->domain);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测路由别名
|
||||
* @access private
|
||||
* @param Request $request
|
||||
* @param string $url URL地址
|
||||
* @return Dispatch|false
|
||||
*/
|
||||
private function checkRouteAlias($request, $url)
|
||||
{
|
||||
$alias = strpos($url, '|') ? strstr($url, '|', true) : $url;
|
||||
|
||||
$item = $this->router->getAlias($alias);
|
||||
|
||||
return $item ? $item->check($request, $url) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测URL绑定
|
||||
* @access private
|
||||
* @param Request $request
|
||||
* @param string $url URL地址
|
||||
* @return Dispatch|false
|
||||
*/
|
||||
private function checkUrlBind($request, $url)
|
||||
{
|
||||
$bind = $this->router->getBind($this->domain);
|
||||
|
||||
if (!empty($bind)) {
|
||||
$this->parseBindAppendParam($bind);
|
||||
|
||||
// 记录绑定信息
|
||||
Container::get('app')->log('[ BIND ] ' . var_export($bind, true));
|
||||
|
||||
// 如果有URL绑定 则进行绑定检测
|
||||
$type = substr($bind, 0, 1);
|
||||
$bind = substr($bind, 1);
|
||||
|
||||
$bindTo = [
|
||||
'\\' => 'bindToClass',
|
||||
'@' => 'bindToController',
|
||||
':' => 'bindToNamespace',
|
||||
];
|
||||
|
||||
if (isset($bindTo[$type])) {
|
||||
return $this->{$bindTo[$type]}($request, $url, $bind);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function parseBindAppendParam(&$bind)
|
||||
{
|
||||
if (false !== strpos($bind, '?')) {
|
||||
list($bind, $query) = explode('?', $bind);
|
||||
parse_str($query, $vars);
|
||||
$this->append($vars);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定到类
|
||||
* @access protected
|
||||
* @param Request $request
|
||||
* @param string $url URL地址
|
||||
* @param string $class 类名(带命名空间)
|
||||
* @return CallbackDispatch
|
||||
*/
|
||||
protected function bindToClass($request, $url, $class)
|
||||
{
|
||||
$array = explode('|', $url, 2);
|
||||
$action = !empty($array[0]) ? $array[0] : $this->router->config('default_action');
|
||||
$param = [];
|
||||
|
||||
if (!empty($array[1])) {
|
||||
$this->parseUrlParams($request, $array[1], $param);
|
||||
}
|
||||
|
||||
return new CallbackDispatch($request, $this, [$class, $action], $param);
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定到命名空间
|
||||
* @access protected
|
||||
* @param Request $request
|
||||
* @param string $url URL地址
|
||||
* @param string $namespace 命名空间
|
||||
* @return CallbackDispatch
|
||||
*/
|
||||
protected function bindToNamespace($request, $url, $namespace)
|
||||
{
|
||||
$array = explode('|', $url, 3);
|
||||
$class = !empty($array[0]) ? $array[0] : $this->router->config('default_controller');
|
||||
$method = !empty($array[1]) ? $array[1] : $this->router->config('default_action');
|
||||
$param = [];
|
||||
|
||||
if (!empty($array[2])) {
|
||||
$this->parseUrlParams($request, $array[2], $param);
|
||||
}
|
||||
|
||||
return new CallbackDispatch($request, $this, [$namespace . '\\' . Loader::parseName($class, 1), $method], $param);
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定到控制器类
|
||||
* @access protected
|
||||
* @param Request $request
|
||||
* @param string $url URL地址
|
||||
* @param string $controller 控制器名 (支持带模块名 index/user )
|
||||
* @return ControllerDispatch
|
||||
*/
|
||||
protected function bindToController($request, $url, $controller)
|
||||
{
|
||||
$array = explode('|', $url, 2);
|
||||
$action = !empty($array[0]) ? $array[0] : $this->router->config('default_action');
|
||||
$param = [];
|
||||
|
||||
if (!empty($array[1])) {
|
||||
$this->parseUrlParams($request, $array[1], $param);
|
||||
}
|
||||
|
||||
return new ControllerDispatch($request, $this, $controller . '/' . $action, $param);
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定到模块/控制器
|
||||
* @access protected
|
||||
* @param Request $request
|
||||
* @param string $url URL地址
|
||||
* @param string $controller 控制器类名(带命名空间)
|
||||
* @return ModuleDispatch
|
||||
*/
|
||||
protected function bindToModule($request, $url, $controller)
|
||||
{
|
||||
$array = explode('|', $url, 2);
|
||||
$action = !empty($array[0]) ? $array[0] : $this->router->config('default_action');
|
||||
$param = [];
|
||||
|
||||
if (!empty($array[1])) {
|
||||
$this->parseUrlParams($request, $array[1], $param);
|
||||
}
|
||||
|
||||
return new ModuleDispatch($request, $this, $controller . '/' . $action, $param);
|
||||
}
|
||||
|
||||
}
|
||||
126
Server/thinkphp/library/think/route/Resource.php
Normal file
126
Server/thinkphp/library/think/route/Resource.php
Normal file
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\route;
|
||||
|
||||
use think\Route;
|
||||
|
||||
class Resource extends RuleGroup
|
||||
{
|
||||
// 资源路由名称
|
||||
protected $resource;
|
||||
|
||||
// REST路由方法定义
|
||||
protected $rest = [];
|
||||
|
||||
/**
|
||||
* 架构函数
|
||||
* @access public
|
||||
* @param Route $router 路由对象
|
||||
* @param RuleGroup $parent 上级对象
|
||||
* @param string $name 资源名称
|
||||
* @param string $route 路由地址
|
||||
* @param array $option 路由参数
|
||||
* @param array $pattern 变量规则
|
||||
* @param array $rest 资源定义
|
||||
*/
|
||||
public function __construct(Route $router, RuleGroup $parent = null, $name = '', $route = '', $option = [], $pattern = [], $rest = [])
|
||||
{
|
||||
$this->router = $router;
|
||||
$this->parent = $parent;
|
||||
$this->resource = $name;
|
||||
$this->route = $route;
|
||||
$this->name = strpos($name, '.') ? strstr($name, '.', true) : $name;
|
||||
|
||||
$this->setFullName();
|
||||
|
||||
// 资源路由默认为完整匹配
|
||||
$option['complete_match'] = true;
|
||||
|
||||
$this->pattern = $pattern;
|
||||
$this->option = $option;
|
||||
$this->rest = $rest;
|
||||
|
||||
if ($this->parent) {
|
||||
$this->domain = $this->parent->getDomain();
|
||||
$this->parent->addRuleItem($this);
|
||||
}
|
||||
|
||||
if ($router->isTest()) {
|
||||
$this->buildResourceRule();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成资源路由规则
|
||||
* @access protected
|
||||
* @return void
|
||||
*/
|
||||
protected function buildResourceRule()
|
||||
{
|
||||
$origin = $this->router->getGroup();
|
||||
$this->router->setGroup($this);
|
||||
|
||||
$rule = $this->resource;
|
||||
$option = $this->option;
|
||||
|
||||
if (strpos($rule, '.')) {
|
||||
// 注册嵌套资源路由
|
||||
$array = explode('.', $rule);
|
||||
$last = array_pop($array);
|
||||
$item = [];
|
||||
|
||||
foreach ($array as $val) {
|
||||
$item[] = $val . '/<' . (isset($option['var'][$val]) ? $option['var'][$val] : $val . '_id') . '>';
|
||||
}
|
||||
|
||||
$rule = implode('/', $item) . '/' . $last;
|
||||
}
|
||||
|
||||
$prefix = substr($rule, strlen($this->name) + 1);
|
||||
|
||||
// 注册资源路由
|
||||
foreach ($this->rest as $key => $val) {
|
||||
if ((isset($option['only']) && !in_array($key, $option['only']))
|
||||
|| (isset($option['except']) && in_array($key, $option['except']))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isset($last) && strpos($val[1], '<id>') && isset($option['var'][$last])) {
|
||||
$val[1] = str_replace('<id>', '<' . $option['var'][$last] . '>', $val[1]);
|
||||
} elseif (strpos($val[1], '<id>') && isset($option['var'][$rule])) {
|
||||
$val[1] = str_replace('<id>', '<' . $option['var'][$rule] . '>', $val[1]);
|
||||
}
|
||||
|
||||
$this->addRule(trim($prefix . $val[1], '/'), $this->route . '/' . $val[2], $val[0]);
|
||||
}
|
||||
|
||||
$this->router->setGroup($origin);
|
||||
}
|
||||
|
||||
/**
|
||||
* rest方法定义和修改
|
||||
* @access public
|
||||
* @param string $name 方法名称
|
||||
* @param array|bool $resource 资源
|
||||
* @return $this
|
||||
*/
|
||||
public function rest($name, $resource = [])
|
||||
{
|
||||
if (is_array($name)) {
|
||||
$this->rest = $resource ? $name : array_merge($this->rest, $name);
|
||||
} else {
|
||||
$this->rest[$name] = $resource;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
1130
Server/thinkphp/library/think/route/Rule.php
Normal file
1130
Server/thinkphp/library/think/route/Rule.php
Normal file
File diff suppressed because it is too large
Load Diff
601
Server/thinkphp/library/think/route/RuleGroup.php
Normal file
601
Server/thinkphp/library/think/route/RuleGroup.php
Normal file
@@ -0,0 +1,601 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\route;
|
||||
|
||||
use think\Container;
|
||||
use think\Exception;
|
||||
use think\Request;
|
||||
use think\Response;
|
||||
use think\Route;
|
||||
use think\route\dispatch\Response as ResponseDispatch;
|
||||
use think\route\dispatch\Url as UrlDispatch;
|
||||
|
||||
class RuleGroup extends Rule
|
||||
{
|
||||
// 分组路由(包括子分组)
|
||||
protected $rules = [
|
||||
'*' => [],
|
||||
'get' => [],
|
||||
'post' => [],
|
||||
'put' => [],
|
||||
'patch' => [],
|
||||
'delete' => [],
|
||||
'head' => [],
|
||||
'options' => [],
|
||||
];
|
||||
|
||||
// MISS路由
|
||||
protected $miss;
|
||||
|
||||
// 自动路由
|
||||
protected $auto;
|
||||
|
||||
// 完整名称
|
||||
protected $fullName;
|
||||
|
||||
// 所在域名
|
||||
protected $domain;
|
||||
|
||||
/**
|
||||
* 架构函数
|
||||
* @access public
|
||||
* @param Route $router 路由对象
|
||||
* @param RuleGroup $parent 上级对象
|
||||
* @param string $name 分组名称
|
||||
* @param mixed $rule 分组路由
|
||||
* @param array $option 路由参数
|
||||
* @param array $pattern 变量规则
|
||||
*/
|
||||
public function __construct(Route $router, RuleGroup $parent = null, $name = '', $rule = [], $option = [], $pattern = [])
|
||||
{
|
||||
$this->router = $router;
|
||||
$this->parent = $parent;
|
||||
$this->rule = $rule;
|
||||
$this->name = trim($name, '/');
|
||||
$this->option = $option;
|
||||
$this->pattern = $pattern;
|
||||
|
||||
$this->setFullName();
|
||||
|
||||
if ($this->parent) {
|
||||
$this->domain = $this->parent->getDomain();
|
||||
$this->parent->addRuleItem($this);
|
||||
}
|
||||
|
||||
if (!empty($option['cross_domain'])) {
|
||||
$this->router->setCrossDomainRule($this);
|
||||
}
|
||||
|
||||
if ($router->isTest()) {
|
||||
$this->lazy(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置分组的路由规则
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
protected function setFullName()
|
||||
{
|
||||
if (false !== strpos($this->name, ':')) {
|
||||
$this->name = preg_replace(['/\[\:(\w+)\]/', '/\:(\w+)/'], ['<\1?>', '<\1>'], $this->name);
|
||||
}
|
||||
|
||||
if ($this->parent && $this->parent->getFullName()) {
|
||||
$this->fullName = $this->parent->getFullName() . ($this->name ? '/' . $this->name : '');
|
||||
} else {
|
||||
$this->fullName = $this->name;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所属域名
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDomain()
|
||||
{
|
||||
return $this->domain;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测分组路由
|
||||
* @access public
|
||||
* @param Request $request 请求对象
|
||||
* @param string $url 访问地址
|
||||
* @param bool $completeMatch 路由是否完全匹配
|
||||
* @return Dispatch|false
|
||||
*/
|
||||
public function check($request, $url, $completeMatch = false)
|
||||
{
|
||||
// 跨域OPTIONS请求
|
||||
if ($dispatch = $this->checkCrossDomain($request)) {
|
||||
return $dispatch;
|
||||
}
|
||||
|
||||
// 检查分组有效性
|
||||
if (!$this->checkOption($this->option, $request) || !$this->checkUrl($url)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查前置行为
|
||||
if (isset($this->option['before'])) {
|
||||
if (false === $this->checkBefore($this->option['before'])) {
|
||||
return false;
|
||||
}
|
||||
unset($this->option['before']);
|
||||
}
|
||||
|
||||
// 解析分组路由
|
||||
if ($this instanceof Resource) {
|
||||
$this->buildResourceRule();
|
||||
} elseif ($this->rule) {
|
||||
if ($this->rule instanceof Response) {
|
||||
return new ResponseDispatch($request, $this, $this->rule);
|
||||
}
|
||||
|
||||
$this->parseGroupRule($this->rule);
|
||||
}
|
||||
|
||||
// 获取当前路由规则
|
||||
$method = strtolower($request->method());
|
||||
$rules = $this->getMethodRules($method);
|
||||
|
||||
if ($this->parent) {
|
||||
// 合并分组参数
|
||||
$this->mergeGroupOptions();
|
||||
// 合并分组变量规则
|
||||
$this->pattern = array_merge($this->parent->getPattern(), $this->pattern);
|
||||
}
|
||||
|
||||
if (isset($this->option['complete_match'])) {
|
||||
$completeMatch = $this->option['complete_match'];
|
||||
}
|
||||
|
||||
if (!empty($this->option['merge_rule_regex'])) {
|
||||
// 合并路由正则规则进行路由匹配检查
|
||||
$result = $this->checkMergeRuleRegex($request, $rules, $url, $completeMatch);
|
||||
|
||||
if (false !== $result) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
// 检查分组路由
|
||||
foreach ($rules as $key => $item) {
|
||||
$result = $item->check($request, $url, $completeMatch);
|
||||
|
||||
if (false !== $result) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->auto) {
|
||||
// 自动解析URL地址
|
||||
$result = new UrlDispatch($request, $this, $this->auto . '/' . $url, ['auto_search' => false]);
|
||||
} elseif ($this->miss && in_array($this->miss->getMethod(), ['*', $method])) {
|
||||
// 未匹配所有路由的路由规则处理
|
||||
$result = $this->miss->parseRule($request, '', $this->miss->getRoute(), $url, $this->miss->mergeGroupOptions());
|
||||
} else {
|
||||
$result = false;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前请求的路由规则(包括子分组、资源路由)
|
||||
* @access protected
|
||||
* @param string $method
|
||||
* @return array
|
||||
*/
|
||||
protected function getMethodRules($method)
|
||||
{
|
||||
return array_merge($this->rules[$method], $this->rules['*']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分组URL匹配检查
|
||||
* @access protected
|
||||
* @param string $url
|
||||
* @return bool
|
||||
*/
|
||||
protected function checkUrl($url)
|
||||
{
|
||||
if ($this->fullName) {
|
||||
$pos = strpos($this->fullName, '<');
|
||||
|
||||
if (false !== $pos) {
|
||||
$str = substr($this->fullName, 0, $pos);
|
||||
} else {
|
||||
$str = $this->fullName;
|
||||
}
|
||||
|
||||
if ($str && 0 !== stripos(str_replace('|', '/', $url), $str)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 延迟解析分组的路由规则
|
||||
* @access public
|
||||
* @param bool $lazy 路由是否延迟解析
|
||||
* @return $this
|
||||
*/
|
||||
public function lazy($lazy = true)
|
||||
{
|
||||
if (!$lazy) {
|
||||
$this->parseGroupRule($this->rule);
|
||||
$this->rule = null;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析分组和域名的路由规则及绑定
|
||||
* @access public
|
||||
* @param mixed $rule 路由规则
|
||||
* @return void
|
||||
*/
|
||||
public function parseGroupRule($rule)
|
||||
{
|
||||
$origin = $this->router->getGroup();
|
||||
$this->router->setGroup($this);
|
||||
|
||||
if ($rule instanceof \Closure) {
|
||||
Container::getInstance()->invokeFunction($rule);
|
||||
} elseif (is_array($rule)) {
|
||||
$this->addRules($rule);
|
||||
} elseif (is_string($rule) && $rule) {
|
||||
$this->router->bind($rule, $this->domain);
|
||||
}
|
||||
|
||||
$this->router->setGroup($origin);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测分组路由
|
||||
* @access public
|
||||
* @param Request $request 请求对象
|
||||
* @param array $rules 路由规则
|
||||
* @param string $url 访问地址
|
||||
* @param bool $completeMatch 路由是否完全匹配
|
||||
* @return Dispatch|false
|
||||
*/
|
||||
protected function checkMergeRuleRegex($request, &$rules, $url, $completeMatch)
|
||||
{
|
||||
$depr = $this->router->config('pathinfo_depr');
|
||||
$url = $depr . str_replace('|', $depr, $url);
|
||||
|
||||
foreach ($rules as $key => $item) {
|
||||
if ($item instanceof RuleItem) {
|
||||
$rule = $depr . str_replace('/', $depr, $item->getRule());
|
||||
if ($depr == $rule && $depr != $url) {
|
||||
unset($rules[$key]);
|
||||
continue;
|
||||
}
|
||||
|
||||
$complete = null !== $item->getOption('complete_match') ? $item->getOption('complete_match') : $completeMatch;
|
||||
|
||||
if (false === strpos($rule, '<')) {
|
||||
if (0 === strcasecmp($rule, $url) || (!$complete && 0 === strncasecmp($rule, $url, strlen($rule)))) {
|
||||
return $item->checkRule($request, $url, []);
|
||||
}
|
||||
|
||||
unset($rules[$key]);
|
||||
continue;
|
||||
}
|
||||
|
||||
$slash = preg_quote('/-' . $depr, '/');
|
||||
|
||||
if ($matchRule = preg_split('/[' . $slash . ']<\w+\??>/', $rule, 2)) {
|
||||
if ($matchRule[0] && 0 !== strncasecmp($rule, $url, strlen($matchRule[0]))) {
|
||||
unset($rules[$key]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (preg_match_all('/[' . $slash . ']?<?\w+\??>?/', $rule, $matches)) {
|
||||
unset($rules[$key]);
|
||||
$pattern = array_merge($this->getPattern(), $item->getPattern());
|
||||
$option = array_merge($this->getOption(), $item->getOption());
|
||||
|
||||
$regex[$key] = $this->buildRuleRegex($rule, $matches[0], $pattern, $option, $complete, '_THINK_' . $key);
|
||||
$items[$key] = $item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($regex)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
$result = preg_match('/^(?:' . implode('|', $regex) . ')/u', $url, $match);
|
||||
} catch (\Exception $e) {
|
||||
throw new Exception('route pattern error');
|
||||
}
|
||||
|
||||
if ($result) {
|
||||
$var = [];
|
||||
foreach ($match as $key => $val) {
|
||||
if (is_string($key) && '' !== $val) {
|
||||
list($name, $pos) = explode('_THINK_', $key);
|
||||
|
||||
$var[$name] = $val;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($pos)) {
|
||||
foreach ($regex as $key => $item) {
|
||||
if (0 === strpos(str_replace(['\/', '\-', '\\' . $depr], ['/', '-', $depr], $item), $match[0])) {
|
||||
$pos = $key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$rule = $items[$pos]->getRule();
|
||||
$array = $this->router->getRule($rule);
|
||||
|
||||
foreach ($array as $item) {
|
||||
if (in_array($item->getMethod(), ['*', strtolower($request->method())])) {
|
||||
$result = $item->checkRule($request, $url, $var);
|
||||
|
||||
if (false !== $result) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分组的MISS路由
|
||||
* @access public
|
||||
* @return RuleItem|null
|
||||
*/
|
||||
public function getMissRule()
|
||||
{
|
||||
return $this->miss;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分组的自动路由
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getAutoRule()
|
||||
{
|
||||
return $this->auto;
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册自动路由
|
||||
* @access public
|
||||
* @param string $route 路由规则
|
||||
* @return void
|
||||
*/
|
||||
public function addAutoRule($route)
|
||||
{
|
||||
$this->auto = $route;
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册MISS路由
|
||||
* @access public
|
||||
* @param string $route 路由地址
|
||||
* @param string $method 请求类型
|
||||
* @param array $option 路由参数
|
||||
* @return RuleItem
|
||||
*/
|
||||
public function addMissRule($route, $method = '*', $option = [])
|
||||
{
|
||||
// 创建路由规则实例
|
||||
$ruleItem = new RuleItem($this->router, $this, null, '', $route, strtolower($method), $option);
|
||||
|
||||
$this->miss = $ruleItem;
|
||||
|
||||
return $ruleItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加分组下的路由规则或者子分组
|
||||
* @access public
|
||||
* @param string $rule 路由规则
|
||||
* @param string $route 路由地址
|
||||
* @param string $method 请求类型
|
||||
* @param array $option 路由参数
|
||||
* @param array $pattern 变量规则
|
||||
* @return $this
|
||||
*/
|
||||
public function addRule($rule, $route, $method = '*', $option = [], $pattern = [])
|
||||
{
|
||||
// 读取路由标识
|
||||
if (is_array($rule)) {
|
||||
$name = $rule[0];
|
||||
$rule = $rule[1];
|
||||
} elseif (is_string($route)) {
|
||||
$name = $route;
|
||||
} else {
|
||||
$name = null;
|
||||
}
|
||||
|
||||
$method = strtolower($method);
|
||||
|
||||
if ('/' === $rule || '' === $rule) {
|
||||
// 首页自动完整匹配
|
||||
$rule .= '$';
|
||||
}
|
||||
|
||||
// 创建路由规则实例
|
||||
$ruleItem = new RuleItem($this->router, $this, $name, $rule, $route, $method, $option, $pattern);
|
||||
|
||||
if (!empty($option['cross_domain'])) {
|
||||
$this->router->setCrossDomainRule($ruleItem, $method);
|
||||
}
|
||||
|
||||
$this->addRuleItem($ruleItem, $method);
|
||||
|
||||
return $ruleItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量注册路由规则
|
||||
* @access public
|
||||
* @param array $rules 路由规则
|
||||
* @param string $method 请求类型
|
||||
* @param array $option 路由参数
|
||||
* @param array $pattern 变量规则
|
||||
* @return void
|
||||
*/
|
||||
public function addRules($rules, $method = '*', $option = [], $pattern = [])
|
||||
{
|
||||
foreach ($rules as $key => $val) {
|
||||
if (is_numeric($key)) {
|
||||
$key = array_shift($val);
|
||||
}
|
||||
|
||||
if (is_array($val)) {
|
||||
$route = array_shift($val);
|
||||
$option = $val ? array_shift($val) : [];
|
||||
$pattern = $val ? array_shift($val) : [];
|
||||
} else {
|
||||
$route = $val;
|
||||
}
|
||||
|
||||
$this->addRule($key, $route, $method, $option, $pattern);
|
||||
}
|
||||
}
|
||||
|
||||
public function addRuleItem($rule, $method = '*')
|
||||
{
|
||||
if (strpos($method, '|')) {
|
||||
$rule->method($method);
|
||||
$method = '*';
|
||||
}
|
||||
|
||||
$this->rules[$method][] = $rule;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置分组的路由前缀
|
||||
* @access public
|
||||
* @param string $prefix
|
||||
* @return $this
|
||||
*/
|
||||
public function prefix($prefix)
|
||||
{
|
||||
if ($this->parent && $this->parent->getOption('prefix')) {
|
||||
$prefix = $this->parent->getOption('prefix') . $prefix;
|
||||
}
|
||||
|
||||
return $this->option('prefix', $prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置资源允许
|
||||
* @access public
|
||||
* @param array $only
|
||||
* @return $this
|
||||
*/
|
||||
public function only($only)
|
||||
{
|
||||
return $this->option('only', $only);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置资源排除
|
||||
* @access public
|
||||
* @param array $except
|
||||
* @return $this
|
||||
*/
|
||||
public function except($except)
|
||||
{
|
||||
return $this->option('except', $except);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置资源路由的变量
|
||||
* @access public
|
||||
* @param array $vars
|
||||
* @return $this
|
||||
*/
|
||||
public function vars($vars)
|
||||
{
|
||||
return $this->option('var', $vars);
|
||||
}
|
||||
|
||||
/**
|
||||
* 合并分组的路由规则正则
|
||||
* @access public
|
||||
* @param bool $merge
|
||||
* @return $this
|
||||
*/
|
||||
public function mergeRuleRegex($merge = true)
|
||||
{
|
||||
return $this->option('merge_rule_regex', $merge);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取完整分组Name
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getFullName()
|
||||
{
|
||||
return $this->fullName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分组的路由规则
|
||||
* @access public
|
||||
* @param string $method
|
||||
* @return array
|
||||
*/
|
||||
public function getRules($method = '')
|
||||
{
|
||||
if ('' === $method) {
|
||||
return $this->rules;
|
||||
}
|
||||
|
||||
return isset($this->rules[strtolower($method)]) ? $this->rules[strtolower($method)] : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空分组下的路由规则
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$this->rules = [
|
||||
'*' => [],
|
||||
'get' => [],
|
||||
'post' => [],
|
||||
'put' => [],
|
||||
'patch' => [],
|
||||
'delete' => [],
|
||||
'head' => [],
|
||||
'options' => [],
|
||||
];
|
||||
}
|
||||
}
|
||||
292
Server/thinkphp/library/think/route/RuleItem.php
Normal file
292
Server/thinkphp/library/think/route/RuleItem.php
Normal file
@@ -0,0 +1,292 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\route;
|
||||
|
||||
use think\Container;
|
||||
use think\Exception;
|
||||
use think\Route;
|
||||
|
||||
class RuleItem extends Rule
|
||||
{
|
||||
protected $hasSetRule;
|
||||
|
||||
/**
|
||||
* 架构函数
|
||||
* @access public
|
||||
* @param Route $router 路由实例
|
||||
* @param RuleGroup $parent 上级对象
|
||||
* @param string $name 路由标识
|
||||
* @param string|array $rule 路由规则
|
||||
* @param string|\Closure $route 路由地址
|
||||
* @param string $method 请求类型
|
||||
* @param array $option 路由参数
|
||||
* @param array $pattern 变量规则
|
||||
*/
|
||||
public function __construct(Route $router, RuleGroup $parent, $name, $rule, $route, $method = '*', $option = [], $pattern = [])
|
||||
{
|
||||
$this->router = $router;
|
||||
$this->parent = $parent;
|
||||
$this->name = $name;
|
||||
$this->route = $route;
|
||||
$this->method = $method;
|
||||
$this->option = $option;
|
||||
$this->pattern = $pattern;
|
||||
|
||||
$this->setRule($rule);
|
||||
|
||||
if (!empty($option['cross_domain'])) {
|
||||
$this->router->setCrossDomainRule($this, $method);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 路由规则预处理
|
||||
* @access public
|
||||
* @param string $rule 路由规则
|
||||
* @return void
|
||||
*/
|
||||
public function setRule($rule)
|
||||
{
|
||||
if ('$' == substr($rule, -1, 1)) {
|
||||
// 是否完整匹配
|
||||
$rule = substr($rule, 0, -1);
|
||||
|
||||
$this->option['complete_match'] = true;
|
||||
}
|
||||
|
||||
$rule = '/' != $rule ? ltrim($rule, '/') : '';
|
||||
|
||||
if ($this->parent && $prefix = $this->parent->getFullName()) {
|
||||
$rule = $prefix . ($rule ? '/' . ltrim($rule, '/') : '');
|
||||
}
|
||||
|
||||
if (false !== strpos($rule, ':')) {
|
||||
$this->rule = preg_replace(['/\[\:(\w+)\]/', '/\:(\w+)/'], ['<\1?>', '<\1>'], $rule);
|
||||
} else {
|
||||
$this->rule = $rule;
|
||||
}
|
||||
|
||||
// 生成路由标识的快捷访问
|
||||
$this->setRuleName();
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查后缀
|
||||
* @access public
|
||||
* @param string $ext
|
||||
* @return $this
|
||||
*/
|
||||
public function ext($ext = '')
|
||||
{
|
||||
$this->option('ext', $ext);
|
||||
$this->setRuleName(true);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置别名
|
||||
* @access public
|
||||
* @param string $name
|
||||
* @return $this
|
||||
*/
|
||||
public function name($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->setRuleName(true);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置路由标识 用于URL反解生成
|
||||
* @access protected
|
||||
* @param bool $first 是否插入开头
|
||||
* @return void
|
||||
*/
|
||||
protected function setRuleName($first = false)
|
||||
{
|
||||
if ($this->name) {
|
||||
$vars = $this->parseVar($this->rule);
|
||||
$name = strtolower($this->name);
|
||||
|
||||
if (isset($this->option['ext'])) {
|
||||
$suffix = $this->option['ext'];
|
||||
} elseif ($this->parent->getOption('ext')) {
|
||||
$suffix = $this->parent->getOption('ext');
|
||||
} else {
|
||||
$suffix = null;
|
||||
}
|
||||
|
||||
$value = [$this->rule, $vars, $this->parent->getDomain(), $suffix, $this->method];
|
||||
|
||||
Container::get('rule_name')->set($name, $value, $first);
|
||||
}
|
||||
|
||||
if (!$this->hasSetRule) {
|
||||
Container::get('rule_name')->setRule($this->rule, $this);
|
||||
$this->hasSetRule = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测路由
|
||||
* @access public
|
||||
* @param Request $request 请求对象
|
||||
* @param string $url 访问地址
|
||||
* @param array $match 匹配路由变量
|
||||
* @param bool $completeMatch 路由是否完全匹配
|
||||
* @return Dispatch|false
|
||||
*/
|
||||
public function checkRule($request, $url, $match = null, $completeMatch = false)
|
||||
{
|
||||
// 检查参数有效性
|
||||
if (!$this->checkOption($this->option, $request)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 合并分组参数
|
||||
$option = $this->mergeGroupOptions();
|
||||
|
||||
$url = $this->urlSuffixCheck($request, $url, $option);
|
||||
|
||||
if (is_null($match)) {
|
||||
$match = $this->match($url, $option, $completeMatch);
|
||||
}
|
||||
|
||||
if (false !== $match) {
|
||||
if (!empty($option['cross_domain'])) {
|
||||
if ($dispatch = $this->checkCrossDomain($request)) {
|
||||
// 允许跨域
|
||||
return $dispatch;
|
||||
}
|
||||
|
||||
$option['header'] = $this->option['header'];
|
||||
}
|
||||
|
||||
// 检查前置行为
|
||||
if (isset($option['before']) && false === $this->checkBefore($option['before'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->parseRule($request, $this->rule, $this->route, $url, $option, $match);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测路由(含路由匹配)
|
||||
* @access public
|
||||
* @param Request $request 请求对象
|
||||
* @param string $url 访问地址
|
||||
* @param string $depr 路径分隔符
|
||||
* @param bool $completeMatch 路由是否完全匹配
|
||||
* @return Dispatch|false
|
||||
*/
|
||||
public function check($request, $url, $completeMatch = false)
|
||||
{
|
||||
return $this->checkRule($request, $url, null, $completeMatch);
|
||||
}
|
||||
|
||||
/**
|
||||
* URL后缀及Slash检查
|
||||
* @access protected
|
||||
* @param Request $request 请求对象
|
||||
* @param string $url 访问地址
|
||||
* @param array $option 路由参数
|
||||
* @return string
|
||||
*/
|
||||
protected function urlSuffixCheck($request, $url, $option = [])
|
||||
{
|
||||
// 是否区分 / 地址访问
|
||||
if (!empty($option['remove_slash']) && '/' != $this->rule) {
|
||||
$this->rule = rtrim($this->rule, '/');
|
||||
$url = rtrim($url, '|');
|
||||
}
|
||||
|
||||
if (isset($option['ext'])) {
|
||||
// 路由ext参数 优先于系统配置的URL伪静态后缀参数
|
||||
$url = preg_replace('/\.(' . $request->ext() . ')$/i', '', $url);
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测URL和规则路由是否匹配
|
||||
* @access private
|
||||
* @param string $url URL地址
|
||||
* @param array $option 路由参数
|
||||
* @param bool $completeMatch 路由是否完全匹配
|
||||
* @return array|false
|
||||
*/
|
||||
private function match($url, $option, $completeMatch)
|
||||
{
|
||||
if (isset($option['complete_match'])) {
|
||||
$completeMatch = $option['complete_match'];
|
||||
}
|
||||
|
||||
$pattern = array_merge($this->parent->getPattern(), $this->pattern);
|
||||
$depr = $this->router->config('pathinfo_depr');
|
||||
|
||||
// 检查完整规则定义
|
||||
if (isset($pattern['__url__']) && !preg_match(0 === strpos($pattern['__url__'], '/') ? $pattern['__url__'] : '/^' . $pattern['__url__'] . '/', str_replace('|', $depr, $url))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$var = [];
|
||||
$url = $depr . str_replace('|', $depr, $url);
|
||||
$rule = $depr . str_replace('/', $depr, $this->rule);
|
||||
|
||||
if ($depr == $rule && $depr != $url) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (false === strpos($rule, '<')) {
|
||||
if (0 === strcasecmp($rule, $url) || (!$completeMatch && 0 === strncasecmp($rule . $depr, $url . $depr, strlen($rule . $depr)))) {
|
||||
return $var;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
$slash = preg_quote('/-' . $depr, '/');
|
||||
|
||||
if ($matchRule = preg_split('/[' . $slash . ']?<\w+\??>/', $rule, 2)) {
|
||||
if ($matchRule[0] && 0 !== strncasecmp($rule, $url, strlen($matchRule[0]))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (preg_match_all('/[' . $slash . ']?<?\w+\??>?/', $rule, $matches)) {
|
||||
$regex = $this->buildRuleRegex($rule, $matches[0], $pattern, $option, $completeMatch);
|
||||
|
||||
try {
|
||||
if (!preg_match('/^' . $regex . ($completeMatch ? '$' : '') . '/u', $url, $match)) {
|
||||
return false;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
throw new Exception('route pattern error');
|
||||
}
|
||||
|
||||
foreach ($match as $key => $val) {
|
||||
if (is_string($key)) {
|
||||
$var[$key] = $val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 成功匹配后返回URL中的动态变量数组
|
||||
return $var;
|
||||
}
|
||||
|
||||
}
|
||||
147
Server/thinkphp/library/think/route/RuleName.php
Normal file
147
Server/thinkphp/library/think/route/RuleName.php
Normal file
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\route;
|
||||
|
||||
class RuleName
|
||||
{
|
||||
protected $item = [];
|
||||
protected $rule = [];
|
||||
|
||||
/**
|
||||
* 注册路由标识
|
||||
* @access public
|
||||
* @param string $name 路由标识
|
||||
* @param array $value 路由规则
|
||||
* @param bool $first 是否置顶
|
||||
* @return void
|
||||
*/
|
||||
public function set($name, $value, $first = false)
|
||||
{
|
||||
if ($first && isset($this->item[$name])) {
|
||||
array_unshift($this->item[$name], $value);
|
||||
} else {
|
||||
$this->item[$name][] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册路由规则
|
||||
* @access public
|
||||
* @param string $rule 路由规则
|
||||
* @param RuleItem $route 路由
|
||||
* @return void
|
||||
*/
|
||||
public function setRule($rule, $route)
|
||||
{
|
||||
$this->rule[$route->getDomain()][$rule][$route->getMethod()] = $route;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据路由规则获取路由对象(列表)
|
||||
* @access public
|
||||
* @param string $name 路由标识
|
||||
* @param string $domain 域名
|
||||
* @return array
|
||||
*/
|
||||
public function getRule($rule, $domain = null)
|
||||
{
|
||||
return isset($this->rule[$domain][$rule]) ? $this->rule[$domain][$rule] : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取全部路由列表
|
||||
* @access public
|
||||
* @param string $domain 域名
|
||||
* @return array
|
||||
*/
|
||||
public function getRuleList($domain = null)
|
||||
{
|
||||
$list = [];
|
||||
|
||||
foreach ($this->rule as $ruleDomain => $rules) {
|
||||
foreach ($rules as $rule => $items) {
|
||||
foreach ($items as $item) {
|
||||
$val['domain'] = $ruleDomain;
|
||||
|
||||
foreach (['method', 'rule', 'name', 'route', 'pattern', 'option'] as $param) {
|
||||
$call = 'get' . $param;
|
||||
$val[$param] = $item->$call();
|
||||
}
|
||||
|
||||
$list[$ruleDomain][] = $val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($domain) {
|
||||
return isset($list[$domain]) ? $list[$domain] : [];
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 导入路由标识
|
||||
* @access public
|
||||
* @param array $name 路由标识
|
||||
* @return void
|
||||
*/
|
||||
public function import($item)
|
||||
{
|
||||
$this->item = $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据路由标识获取路由信息(用于URL生成)
|
||||
* @access public
|
||||
* @param string $name 路由标识
|
||||
* @param string $domain 域名
|
||||
* @return array|null
|
||||
*/
|
||||
public function get($name = null, $domain = null, $method = '*')
|
||||
{
|
||||
if (is_null($name)) {
|
||||
return $this->item;
|
||||
}
|
||||
|
||||
$name = strtolower($name);
|
||||
$method = strtolower($method);
|
||||
|
||||
if (isset($this->item[$name])) {
|
||||
if (is_null($domain)) {
|
||||
$result = $this->item[$name];
|
||||
} else {
|
||||
$result = [];
|
||||
foreach ($this->item[$name] as $item) {
|
||||
if ($item[2] == $domain && ('*' == $item[4] || $method == $item[4])) {
|
||||
$result[] = $item;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$result = null;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空路由规则
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$this->item = [];
|
||||
$this->rule = [];
|
||||
}
|
||||
}
|
||||
26
Server/thinkphp/library/think/route/dispatch/Callback.php
Normal file
26
Server/thinkphp/library/think/route/dispatch/Callback.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\route\dispatch;
|
||||
|
||||
use think\route\Dispatch;
|
||||
|
||||
class Callback extends Dispatch
|
||||
{
|
||||
public function exec()
|
||||
{
|
||||
// 执行回调方法
|
||||
$vars = array_merge($this->request->param(), $this->param);
|
||||
|
||||
return $this->app->invoke($this->dispatch, $vars);
|
||||
}
|
||||
|
||||
}
|
||||
30
Server/thinkphp/library/think/route/dispatch/Controller.php
Normal file
30
Server/thinkphp/library/think/route/dispatch/Controller.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\route\dispatch;
|
||||
|
||||
use think\route\Dispatch;
|
||||
|
||||
class Controller extends Dispatch
|
||||
{
|
||||
public function exec()
|
||||
{
|
||||
// 执行控制器的操作方法
|
||||
$vars = array_merge($this->request->param(), $this->param);
|
||||
|
||||
return $this->app->action(
|
||||
$this->dispatch, $vars,
|
||||
$this->rule->getConfig('url_controller_layer'),
|
||||
$this->rule->getConfig('controller_suffix')
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
138
Server/thinkphp/library/think/route/dispatch/Module.php
Normal file
138
Server/thinkphp/library/think/route/dispatch/Module.php
Normal file
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\route\dispatch;
|
||||
|
||||
use ReflectionMethod;
|
||||
use think\exception\ClassNotFoundException;
|
||||
use think\exception\HttpException;
|
||||
use think\Loader;
|
||||
use think\Request;
|
||||
use think\route\Dispatch;
|
||||
|
||||
class Module extends Dispatch
|
||||
{
|
||||
protected $controller;
|
||||
protected $actionName;
|
||||
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
|
||||
$result = $this->dispatch;
|
||||
|
||||
if (is_string($result)) {
|
||||
$result = explode('/', $result);
|
||||
}
|
||||
|
||||
if ($this->rule->getConfig('app_multi_module')) {
|
||||
// 多模块部署
|
||||
$module = strip_tags(strtolower($result[0] ?: $this->rule->getConfig('default_module')));
|
||||
$bind = $this->rule->getRouter()->getBind();
|
||||
$available = false;
|
||||
|
||||
if ($bind && preg_match('/^[a-z]/is', $bind)) {
|
||||
// 绑定模块
|
||||
list($bindModule) = explode('/', $bind);
|
||||
if (empty($result[0])) {
|
||||
$module = $bindModule;
|
||||
}
|
||||
$available = true;
|
||||
} elseif (!in_array($module, $this->rule->getConfig('deny_module_list')) && is_dir($this->app->getAppPath() . $module)) {
|
||||
$available = true;
|
||||
} elseif ($this->rule->getConfig('empty_module')) {
|
||||
$module = $this->rule->getConfig('empty_module');
|
||||
$available = true;
|
||||
}
|
||||
|
||||
// 模块初始化
|
||||
if ($module && $available) {
|
||||
// 初始化模块
|
||||
$this->request->setModule($module);
|
||||
$this->app->init($module);
|
||||
} else {
|
||||
throw new HttpException(404, 'module not exists:' . $module);
|
||||
}
|
||||
}
|
||||
|
||||
// 是否自动转换控制器和操作名
|
||||
$convert = is_bool($this->convert) ? $this->convert : $this->rule->getConfig('url_convert');
|
||||
// 获取控制器名
|
||||
$controller = strip_tags($result[1] ?: $this->rule->getConfig('default_controller'));
|
||||
|
||||
$this->controller = $convert ? strtolower($controller) : $controller;
|
||||
|
||||
// 获取操作名
|
||||
$this->actionName = strip_tags($result[2] ?: $this->rule->getConfig('default_action'));
|
||||
|
||||
// 设置当前请求的控制器、操作
|
||||
$this->request
|
||||
->setController(Loader::parseName($this->controller, 1))
|
||||
->setAction($this->actionName);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function exec()
|
||||
{
|
||||
// 监听module_init
|
||||
$this->app['hook']->listen('module_init');
|
||||
|
||||
try {
|
||||
// 实例化控制器
|
||||
$instance = $this->app->controller($this->controller,
|
||||
$this->rule->getConfig('url_controller_layer'),
|
||||
$this->rule->getConfig('controller_suffix'),
|
||||
$this->rule->getConfig('empty_controller'));
|
||||
} catch (ClassNotFoundException $e) {
|
||||
throw new HttpException(404, 'controller not exists:' . $e->getClass());
|
||||
}
|
||||
|
||||
$this->app['middleware']->controller(function (Request $request, $next) use ($instance) {
|
||||
// 获取当前操作名
|
||||
$action = $this->actionName . $this->rule->getConfig('action_suffix');
|
||||
|
||||
if (is_callable([$instance, $action])) {
|
||||
// 执行操作方法
|
||||
$call = [$instance, $action];
|
||||
|
||||
// 严格获取当前操作方法名
|
||||
$reflect = new ReflectionMethod($instance, $action);
|
||||
$methodName = $reflect->getName();
|
||||
$suffix = $this->rule->getConfig('action_suffix');
|
||||
$actionName = $suffix ? substr($methodName, 0, -strlen($suffix)) : $methodName;
|
||||
$this->request->setAction($actionName);
|
||||
|
||||
// 自动获取请求变量
|
||||
$vars = $this->rule->getConfig('url_param_type')
|
||||
? $this->request->route()
|
||||
: $this->request->param();
|
||||
$vars = array_merge($vars, $this->param);
|
||||
} elseif (is_callable([$instance, '_empty'])) {
|
||||
// 空操作
|
||||
$call = [$instance, '_empty'];
|
||||
$vars = [$this->actionName];
|
||||
$reflect = new ReflectionMethod($instance, '_empty');
|
||||
} else {
|
||||
// 操作不存在
|
||||
throw new HttpException(404, 'method not exists:' . get_class($instance) . '->' . $action . '()');
|
||||
}
|
||||
|
||||
$this->app['hook']->listen('action_begin', $call);
|
||||
|
||||
$data = $this->app->invokeReflectMethod($instance, $reflect, $vars);
|
||||
|
||||
return $this->autoResponse($data);
|
||||
});
|
||||
|
||||
return $this->app['middleware']->dispatch($this->request, 'controller');
|
||||
}
|
||||
}
|
||||
23
Server/thinkphp/library/think/route/dispatch/Redirect.php
Normal file
23
Server/thinkphp/library/think/route/dispatch/Redirect.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\route\dispatch;
|
||||
|
||||
use think\Response;
|
||||
use think\route\Dispatch;
|
||||
|
||||
class Redirect extends Dispatch
|
||||
{
|
||||
public function exec()
|
||||
{
|
||||
return Response::create($this->dispatch, 'redirect')->code($this->code);
|
||||
}
|
||||
}
|
||||
23
Server/thinkphp/library/think/route/dispatch/Response.php
Normal file
23
Server/thinkphp/library/think/route/dispatch/Response.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\route\dispatch;
|
||||
|
||||
use think\route\Dispatch;
|
||||
|
||||
class Response extends Dispatch
|
||||
{
|
||||
public function exec()
|
||||
{
|
||||
return $this->dispatch;
|
||||
}
|
||||
|
||||
}
|
||||
169
Server/thinkphp/library/think/route/dispatch/Url.php
Normal file
169
Server/thinkphp/library/think/route/dispatch/Url.php
Normal file
@@ -0,0 +1,169 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\route\dispatch;
|
||||
|
||||
use think\exception\HttpException;
|
||||
use think\Loader;
|
||||
use think\route\Dispatch;
|
||||
|
||||
class Url extends Dispatch
|
||||
{
|
||||
public function init()
|
||||
{
|
||||
// 解析默认的URL规则
|
||||
$result = $this->parseUrl($this->dispatch);
|
||||
|
||||
return (new Module($this->request, $this->rule, $result))->init();
|
||||
}
|
||||
|
||||
public function exec()
|
||||
{}
|
||||
|
||||
/**
|
||||
* 解析URL地址
|
||||
* @access protected
|
||||
* @param string $url URL
|
||||
* @return array
|
||||
*/
|
||||
protected function parseUrl($url)
|
||||
{
|
||||
$depr = $this->rule->getConfig('pathinfo_depr');
|
||||
$bind = $this->rule->getRouter()->getBind();
|
||||
|
||||
if (!empty($bind) && preg_match('/^[a-z]/is', $bind)) {
|
||||
$bind = str_replace('/', $depr, $bind);
|
||||
// 如果有模块/控制器绑定
|
||||
$url = $bind . ('.' != substr($bind, -1) ? $depr : '') . ltrim($url, $depr);
|
||||
}
|
||||
|
||||
list($path, $var) = $this->rule->parseUrlPath($url);
|
||||
if (empty($path)) {
|
||||
return [null, null, null];
|
||||
}
|
||||
|
||||
// 解析模块
|
||||
$module = $this->rule->getConfig('app_multi_module') ? array_shift($path) : null;
|
||||
|
||||
if ($this->param['auto_search']) {
|
||||
$controller = $this->autoFindController($module, $path);
|
||||
} else {
|
||||
// 解析控制器
|
||||
$controller = !empty($path) ? array_shift($path) : null;
|
||||
}
|
||||
|
||||
if ($controller && !preg_match('/^[A-Za-z0-9][\w|\.]*$/', $controller)) {
|
||||
throw new HttpException(404, 'controller not exists:' . $controller);
|
||||
}
|
||||
|
||||
// 解析操作
|
||||
$action = !empty($path) ? array_shift($path) : null;
|
||||
|
||||
// 解析额外参数
|
||||
if ($path) {
|
||||
if ($this->rule->getConfig('url_param_type')) {
|
||||
$var += $path;
|
||||
} else {
|
||||
preg_replace_callback('/(\w+)\|([^\|]+)/', function ($match) use (&$var) {
|
||||
$var[$match[1]] = strip_tags($match[2]);
|
||||
}, implode('|', $path));
|
||||
}
|
||||
}
|
||||
|
||||
$panDomain = $this->request->panDomain();
|
||||
|
||||
if ($panDomain && $key = array_search('*', $var)) {
|
||||
// 泛域名赋值
|
||||
$var[$key] = $panDomain;
|
||||
}
|
||||
|
||||
// 设置当前请求的参数
|
||||
$this->request->setRouteVars($var);
|
||||
|
||||
// 封装路由
|
||||
$route = [$module, $controller, $action];
|
||||
|
||||
if ($this->hasDefinedRoute($route, $bind)) {
|
||||
throw new HttpException(404, 'invalid request:' . str_replace('|', $depr, $url));
|
||||
}
|
||||
|
||||
return $route;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查URL是否已经定义过路由
|
||||
* @access protected
|
||||
* @param string $route 路由信息
|
||||
* @param string $bind 绑定信息
|
||||
* @return bool
|
||||
*/
|
||||
protected function hasDefinedRoute($route, $bind)
|
||||
{
|
||||
list($module, $controller, $action) = $route;
|
||||
|
||||
// 检查地址是否被定义过路由
|
||||
$name = strtolower($module . '/' . Loader::parseName($controller, 1) . '/' . $action);
|
||||
|
||||
$name2 = '';
|
||||
|
||||
if (empty($module) || $module == $bind) {
|
||||
$name2 = strtolower(Loader::parseName($controller, 1) . '/' . $action);
|
||||
}
|
||||
|
||||
$host = $this->request->host(true);
|
||||
|
||||
$method = $this->request->method();
|
||||
|
||||
if ($this->rule->getRouter()->getName($name, $host, $method) || $this->rule->getRouter()->getName($name2, $host, $method)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动定位控制器类
|
||||
* @access protected
|
||||
* @param string $module 模块名
|
||||
* @param array $path URL
|
||||
* @return string
|
||||
*/
|
||||
protected function autoFindController($module, &$path)
|
||||
{
|
||||
$dir = $this->app->getAppPath() . ($module ? $module . '/' : '') . $this->rule->getConfig('url_controller_layer');
|
||||
$suffix = $this->app->getSuffix() || $this->rule->getConfig('controller_suffix') ? ucfirst($this->rule->getConfig('url_controller_layer')) : '';
|
||||
|
||||
$item = [];
|
||||
$find = false;
|
||||
|
||||
foreach ($path as $val) {
|
||||
$item[] = $val;
|
||||
$file = $dir . '/' . str_replace('.', '/', $val) . $suffix . '.php';
|
||||
$file = pathinfo($file, PATHINFO_DIRNAME) . '/' . Loader::parseName(pathinfo($file, PATHINFO_FILENAME), 1) . '.php';
|
||||
if (is_file($file)) {
|
||||
$find = true;
|
||||
break;
|
||||
} else {
|
||||
$dir .= '/' . Loader::parseName($val);
|
||||
}
|
||||
}
|
||||
|
||||
if ($find) {
|
||||
$controller = implode('.', $item);
|
||||
$path = array_slice($path, count($item));
|
||||
} else {
|
||||
$controller = array_shift($path);
|
||||
}
|
||||
|
||||
return $controller;
|
||||
}
|
||||
|
||||
}
|
||||
26
Server/thinkphp/library/think/route/dispatch/View.php
Normal file
26
Server/thinkphp/library/think/route/dispatch/View.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\route\dispatch;
|
||||
|
||||
use think\Response;
|
||||
use think\route\Dispatch;
|
||||
|
||||
class View extends Dispatch
|
||||
{
|
||||
public function exec()
|
||||
{
|
||||
// 渲染模板输出
|
||||
$vars = array_merge($this->request->param(), $this->param);
|
||||
|
||||
return Response::create($this->dispatch, 'view')->assign($vars);
|
||||
}
|
||||
}
|
||||
171
Server/thinkphp/library/think/validate/ValidateRule.php
Normal file
171
Server/thinkphp/library/think/validate/ValidateRule.php
Normal file
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\validate;
|
||||
|
||||
/**
|
||||
* Class ValidateRule
|
||||
* @package think\validate
|
||||
* @method ValidateRule confirm(mixed $rule, string $msg = '') static 验证是否和某个字段的值一致
|
||||
* @method ValidateRule different(mixed $rule, string $msg = '') static 验证是否和某个字段的值是否不同
|
||||
* @method ValidateRule egt(mixed $rule, string $msg = '') static 验证是否大于等于某个值
|
||||
* @method ValidateRule gt(mixed $rule, string $msg = '') static 验证是否大于某个值
|
||||
* @method ValidateRule elt(mixed $rule, string $msg = '') static 验证是否小于等于某个值
|
||||
* @method ValidateRule lt(mixed $rule, string $msg = '') static 验证是否小于某个值
|
||||
* @method ValidateRule eg(mixed $rule, string $msg = '') static 验证是否等于某个值
|
||||
* @method ValidateRule in(mixed $rule, string $msg = '') static 验证是否在范围内
|
||||
* @method ValidateRule notIn(mixed $rule, string $msg = '') static 验证是否不在某个范围
|
||||
* @method ValidateRule between(mixed $rule, string $msg = '') static 验证是否在某个区间
|
||||
* @method ValidateRule notBetween(mixed $rule, string $msg = '') static 验证是否不在某个区间
|
||||
* @method ValidateRule length(mixed $rule, string $msg = '') static 验证数据长度
|
||||
* @method ValidateRule max(mixed $rule, string $msg = '') static 验证数据最大长度
|
||||
* @method ValidateRule min(mixed $rule, string $msg = '') static 验证数据最小长度
|
||||
* @method ValidateRule after(mixed $rule, string $msg = '') static 验证日期
|
||||
* @method ValidateRule before(mixed $rule, string $msg = '') static 验证日期
|
||||
* @method ValidateRule expire(mixed $rule, string $msg = '') static 验证有效期
|
||||
* @method ValidateRule allowIp(mixed $rule, string $msg = '') static 验证IP许可
|
||||
* @method ValidateRule denyIp(mixed $rule, string $msg = '') static 验证IP禁用
|
||||
* @method ValidateRule regex(mixed $rule, string $msg = '') static 使用正则验证数据
|
||||
* @method ValidateRule token(mixed $rule='__token__', string $msg = '') static 验证表单令牌
|
||||
* @method ValidateRule is(mixed $rule, string $msg = '') static 验证字段值是否为有效格式
|
||||
* @method ValidateRule isRequire(mixed $rule = null, string $msg = '') static 验证字段必须
|
||||
* @method ValidateRule isNumber(mixed $rule = null, string $msg = '') static 验证字段值是否为数字
|
||||
* @method ValidateRule isArray(mixed $rule = null, string $msg = '') static 验证字段值是否为数组
|
||||
* @method ValidateRule isInteger(mixed $rule = null, string $msg = '') static 验证字段值是否为整形
|
||||
* @method ValidateRule isFloat(mixed $rule = null, string $msg = '') static 验证字段值是否为浮点数
|
||||
* @method ValidateRule isMobile(mixed $rule = null, string $msg = '') static 验证字段值是否为手机
|
||||
* @method ValidateRule isIdCard(mixed $rule = null, string $msg = '') static 验证字段值是否为身份证号码
|
||||
* @method ValidateRule isChs(mixed $rule = null, string $msg = '') static 验证字段值是否为中文
|
||||
* @method ValidateRule isChsDash(mixed $rule = null, string $msg = '') static 验证字段值是否为中文字母及下划线
|
||||
* @method ValidateRule isChsAlpha(mixed $rule = null, string $msg = '') static 验证字段值是否为中文和字母
|
||||
* @method ValidateRule isChsAlphaNum(mixed $rule = null, string $msg = '') static 验证字段值是否为中文字母和数字
|
||||
* @method ValidateRule isDate(mixed $rule = null, string $msg = '') static 验证字段值是否为有效格式
|
||||
* @method ValidateRule isBool(mixed $rule = null, string $msg = '') static 验证字段值是否为布尔值
|
||||
* @method ValidateRule isAlpha(mixed $rule = null, string $msg = '') static 验证字段值是否为字母
|
||||
* @method ValidateRule isAlphaDash(mixed $rule = null, string $msg = '') static 验证字段值是否为字母和下划线
|
||||
* @method ValidateRule isAlphaNum(mixed $rule = null, string $msg = '') static 验证字段值是否为字母和数字
|
||||
* @method ValidateRule isAccepted(mixed $rule = null, string $msg = '') static 验证字段值是否为yes, on, 或是 1
|
||||
* @method ValidateRule isEmail(mixed $rule = null, string $msg = '') static 验证字段值是否为有效邮箱格式
|
||||
* @method ValidateRule isUrl(mixed $rule = null, string $msg = '') static 验证字段值是否为有效URL地址
|
||||
* @method ValidateRule activeUrl(mixed $rule, string $msg = '') static 验证是否为合格的域名或者IP
|
||||
* @method ValidateRule ip(mixed $rule, string $msg = '') static 验证是否有效IP
|
||||
* @method ValidateRule fileExt(mixed $rule, string $msg = '') static 验证文件后缀
|
||||
* @method ValidateRule fileMime(mixed $rule, string $msg = '') static 验证文件类型
|
||||
* @method ValidateRule fileSize(mixed $rule, string $msg = '') static 验证文件大小
|
||||
* @method ValidateRule image(mixed $rule, string $msg = '') static 验证图像文件
|
||||
* @method ValidateRule method(mixed $rule, string $msg = '') static 验证请求类型
|
||||
* @method ValidateRule dateFormat(mixed $rule, string $msg = '') static 验证时间和日期是否符合指定格式
|
||||
* @method ValidateRule unique(mixed $rule, string $msg = '') static 验证是否唯一
|
||||
* @method ValidateRule behavior(mixed $rule, string $msg = '') static 使用行为类验证
|
||||
* @method ValidateRule filter(mixed $rule, string $msg = '') static 使用filter_var方式验证
|
||||
* @method ValidateRule requireIf(mixed $rule, string $msg = '') static 验证某个字段等于某个值的时候必须
|
||||
* @method ValidateRule requireCallback(mixed $rule, string $msg = '') static 通过回调方法验证某个字段是否必须
|
||||
* @method ValidateRule requireWith(mixed $rule, string $msg = '') static 验证某个字段有值的情况下必须
|
||||
* @method ValidateRule must(mixed $rule = null, string $msg = '') static 必须验证
|
||||
*/
|
||||
class ValidateRule
|
||||
{
|
||||
// 验证字段的名称
|
||||
protected $title;
|
||||
|
||||
// 当前验证规则
|
||||
protected $rule = [];
|
||||
|
||||
// 验证提示信息
|
||||
protected $message = [];
|
||||
|
||||
/**
|
||||
* 添加验证因子
|
||||
* @access protected
|
||||
* @param string $name 验证名称
|
||||
* @param mixed $rule 验证规则
|
||||
* @param string $msg 提示信息
|
||||
* @return $this
|
||||
*/
|
||||
protected function addItem($name, $rule = null, $msg = '')
|
||||
{
|
||||
if ($rule || 0 === $rule) {
|
||||
$this->rule[$name] = $rule;
|
||||
} else {
|
||||
$this->rule[] = $name;
|
||||
}
|
||||
|
||||
$this->message[] = $msg;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取验证规则
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getRule()
|
||||
{
|
||||
return $this->rule;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取验证字段名称
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取验证提示
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getMsg()
|
||||
{
|
||||
return $this->message;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置验证字段名称
|
||||
* @access public
|
||||
* @return $this
|
||||
*/
|
||||
public function title($title)
|
||||
{
|
||||
$this->title = $title;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function __call($method, $args)
|
||||
{
|
||||
if ('is' == strtolower(substr($method, 0, 2))) {
|
||||
$method = substr($method, 2);
|
||||
}
|
||||
|
||||
array_unshift($args, lcfirst($method));
|
||||
|
||||
return call_user_func_array([$this, 'addItem'], $args);
|
||||
}
|
||||
|
||||
public static function __callStatic($method, $args)
|
||||
{
|
||||
$rule = new static();
|
||||
|
||||
if ('is' == strtolower(substr($method, 0, 2))) {
|
||||
$method = substr($method, 2);
|
||||
}
|
||||
|
||||
array_unshift($args, lcfirst($method));
|
||||
|
||||
return call_user_func_array([$rule, 'addItem'], $args);
|
||||
}
|
||||
}
|
||||
41
Server/thinkphp/phpunit.xml.dist
Normal file
41
Server/thinkphp/phpunit.xml.dist
Normal file
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
|
||||
backupGlobals="false"
|
||||
colors="true"
|
||||
bootstrap="./base.php"
|
||||
failOnRisky="true"
|
||||
failOnWarning="true"
|
||||
>
|
||||
<php>
|
||||
<ini name="error_reporting" value="-1" />
|
||||
<ini name="intl.default_locale" value="en" />
|
||||
<ini name="intl.error_level" value="0" />
|
||||
<ini name="memory_limit" value="-1" />
|
||||
<env name="DUMP_LIGHT_ARRAY" value="" />
|
||||
<env name="DUMP_STRING_LENGTH" value="" />
|
||||
<env name="LDAP_HOST" value="127.0.0.1" />
|
||||
<env name="LDAP_PORT" value="3389" />
|
||||
<env name="REDIS_HOST" value="localhost" />
|
||||
<env name="MEMCACHED_HOST" value="localhost" />
|
||||
</php>
|
||||
|
||||
<testsuites>
|
||||
<testsuite name="ThinkPHP Test Suite">
|
||||
<directory>./library/think/*/tests/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory>./library/</directory>
|
||||
<exclude>
|
||||
<directory>./library/think/*/tests</directory>
|
||||
<directory>./library/think/*/assets</directory>
|
||||
<directory>./library/think/*/resources</directory>
|
||||
<directory>./library/think/*/vendor</directory>
|
||||
</exclude>
|
||||
</whitelist>
|
||||
</filter>
|
||||
</phpunit>
|
||||
@@ -23,3 +23,28 @@
|
||||
[运行时间:0.008414s] [吞吐率:118.85req/s] [内存消耗:441.96kb] [文件加载:17]
|
||||
[ error ] [0]Fatal error: Class 'think\Container' not found[E:\WorkSpace\Maokaka\Server\public\index.php:33]
|
||||
[ info ] [ LOG ] INIT File
|
||||
---------------------------------------------------------------
|
||||
[ 2025-07-07T12:25:29+08:00 ] 127.0.0.1 GET www.yishi.com/
|
||||
[运行时间:0.013366s] [吞吐率:74.82req/s] [内存消耗:23.02kb] [文件加载:17]
|
||||
[ error ] [0]Fatal error: Class 'think\Container' not found[E:\WorkSpace\Maokaka\Server\public\index.php:33]
|
||||
[ info ] [ LOG ] INIT File
|
||||
---------------------------------------------------------------
|
||||
[ 2025-07-07T12:26:30+08:00 ] 127.0.0.1 GET www.yishi.com/
|
||||
[运行时间:0.014007s] [吞吐率:71.39req/s] [内存消耗:23.02kb] [文件加载:17]
|
||||
[ error ] [0]Fatal error: Class 'think\Container' not found[E:\WorkSpace\Maokaka\Server\public\index.php:33]
|
||||
[ info ] [ LOG ] INIT File
|
||||
---------------------------------------------------------------
|
||||
[ 2025-07-07T12:27:25+08:00 ] 127.0.0.1 GET www.yishi.com/
|
||||
[运行时间:0.013642s] [吞吐率:73.30req/s] [内存消耗:23.02kb] [文件加载:17]
|
||||
[ error ] [0]Fatal error: Class 'think\Container' not found[E:\WorkSpace\Maokaka\Server\public\index.php:33]
|
||||
[ info ] [ LOG ] INIT File
|
||||
---------------------------------------------------------------
|
||||
[ 2025-07-07T12:27:26+08:00 ] 127.0.0.1 GET www.yishi.com/
|
||||
[运行时间:0.004214s] [吞吐率:237.30req/s] [内存消耗:20.68kb] [文件加载:18]
|
||||
[ error ] [0]Fatal error: Class 'think\Container' not found[E:\WorkSpace\Maokaka\Server\public\index.php:33]
|
||||
[ info ] [ LOG ] INIT File
|
||||
---------------------------------------------------------------
|
||||
[ 2025-07-07T12:31:39+08:00 ] 127.0.0.1 GET www.yishi.com/
|
||||
[运行时间:0.014264s] [吞吐率:70.11req/s] [内存消耗:23.02kb] [文件加载:17]
|
||||
[ error ] [0]Fatal error: Class 'think\Container' not found[E:\WorkSpace\Maokaka\Server\public\index.php:33]
|
||||
[ info ] [ LOG ] INIT File
|
||||
|
||||
Reference in New Issue
Block a user