内核更新,标签的更新

This commit is contained in:
2016-06-29 15:02:59 +08:00
parent c8e979b159
commit c98ca32ede
16 changed files with 354 additions and 342 deletions

View File

@@ -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 写入错误',
];

View File

@@ -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)) {

View File

@@ -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();
}

View File

@@ -148,7 +148,7 @@ class Lang
/**
* 自动侦测设置获取语言选择
* @return void
* @return string
*/
public static function detect()
{

View File

@@ -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;
}

View 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

View File

@@ -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': // 识别为数组

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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)) {

View File

@@ -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');
}

View File

@@ -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]));
}
/**