内核更新,标签的更新
This commit is contained in:
@@ -11,49 +11,50 @@
|
||||
|
||||
// 核心中文语言包
|
||||
return [
|
||||
// 系统错误提示
|
||||
'Undefined variable' => '未定义变量',
|
||||
'Undefined index' => '未定义索引',
|
||||
'Parse error' => '语法解析错误',
|
||||
'Type error' => '类型错误',
|
||||
'Fatal error' => '致命错误',
|
||||
// 系统错误提示
|
||||
'Undefined variable' => '未定义变量',
|
||||
'Undefined index' => '未定义索引',
|
||||
'Parse error' => '语法解析错误',
|
||||
'Type error' => '类型错误',
|
||||
'Fatal error' => '致命错误',
|
||||
|
||||
// 框架核心错误提示
|
||||
'dispatch type not support' => '不支持的调度类型',
|
||||
'method param miss' => '方法参数错误',
|
||||
'method not exists' => '方法不存在',
|
||||
'module not exists' => '模块不存在',
|
||||
'class not exists' => '类不存在',
|
||||
'template not exists' => '模板文件不存在',
|
||||
'illegal controller name' => '非法的控制器名称',
|
||||
'illegal action name' => '非法的操作名称',
|
||||
'url suffix deny' => '禁止的URL后缀访问',
|
||||
'Route Not Found' => '当前访问路由未定义',
|
||||
'Underfined db type' => '未定义数据库类型',
|
||||
'variable type error' => '变量类型错误',
|
||||
'PSR-4 error' => 'PSR-4 规范错误',
|
||||
'not support total' => '简洁模式下不能获取数据总数',
|
||||
'not support last' => '简洁模式下不能获取最后一页',
|
||||
'error session handler' => '错误的SESSION处理器类',
|
||||
'not allow php tag' => '模板不允许使用PHP语法',
|
||||
'not support' => '不支持',
|
||||
'redisd master' => 'Redisd 主服务器错误',
|
||||
'redisd slave' => 'Redisd 从服务器错误',
|
||||
'must run at sae' => '必须在SAE运行',
|
||||
'memcache init error' => '未开通Memcache服务,请在SAE管理平台初始化Memcache服务',
|
||||
'KVDB init error' => '没有初始化KVDB,请在SAE管理平台初始化KVDB服务',
|
||||
'fields not exists' => '数据表字段不存在',
|
||||
'where express error' => '查询表达式错误',
|
||||
'no data to update' => '没有任何数据需要更新',
|
||||
'miss data to insert' => '缺少需要写入的数据',
|
||||
'miss complex primary data' => '缺少复合主键数据',
|
||||
'miss update condition' => '缺少更新条件',
|
||||
'model data Not Found' => '模型数据不存在',
|
||||
'table data not Found' => '表数据不存在',
|
||||
'delete without condition' => '没有条件不会执行删除操作',
|
||||
'miss relation data' => '缺少关联表数据',
|
||||
'tag attr must' => '模板标签属性必须',
|
||||
'tag error' => '模板标签错误',
|
||||
'cache write error' => '缓存写入失败',
|
||||
'sae mc write error' => 'SAE mc 写入错误',
|
||||
'dispatch type not support' => '不支持的调度类型',
|
||||
'method param miss' => '方法参数错误',
|
||||
'method not exists' => '方法不存在',
|
||||
'module not exists' => '模块不存在',
|
||||
'controller not exists' => '控制器不存在',
|
||||
'class not exists' => '类不存在',
|
||||
'template not exists' => '模板文件不存在',
|
||||
'illegal controller name' => '非法的控制器名称',
|
||||
'illegal action name' => '非法的操作名称',
|
||||
'url suffix deny' => '禁止的URL后缀访问',
|
||||
'Route Not Found' => '当前访问路由未定义',
|
||||
'Underfined db type' => '未定义数据库类型',
|
||||
'variable type error' => '变量类型错误',
|
||||
'PSR-4 error' => 'PSR-4 规范错误',
|
||||
'not support total' => '简洁模式下不能获取数据总数',
|
||||
'not support last' => '简洁模式下不能获取最后一页',
|
||||
'error session handler' => '错误的SESSION处理器类',
|
||||
'not allow php tag' => '模板不允许使用PHP语法',
|
||||
'not support' => '不支持',
|
||||
'redisd master' => 'Redisd 主服务器错误',
|
||||
'redisd slave' => 'Redisd 从服务器错误',
|
||||
'must run at sae' => '必须在SAE运行',
|
||||
'memcache init error' => '未开通Memcache服务,请在SAE管理平台初始化Memcache服务',
|
||||
'KVDB init error' => '没有初始化KVDB,请在SAE管理平台初始化KVDB服务',
|
||||
'fields not exists' => '数据表字段不存在',
|
||||
'where express error' => '查询表达式错误',
|
||||
'no data to update' => '没有任何数据需要更新',
|
||||
'miss data to insert' => '缺少需要写入的数据',
|
||||
'miss complex primary data' => '缺少复合主键数据',
|
||||
'miss update condition' => '缺少更新条件',
|
||||
'model data Not Found' => '模型数据不存在',
|
||||
'table data not Found' => '表数据不存在',
|
||||
'delete without condition' => '没有条件不会执行删除操作',
|
||||
'miss relation data' => '缺少关联表数据',
|
||||
'tag attr must' => '模板标签属性必须',
|
||||
'tag error' => '模板标签错误',
|
||||
'cache write error' => '缓存写入失败',
|
||||
'sae mc write error' => 'SAE mc 写入错误',
|
||||
];
|
||||
|
||||
@@ -162,7 +162,7 @@ class App
|
||||
* @param array $params 参数
|
||||
* @return void
|
||||
*/
|
||||
public static function dispatch($dispath, $type = 'module', $params = [])
|
||||
public static function dispatch($dispatch, $type = 'module', $params = [])
|
||||
{
|
||||
self::$dispatch = ['type' => $type, $type => $dispatch, 'params' => $params];
|
||||
}
|
||||
@@ -307,7 +307,9 @@ class App
|
||||
|
||||
try {
|
||||
$instance = Loader::controller($controller, $config['url_controller_layer'], $config['controller_suffix'], $config['empty_controller']);
|
||||
|
||||
if (is_null($instance)) {
|
||||
throw new HttpException(404, 'controller not exists:' . $controller);
|
||||
}
|
||||
// 获取当前操作名
|
||||
$action = $actionName . $config['action_suffix'];
|
||||
if (!preg_match('/^[A-Za-z](\w)*$/', $action)) {
|
||||
|
||||
@@ -29,9 +29,9 @@ class File extends SplFileObject
|
||||
// 上传文件信息
|
||||
protected $info;
|
||||
|
||||
public function __construct($filename, $mode = 'r', $useIncludePath = false, $context = null)
|
||||
public function __construct($filename, $mode = 'r')
|
||||
{
|
||||
parent::__construct($filename, $mode, $useIncludePath, $context);
|
||||
parent::__construct($filename, $mode);
|
||||
$this->filename = $this->getRealPath();
|
||||
}
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ class Lang
|
||||
|
||||
/**
|
||||
* 自动侦测设置获取语言选择
|
||||
* @return void
|
||||
* @return string
|
||||
*/
|
||||
public static function detect()
|
||||
{
|
||||
|
||||
@@ -11,28 +11,28 @@
|
||||
|
||||
namespace think;
|
||||
|
||||
use think\App;
|
||||
use think\exception\ClassNotFoundException;
|
||||
use think\Request;
|
||||
|
||||
class Loader
|
||||
{
|
||||
protected static $instance = [];
|
||||
// 类名映射
|
||||
protected static $map = [];
|
||||
// 加载列表
|
||||
protected static $load = [];
|
||||
// 命名空间
|
||||
protected static $namespace = [];
|
||||
|
||||
// 命名空间别名
|
||||
protected static $namespaceAlias = [];
|
||||
|
||||
// PSR-4
|
||||
private static $prefixLengthsPsr4 = [];
|
||||
private static $prefixDirsPsr4 = [];
|
||||
private static $fallbackDirsPsr4 = [];
|
||||
|
||||
// PSR-0
|
||||
private static $prefixesPsr0 = [];
|
||||
// Composer自动加载
|
||||
private static $composerLoader = false;
|
||||
private static $prefixesPsr0 = [];
|
||||
private static $fallbackDirsPsr0 = [];
|
||||
|
||||
// 自动加载的文件
|
||||
private static $autoloadFiles = [];
|
||||
|
||||
// 自动加载
|
||||
public static function autoload($class)
|
||||
@@ -48,55 +48,83 @@ class Loader
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty(self::$map[$class])) {
|
||||
// 类库映射
|
||||
include self::$map[$class];
|
||||
} elseif (self::$composerLoader && $file = self::findFileInComposer($class)) {
|
||||
// Composer自动加载
|
||||
include $file;
|
||||
} else {
|
||||
// 命名空间自动加载
|
||||
if (!strpos($class, '\\')) {
|
||||
if ($file = self::findFile($class)) {
|
||||
|
||||
// Win环境严格区分大小写
|
||||
if (IS_WIN && pathinfo($file, PATHINFO_FILENAME) != pathinfo(realpath($file), PATHINFO_FILENAME)) {
|
||||
return false;
|
||||
}
|
||||
$item = explode('\\', $class);
|
||||
// 解析命名空间所在的路径
|
||||
if (count($item) > 2 && isset(self::$namespace[$item[0] . '\\' . $item[1]])) {
|
||||
// 子命名空间定义(仅支持二级)
|
||||
list($ns1, $ns2, $class) = explode('\\', $class, 3);
|
||||
$path = self::$namespace[$ns1 . '\\' . $ns2];
|
||||
} elseif (isset(self::$namespace[$item[0]])) {
|
||||
// 根命名空间定义
|
||||
list($name, $class) = explode('\\', $class, 2);
|
||||
$path = self::$namespace[$name];
|
||||
} elseif (is_dir(EXTEND_PATH . $item[0])) {
|
||||
// 扩展类库命名空间
|
||||
list($name, $class) = explode('\\', $class, 2);
|
||||
$path = EXTEND_PATH . $name . DS;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
// 定位文件
|
||||
$match = false;
|
||||
foreach ((array) $path as $p) {
|
||||
$filename = $p . str_replace('\\', DS, $class) . EXT;
|
||||
if (is_file($filename)) {
|
||||
// Win环境严格区分大小写
|
||||
if (IS_WIN && false === strpos(realpath($filename), $class . EXT)) {
|
||||
continue;
|
||||
}
|
||||
$match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($match) {
|
||||
include $filename;
|
||||
} else {
|
||||
return false;
|
||||
includeFile($file);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找文件
|
||||
* @param $class
|
||||
* @return bool
|
||||
*/
|
||||
private static function findFile($class)
|
||||
{
|
||||
if (!empty(self::$map[$class])) {
|
||||
// 类库映射
|
||||
return self::$map[$class];
|
||||
}
|
||||
|
||||
// 查找 PSR-4
|
||||
$logicalPathPsr4 = strtr($class, '\\', DS) . EXT;
|
||||
|
||||
$first = $class[0];
|
||||
if (isset(self::$prefixLengthsPsr4[$first])) {
|
||||
foreach (self::$prefixLengthsPsr4[$first] as $prefix => $length) {
|
||||
if (0 === strpos($class, $prefix)) {
|
||||
foreach (self::$prefixDirsPsr4[$prefix] as $dir) {
|
||||
if (is_file($file = $dir . DS . substr($logicalPathPsr4, $length))) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
// 查找 PSR-4 fallback dirs
|
||||
foreach (self::$fallbackDirsPsr4 as $dir) {
|
||||
if (is_file($file = $dir . DS . $logicalPathPsr4)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// 查找 PSR-0
|
||||
if (false !== $pos = strrpos($class, '\\')) {
|
||||
// namespaced class name
|
||||
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
|
||||
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DS);
|
||||
} else {
|
||||
// PEAR-like class name
|
||||
$logicalPathPsr0 = strtr($class, '_', DS) . EXT;
|
||||
}
|
||||
|
||||
if (isset(self::$prefixesPsr0[$first])) {
|
||||
foreach (self::$prefixesPsr0[$first] as $prefix => $dirs) {
|
||||
if (0 === strpos($class, $prefix)) {
|
||||
foreach ($dirs as $dir) {
|
||||
if (is_file($file = $dir . DS . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 查找 PSR-0 fallback dirs
|
||||
foreach (self::$fallbackDirsPsr0 as $dir) {
|
||||
if (is_file($file = $dir . DS . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
return self::$map[$class] = false;
|
||||
}
|
||||
|
||||
// 注册classmap
|
||||
@@ -113,12 +141,40 @@ class Loader
|
||||
public static function addNamespace($namespace, $path = '')
|
||||
{
|
||||
if (is_array($namespace)) {
|
||||
self::$namespace = array_merge(self::$namespace, $namespace);
|
||||
foreach ($namespace as $prefix => $paths) {
|
||||
self::setPsr4($prefix . '\\', rtrim($paths, DS));
|
||||
}
|
||||
} else {
|
||||
self::$namespace[$namespace] = $path;
|
||||
self::setPsr4($namespace . '\\', rtrim($path, DS));
|
||||
}
|
||||
}
|
||||
|
||||
// 注册Psr0空间
|
||||
private static function setPsr0($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
self::$fallbackDirsPsr0 = (array)$paths;
|
||||
} else {
|
||||
self::$prefixesPsr0[$prefix[0]][$prefix] = (array)$paths;
|
||||
}
|
||||
}
|
||||
|
||||
// 注册Psr4空间
|
||||
private static function setPsr4($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
self::$fallbackDirsPsr4 = (array)$paths;
|
||||
} else {
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
self::$prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
self::$prefixDirsPsr4[$prefix] = (array)$paths;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 注册命名空间别名
|
||||
public static function addNamespaceAlias($namespace, $original = '')
|
||||
{
|
||||
@@ -133,7 +189,7 @@ class Loader
|
||||
public static function register($autoload = '')
|
||||
{
|
||||
// 注册系统自动加载
|
||||
spl_autoload_register($autoload ?: 'think\\Loader::autoload');
|
||||
spl_autoload_register($autoload ?: 'think\\Loader::autoload', true, true);
|
||||
// 注册命名空间定义
|
||||
self::addNamespace([
|
||||
'think' => LIB_PATH . 'think' . DS,
|
||||
@@ -141,26 +197,15 @@ class Loader
|
||||
'traits' => LIB_PATH . 'traits' . DS,
|
||||
]);
|
||||
// 加载类库映射文件
|
||||
self::addClassMap(include THINK_PATH . 'classmap' . EXT);
|
||||
self::addClassMap(includeFile(THINK_PATH . 'classmap' . EXT));
|
||||
|
||||
// Composer自动加载支持
|
||||
if (is_dir(VENDOR_PATH . 'composer')) {
|
||||
// 注册Composer自动加载
|
||||
self::$composerLoader = true;
|
||||
self::registerComposerLoader();
|
||||
} elseif (is_file(VENDOR_PATH . 'think_autoload.php')) {
|
||||
// 读取Composer自动加载文件
|
||||
$autoload = include VENDOR_PATH . 'think_autoload.php';
|
||||
if (is_array($autoload)) {
|
||||
// 命名空间和类库映射注册
|
||||
self::addNamespace($autoload['namespace']);
|
||||
self::addClassMap($autoload['classmap']);
|
||||
// 载入composer包的文件列表
|
||||
foreach ($autoload['files'] as $file) {
|
||||
include $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 自动加载extend目录
|
||||
self::$fallbackDirsPsr4[] = rtrim(EXTEND_PATH, DS);
|
||||
}
|
||||
|
||||
// 注册composer自动加载
|
||||
@@ -169,19 +214,14 @@ class Loader
|
||||
if (is_file(VENDOR_PATH . 'composer/autoload_namespaces.php')) {
|
||||
$map = require VENDOR_PATH . 'composer/autoload_namespaces.php';
|
||||
foreach ($map as $namespace => $path) {
|
||||
self::$prefixesPsr0[$namespace[0]][$namespace] = (array) $path;
|
||||
self::setPsr0($namespace, $path);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_file(VENDOR_PATH . 'composer/autoload_psr4.php')) {
|
||||
$map = require VENDOR_PATH . 'composer/autoload_psr4.php';
|
||||
foreach ($map as $namespace => $path) {
|
||||
$length = strlen($namespace);
|
||||
if ('\\' !== $namespace[$length - 1]) {
|
||||
throw new \InvalidArgumentException("PSR-4 error: A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
self::$prefixLengthsPsr4[$namespace[0]][$namespace] = $length;
|
||||
self::$prefixDirsPsr4[$namespace] = (array) $path;
|
||||
self::setPsr4($namespace, $path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,81 +235,34 @@ class Loader
|
||||
if (is_file(VENDOR_PATH . 'composer/autoload_files.php')) {
|
||||
$includeFiles = require VENDOR_PATH . 'composer/autoload_files.php';
|
||||
foreach ($includeFiles as $fileIdentifier => $file) {
|
||||
self::composerRequire($fileIdentifier, $file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static function composerRequire($fileIdentifier, $file)
|
||||
{
|
||||
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||
require $file;
|
||||
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
||||
}
|
||||
}
|
||||
|
||||
private static function findFileInComposer($class, $ext = '.php')
|
||||
{
|
||||
// PSR-4 lookup
|
||||
$logicalPathPsr4 = strtr($class, '\\', DS) . $ext;
|
||||
|
||||
$first = $class[0];
|
||||
if (isset(self::$prefixLengthsPsr4[$first])) {
|
||||
foreach (self::$prefixLengthsPsr4[$first] as $prefix => $length) {
|
||||
if (0 === strpos($class, $prefix)) {
|
||||
foreach (self::$prefixDirsPsr4[$prefix] as $dir) {
|
||||
if (file_exists($file = $dir . DS . substr($logicalPathPsr4, $length))) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
if (empty(self::$autoloadFiles[$fileIdentifier])) {
|
||||
requireFile($file);
|
||||
self::$autoloadFiles[$fileIdentifier] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// PSR-0 lookup
|
||||
if (false !== $pos = strrpos($class, '\\')) {
|
||||
// namespaced class name
|
||||
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
|
||||
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DS);
|
||||
} else {
|
||||
// PEAR-like class name
|
||||
$logicalPathPsr0 = strtr($class, '_', DS) . $ext;
|
||||
}
|
||||
|
||||
if (isset(self::$prefixesPsr0[$first])) {
|
||||
foreach (self::$prefixesPsr0[$first] as $prefix => $dirs) {
|
||||
if (0 === strpos($class, $prefix)) {
|
||||
foreach ($dirs as $dir) {
|
||||
if (file_exists($file = $dir . DS . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Remember that this class does not exist.
|
||||
return self::$map[$class] = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 导入所需的类库 同java的Import 本函数有缓存功能
|
||||
* @param string $class 类库命名空间字符串
|
||||
* @param string $class 类库命名空间字符串
|
||||
* @param string $baseUrl 起始路径
|
||||
* @param string $ext 导入的文件扩展名
|
||||
* @param string $ext 导入的文件扩展名
|
||||
* @return boolean
|
||||
*/
|
||||
public static function import($class, $baseUrl = '', $ext = EXT)
|
||||
{
|
||||
static $_file = [];
|
||||
$class = str_replace(['.', '#'], [DS, '.'], $class);
|
||||
$class = str_replace(['.', '#'], [DS, '.'], $class);
|
||||
if (isset($_file[$class . $baseUrl])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (empty($baseUrl)) {
|
||||
list($name, $class) = explode(DS, $class, 2);
|
||||
if (isset(self::$namespace[$name])) {
|
||||
if (isset(self::$prefixDirsPsr4[$name])) {
|
||||
// 注册的命名空间
|
||||
$baseUrl = self::$namespace[$name];
|
||||
$baseUrl = self::$prefixDirsPsr4[$name];
|
||||
} elseif ('@' == $name) {
|
||||
//加载当前模块应用类库
|
||||
$baseUrl = App::$modulePath;
|
||||
@@ -283,13 +276,23 @@ class Loader
|
||||
$baseUrl .= DS;
|
||||
}
|
||||
// 如果类存在 则导入类库文件
|
||||
$filename = $baseUrl . $class . $ext;
|
||||
if (is_file($filename)) {
|
||||
if (is_array($baseUrl)) {
|
||||
foreach ($baseUrl as $path) {
|
||||
$filename = $path . DS . $class . $ext;
|
||||
if (is_file($filename)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$filename = $baseUrl . $class . $ext;
|
||||
}
|
||||
|
||||
if (!empty($filename) && is_file($filename)) {
|
||||
// 开启调试模式Win环境严格区分大小写
|
||||
if (IS_WIN && false === strpos(realpath($filename), $class . $ext)) {
|
||||
if (IS_WIN && pathinfo($filename, PATHINFO_FILENAME) != pathinfo(realpath($filename), PATHINFO_FILENAME)) {
|
||||
return false;
|
||||
}
|
||||
include $filename;
|
||||
includeFile($filename);
|
||||
$_file[$class . $baseUrl] = true;
|
||||
return true;
|
||||
}
|
||||
@@ -298,10 +301,10 @@ class Loader
|
||||
|
||||
/**
|
||||
* 实例化(分层)模型
|
||||
* @param string $name Model名称
|
||||
* @param string $layer 业务层名称
|
||||
* @param bool $appendSuffix 是否添加类名后缀
|
||||
* @param string $common 公共模块名
|
||||
* @param string $name Model名称
|
||||
* @param string $layer 业务层名称
|
||||
* @param bool $appendSuffix 是否添加类名后缀
|
||||
* @param string $common 公共模块名
|
||||
* @return Object
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
@@ -332,10 +335,10 @@ class Loader
|
||||
|
||||
/**
|
||||
* 实例化(分层)控制器 格式:[模块名/]控制器名
|
||||
* @param string $name 资源地址
|
||||
* @param string $layer 控制层名称
|
||||
* @param bool $appendSuffix 是否添加类名后缀
|
||||
* @param string $empty 空控制器名称
|
||||
* @param string $name 资源地址
|
||||
* @param string $layer 控制层名称
|
||||
* @param bool $appendSuffix 是否添加类名后缀
|
||||
* @param string $empty 空控制器名称
|
||||
* @return Object|false
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
@@ -351,17 +354,15 @@ class Loader
|
||||
return new $class(Request::instance());
|
||||
} elseif ($empty && class_exists($emptyClass = self::parseClass($module, $layer, $empty, $appendSuffix))) {
|
||||
return new $emptyClass(Request::instance());
|
||||
} else {
|
||||
throw new ClassNotFoundException('class not exists:' . $class, $class);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 实例化验证类 格式:[模块名/]验证器名
|
||||
* @param string $name 资源地址
|
||||
* @param string $layer 验证层名称
|
||||
* @param bool $appendSuffix 是否添加类名后缀
|
||||
* @param string $common 公共模块名
|
||||
* @param string $name 资源地址
|
||||
* @param string $layer 验证层名称
|
||||
* @param bool $appendSuffix 是否添加类名后缀
|
||||
* @param string $common 公共模块名
|
||||
* @return Object|false
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
@@ -407,10 +408,10 @@ class Loader
|
||||
|
||||
/**
|
||||
* 远程调用模块的操作方法 参数格式 [模块/控制器/]操作
|
||||
* @param string $url 调用地址
|
||||
* @param string|array $vars 调用参数 支持字符串和数组
|
||||
* @param string $layer 要调用的控制层名称
|
||||
* @param bool $appendSuffix 是否添加类名后缀
|
||||
* @param string $url 调用地址
|
||||
* @param string|array $vars 调用参数 支持字符串和数组
|
||||
* @param string $layer 要调用的控制层名称
|
||||
* @param bool $appendSuffix 是否添加类名后缀
|
||||
* @return mixed
|
||||
*/
|
||||
public static function action($url, $vars = [], $layer = 'controller', $appendSuffix = false)
|
||||
@@ -434,14 +435,16 @@ class Loader
|
||||
/**
|
||||
* 字符串命名风格转换
|
||||
* type 0 将Java风格转换为C的风格 1 将C风格转换为Java的风格
|
||||
* @param string $name 字符串
|
||||
* @param integer $type 转换类型
|
||||
* @param string $name 字符串
|
||||
* @param integer $type 转换类型
|
||||
* @return string
|
||||
*/
|
||||
public static function parseName($name, $type = 0)
|
||||
{
|
||||
if ($type) {
|
||||
return ucfirst(preg_replace_callback('/_([a-zA-Z])/', function ($match) {return strtoupper($match[1]);}, $name));
|
||||
return ucfirst(preg_replace_callback('/_([a-zA-Z])/', function ($match) {
|
||||
return strtoupper($match[1]);
|
||||
}, $name));
|
||||
} else {
|
||||
return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_"));
|
||||
}
|
||||
@@ -450,8 +453,9 @@ class Loader
|
||||
/**
|
||||
* 解析应用类的类名
|
||||
* @param string $module 模块名
|
||||
* @param string $layer 层名 controller model ...
|
||||
* @param string $name 类名
|
||||
* @param string $layer 层名 controller model ...
|
||||
* @param string $name 类名
|
||||
* @param bool $appendSuffix
|
||||
* @return string
|
||||
*/
|
||||
public static function parseClass($module, $layer, $name, $appendSuffix = false)
|
||||
@@ -472,3 +476,19 @@ class Loader
|
||||
self::$instance = [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 作用范围隔离
|
||||
*
|
||||
* @param $file
|
||||
* @return mixed
|
||||
*/
|
||||
function includeFile($file)
|
||||
{
|
||||
return include $file;
|
||||
}
|
||||
|
||||
function requireFile($file)
|
||||
{
|
||||
return require $file;
|
||||
}
|
||||
@@ -638,7 +638,7 @@ class Route
|
||||
|
||||
if (isset(self::$map[$url])) {
|
||||
// URL映射(完整静态URL匹配)
|
||||
return self::parseUrl(self::$map[$url], $depr);
|
||||
return self::parseModule(self::$map[$url], $depr);
|
||||
}
|
||||
|
||||
if (strpos($url, '/') && isset(self::$alias[strstr($url, '/', true)])) {
|
||||
@@ -1010,12 +1010,8 @@ class Route
|
||||
// 如果有模块/控制器绑定
|
||||
$url = self::$bind['module'] . '/' . $url;
|
||||
}
|
||||
// 分隔符替换 确保路由定义使用统一的分隔符
|
||||
if ('/' != $depr) {
|
||||
$url = str_replace($depr, '/', $url);
|
||||
}
|
||||
|
||||
list($path, $var) = self::parseUrlPath($url);
|
||||
list($path, $var) = self::parseUrlPath($url, $depr);
|
||||
$route = [null, null, null];
|
||||
if (isset($path)) {
|
||||
// 解析模块
|
||||
@@ -1052,10 +1048,15 @@ class Route
|
||||
* 解析URL的pathinfo参数和变量
|
||||
* @access private
|
||||
* @param string $url URL地址
|
||||
* @param string $depr URL分隔符
|
||||
* @return array
|
||||
*/
|
||||
private static function parseUrlPath($url)
|
||||
private static function parseUrlPath($url, $depr = '/')
|
||||
{
|
||||
// 分隔符替换 确保路由定义使用统一的分隔符
|
||||
if ('/' != $depr) {
|
||||
$url = str_replace($depr, '/', $url);
|
||||
}
|
||||
$url = trim($url, '/');
|
||||
$var = [];
|
||||
if (false !== strpos($url, '?')) {
|
||||
@@ -1185,24 +1186,36 @@ class Route
|
||||
$result = ['type' => 'controller', 'controller' => substr($url, 1), 'params' => $matches];
|
||||
} else {
|
||||
// 路由到模块/控制器/操作
|
||||
list($path, $var) = self::parseUrlPath($url);
|
||||
$action = array_pop($path);
|
||||
$controller = !empty($path) ? array_pop($path) : null;
|
||||
$module = Config::get('app_multi_module') && !empty($path) ? array_pop($path) : null;
|
||||
$method = Request::instance()->method();
|
||||
if (Config::get('use_action_prefix') && !empty(self::$methodPrefix[$method])) {
|
||||
// 操作方法前缀支持
|
||||
$action = 0 !== strpos($action, self::$methodPrefix[$method]) ? self::$methodPrefix[$method] . $action : $action;
|
||||
}
|
||||
$_GET = array_merge($_GET, $var);
|
||||
// 路由到模块/控制器/操作
|
||||
$result = ['type' => 'module', 'module' => [$module, $controller, $action], 'convert' => false];
|
||||
$result = self::parseModule($url);
|
||||
}
|
||||
// 解析额外参数
|
||||
self::parseUrlParams(empty($paths) ? '' : implode('/', $paths), $matches);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析URL地址为 模块/控制器/操作
|
||||
* @access private
|
||||
* @param string $url URL地址
|
||||
* @param string $depr URL分隔符
|
||||
* @return array
|
||||
*/
|
||||
private static function parseModule($url, $depr = '/')
|
||||
{
|
||||
list($path, $var) = self::parseUrlPath($url, $depr);
|
||||
$action = array_pop($path);
|
||||
$controller = !empty($path) ? array_pop($path) : null;
|
||||
$module = Config::get('app_multi_module') && !empty($path) ? array_pop($path) : null;
|
||||
$method = Request::instance()->method();
|
||||
if (Config::get('use_action_prefix') && !empty(self::$methodPrefix[$method])) {
|
||||
// 操作方法前缀支持
|
||||
$action = 0 !== strpos($action, self::$methodPrefix[$method]) ? self::$methodPrefix[$method] . $action : $action;
|
||||
}
|
||||
$_GET = array_merge($_GET, $var);
|
||||
// 路由到模块/控制器/操作
|
||||
return ['type' => 'module', 'module' => [$module, $controller, $action], 'convert' => false];
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析URL地址中的参数Request对象
|
||||
* @access private
|
||||
|
||||
@@ -556,9 +556,15 @@ class Template
|
||||
$children[$parent][] = $name;
|
||||
continue;
|
||||
}
|
||||
} elseif (!empty($val['parent'])) {
|
||||
// 如果子标签没有被继承则用原值
|
||||
$children[$val['parent']][] = $name;
|
||||
$blocks[$name] = $val;
|
||||
}
|
||||
if (!$val['parent']) {
|
||||
// 替换模板中的顶级block标签
|
||||
$extend = str_replace($val['begin'] . $val['content'] . $val['end'], $replace, $extend);
|
||||
}
|
||||
// 替换模板中的block标签
|
||||
$extend = str_replace($val['begin'] . $val['content'] . $val['end'], $replace, $extend);
|
||||
}
|
||||
}
|
||||
$content = $extend;
|
||||
@@ -735,20 +741,15 @@ class Template
|
||||
$str = trim(substr($str, $pos + 1));
|
||||
$this->parseVar($str);
|
||||
$first = substr($str, 0, 1);
|
||||
if (isset($array[1])) {
|
||||
$this->parseVar($array[2]);
|
||||
$name .= $array[1] . $array[2];
|
||||
if ('=' == $first) {
|
||||
// {$varname?='xxx'} $varname为真时才输出xxx
|
||||
$str = '<?php if(' . $name . ') echo ' . substr($str, 1) . '; ?>';
|
||||
} else {
|
||||
$str = '<?php echo (' . $name . ')?' . $str . '; ?>';
|
||||
}
|
||||
} elseif (')' == substr($name, -1, 1)) {
|
||||
if (strpos($name, ')')) {
|
||||
// $name为对象或是自动识别,或者含有函数
|
||||
if (isset($array[1])) {
|
||||
$this->parseVar($array[2]);
|
||||
$name .= $array[1] . $array[2];
|
||||
}
|
||||
switch ($first) {
|
||||
case '?':
|
||||
$str = '<?php echo ' . $name . ' ? ' . $name . ' : ' . substr($str, 1) . '; ?>';
|
||||
$str = '<?php echo (' . $name . ') ? ' . $name . ' : ' . substr($str, 1) . '; ?>';
|
||||
break;
|
||||
case '=':
|
||||
$str = '<?php if(' . $name . ') echo ' . substr($str, 1) . '; ?>';
|
||||
@@ -757,26 +758,32 @@ class Template
|
||||
$str = '<?php echo ' . $name . '?' . $str . '; ?>';
|
||||
}
|
||||
} else {
|
||||
if (isset($array[1])) {
|
||||
$this->parseVar($array[2]);
|
||||
$_name = ' && ' . $name . $array[1] . $array[2];
|
||||
} else {
|
||||
$_name = '';
|
||||
}
|
||||
// $name为数组
|
||||
switch ($first) {
|
||||
case '?':
|
||||
// {$varname??'xxx'} $varname有定义则输出$varname,否则输出xxx
|
||||
$str = '<?php echo isset(' . $name . ') ? ' . $name . ' : ' . substr($str, 1) . '; ?>';
|
||||
$str = '<?php echo isset(' . $name . ')' . $_name . ' ? ' . $name . ' : ' . substr($str, 1) . '; ?>';
|
||||
break;
|
||||
case '=':
|
||||
// {$varname?='xxx'} $varname为真时才输出xxx
|
||||
$str = '<?php if(!empty(' . $name . ')) echo ' . substr($str, 1) . '; ?>';
|
||||
$str = '<?php if(!empty(' . $name . ')' . $_name . ') echo ' . substr($str, 1) . '; ?>';
|
||||
break;
|
||||
case ':':
|
||||
// {$varname?:'xxx'} $varname为真时输出$varname,否则输出xxx
|
||||
$str = '<?php echo !empty(' . $name . ')?' . $name . $str . '; ?>';
|
||||
$str = '<?php echo !empty(' . $name . ')' . $_name . '?' . $name . $str . '; ?>';
|
||||
break;
|
||||
default:
|
||||
if (strpos($str, ':')) {
|
||||
// {$varname ? 'a' : 'b'} $varname为真时输出a,否则输出b
|
||||
$str = '<?php echo !empty(' . $name . ')?' . $str . '; ?>';
|
||||
$str = '<?php echo !empty(' . $name . ')' . $_name . '?' . $str . '; ?>';
|
||||
} else {
|
||||
$str = '<?php echo ' . $name . '?' . $str . '; ?>';
|
||||
$str = '<?php echo ' . $_name . '?' . $str . '; ?>';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -847,6 +854,18 @@ class Template
|
||||
if ('$Think' == $first) {
|
||||
// 所有以Think.打头的以特殊变量对待 无需模板赋值就可以输出
|
||||
$parseStr = $this->parseThinkVar($vars);
|
||||
} elseif ('$Request' == $first) {
|
||||
// 获取Request请求对象参数
|
||||
$method = array_shift($vars);
|
||||
if (!empty($vars)) {
|
||||
$params = implode('.', $vars);
|
||||
if ('true' != $params) {
|
||||
$params = '\'' . $params . '\'';
|
||||
}
|
||||
} else {
|
||||
$params = '';
|
||||
}
|
||||
$parseStr = '\think\Request::instance()->' . $method . '(' . $params . ')';
|
||||
} else {
|
||||
switch ($this->config['tpl_var_identify']) {
|
||||
case 'array': // 识别为数组
|
||||
|
||||
@@ -243,7 +243,7 @@ class Url
|
||||
} elseif (empty($pattern) && array_intersect_assoc($param, $array) == $param) {
|
||||
$match = true;
|
||||
}
|
||||
if (!empty($param) && array_intersect_assoc($param, $array) != $param) {
|
||||
if ($match && !empty($param) && array_intersect_assoc($param, $array) != $param) {
|
||||
$match = false;
|
||||
}
|
||||
if ($match) {
|
||||
@@ -324,10 +324,6 @@ class Url
|
||||
// 分析路由规则中的变量
|
||||
private static function parseVar($rule)
|
||||
{
|
||||
// 检测是否设置了参数分隔符
|
||||
if ($depr = Config::get('url_params_depr')) {
|
||||
$rule = str_replace($depr, '/', $rule);
|
||||
}
|
||||
// 提取路由规则中的变量
|
||||
$var = [];
|
||||
foreach (explode('/', $rule) as $val) {
|
||||
@@ -344,6 +340,9 @@ class Url
|
||||
}
|
||||
}
|
||||
|
||||
if ('$' == substr($val, -1, 1)) {
|
||||
$val = substr($val, 0, -1);
|
||||
}
|
||||
if (0 === strpos($val, '[:')) {
|
||||
// 可选参数
|
||||
$optional = true;
|
||||
|
||||
@@ -70,7 +70,7 @@ abstract class Rest
|
||||
if (method_exists($this, $method . '_' . $this->method . '_' . $this->type)) {
|
||||
// RESTFul方法支持
|
||||
$fun = $method . '_' . $this->method . '_' . $this->type;
|
||||
} elseif ($this->_method == $this->restDefaultMethod && method_exists($this, $method . '_' . $this->type)) {
|
||||
} elseif ($this->method == $this->restDefaultMethod && method_exists($this, $method . '_' . $this->type)) {
|
||||
$fun = $method . '_' . $this->type;
|
||||
} elseif ($this->type == $this->restDefaultType && method_exists($this, $method . '_' . $this->method)) {
|
||||
$fun = $method . '_' . $this->method;
|
||||
|
||||
@@ -30,7 +30,7 @@ abstract class Yar
|
||||
|
||||
//判断扩展是否存在
|
||||
if (!extension_loaded('yar')) {
|
||||
throw new Exception('not support yar');
|
||||
throw new \Exception('not support yar');
|
||||
}
|
||||
|
||||
//实例化Yar_Server
|
||||
|
||||
@@ -138,8 +138,6 @@ abstract class Builder
|
||||
{
|
||||
if (is_string($value)) {
|
||||
$value = strpos($value, ':') === 0 && $this->query->isBind(substr($value, 1)) ? $value : $this->connection->quote($value);
|
||||
} elseif (is_array($value) && is_string($value[0]) && strtolower($value[0]) == 'exp') {
|
||||
$value = $value[1];
|
||||
} elseif (is_array($value)) {
|
||||
$value = array_map([$this, 'parseValue'], $value);
|
||||
} elseif (is_bool($value)) {
|
||||
|
||||
@@ -178,16 +178,15 @@ class Query
|
||||
* @access public
|
||||
* @param string $sql sql指令
|
||||
* @param array $bind 参数绑定
|
||||
* @param boolean $fetch 不执行只是获取SQL
|
||||
* @param boolean $master 是否在主服务器读操作
|
||||
* @param bool|string $class 指定返回的数据集对象
|
||||
* @return mixed
|
||||
* @throws BindParamException
|
||||
* @throws PDOException
|
||||
*/
|
||||
public function query($sql, $bind = [], $fetch = false, $master = false, $class = false)
|
||||
public function query($sql, $bind = [], $master = false, $class = false)
|
||||
{
|
||||
return $this->connection->query($sql, $bind, $fetch, $master, $class);
|
||||
return $this->connection->query($sql, $bind, $master, $class);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -195,16 +194,15 @@ class Query
|
||||
* @access public
|
||||
* @param string $sql sql指令
|
||||
* @param array $bind 参数绑定
|
||||
* @param boolean $fetch 不执行只是获取SQL
|
||||
* @param boolean $getLastInsID 是否获取自增ID
|
||||
* @param boolean $sequence 自增序列名
|
||||
* @return int
|
||||
* @throws BindParamException
|
||||
* @throws PDOException
|
||||
*/
|
||||
public function execute($sql, $bind = [], $fetch = false, $getLastInsID = false, $sequence = null)
|
||||
public function execute($sql, $bind = [], $getLastInsID = false, $sequence = null)
|
||||
{
|
||||
return $this->connection->execute($sql, $bind, $fetch, $getLastInsID, $sequence);
|
||||
return $this->connection->execute($sql, $bind, $getLastInsID, $sequence);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1466,7 +1464,7 @@ class Query
|
||||
unset($this->options['with_field']);
|
||||
}
|
||||
}
|
||||
$this->field($field, false, $joinTable, $joinAlias, $joinName . '__');
|
||||
$this->field($field, false, $joinTable, $joinAlias, $relation . '__');
|
||||
$i++;
|
||||
} elseif ($closure) {
|
||||
$with[$key] = $closure;
|
||||
@@ -1873,7 +1871,7 @@ class Query
|
||||
* @throws Exception
|
||||
* @throws PDOException
|
||||
*/
|
||||
public function selectOrFail($data = [])
|
||||
public function selectOrFail($data = null)
|
||||
{
|
||||
return $this->failException(true)->select($data);
|
||||
}
|
||||
@@ -1887,7 +1885,7 @@ class Query
|
||||
* @throws Exception
|
||||
* @throws PDOException
|
||||
*/
|
||||
public function findOrFail($data = [])
|
||||
public function findOrFail($data = null)
|
||||
{
|
||||
return $this->failException(true)->find($data);
|
||||
}
|
||||
@@ -1950,22 +1948,22 @@ class Query
|
||||
/**
|
||||
* 删除记录
|
||||
* @access public
|
||||
* @param array $data 表达式
|
||||
* @param mixed $data 表达式 true 表示强制删除
|
||||
* @return int
|
||||
* @throws Exception
|
||||
* @throws PDOException
|
||||
*/
|
||||
public function delete($data = [])
|
||||
public function delete($data = null)
|
||||
{
|
||||
// 分析查询表达式
|
||||
$options = $this->parseExpress();
|
||||
|
||||
if (!empty($data)) {
|
||||
if (!is_null($data) && true !== $data) {
|
||||
// AR模式分析主键条件
|
||||
$this->parsePkWhere($data, $options);
|
||||
}
|
||||
|
||||
if (empty($options['where'])) {
|
||||
if (true !== $data && empty($options['where'])) {
|
||||
// 如果条件为空 不进行删除操作 除非设置 1=1
|
||||
throw new Exception('delete without condition');
|
||||
}
|
||||
|
||||
@@ -302,23 +302,22 @@ class Relation
|
||||
*/
|
||||
protected function match($model, $relation, &$result)
|
||||
{
|
||||
$modelName = Loader::parseName(basename(str_replace('\\', '/', $model)));
|
||||
// 重新组装模型数据
|
||||
foreach ($result->toArray() as $key => $val) {
|
||||
if (strpos($key, '__')) {
|
||||
list($name, $attr) = explode('__', $key, 2);
|
||||
if ($name == $modelName) {
|
||||
if ($name == $relation) {
|
||||
$list[$name][$attr] = $val;
|
||||
unset($result->$key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($list[$modelName])) {
|
||||
if (!isset($list[$relation])) {
|
||||
// 设置关联模型属性
|
||||
$list[$modelName] = [];
|
||||
$list[$relation] = [];
|
||||
}
|
||||
$result->setAttr($relation, new $model($list[$modelName]));
|
||||
$result->setAttr($relation, new $model($list[$relation]));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user