mirror of
https://gitee.com/fastadminnet/framework.git
synced 2026-07-01 12:42:48 +08:00
Merge branch 'master' of https://github.com/top-think/think
This commit is contained in:
@@ -95,7 +95,7 @@ return [
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
// 默认跳转页面对应的模板文件
|
||||
'dispatch_jump_tmpl' => THINK_PATH . 'tpl/dispatch_jump.tpl',
|
||||
'dispatch_jump_tmpl' => THINK_PATH . 'tpl' . DS . 'dispatch_jump.tpl',
|
||||
// 默认的模板引擎
|
||||
'template_engine' => 'Think',
|
||||
|
||||
@@ -104,7 +104,7 @@ return [
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
// 异常页面的模板文件
|
||||
'exception_tmpl' => THINK_PATH . 'tpl/think_exception.tpl',
|
||||
'exception_tmpl' => THINK_PATH . 'tpl' . DS . 'think_exception.tpl',
|
||||
// 错误显示信息,非调试模式有效
|
||||
'error_message' => '页面错误!请稍后再试~',
|
||||
// 错误定向页面
|
||||
@@ -152,6 +152,7 @@ return [
|
||||
|
||||
// 是否启用多状态数据库配置 如果启用的话 需要跟随app_status配置不同的数据库信息
|
||||
'use_db_switch' => false,
|
||||
'db_fields_strict' => true,
|
||||
'database' => [
|
||||
// 数据库类型
|
||||
'type' => 'mysql',
|
||||
|
||||
@@ -190,14 +190,18 @@ class Model
|
||||
}
|
||||
}
|
||||
}
|
||||
$fields = $this->getDbFields();
|
||||
// 检查非数据字段
|
||||
if (!empty($this->fields)) {
|
||||
if (!empty($fields)) {
|
||||
foreach ($data as $key => $val) {
|
||||
if (!in_array($key, $this->fields, true)) {
|
||||
if (!in_array($key, $fields, true)) {
|
||||
if (Config::get('db_fields_strict')) {
|
||||
throw new Exception(' fields not exists :[' . $key . '=>' . $val . ']');
|
||||
}
|
||||
unset($data[$key]);
|
||||
} elseif (is_scalar($val) && empty($this->options['bind'][':' . $key])) {
|
||||
// 字段类型检查
|
||||
$this->_parseType($data, $key);
|
||||
$this->_parseType($data, $key, $this->options['bind']);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -777,7 +781,7 @@ class Model
|
||||
$key = trim($key);
|
||||
if (in_array($key, $fields, true)) {
|
||||
if (is_scalar($val) && empty($options['bind'][':' . $key])) {
|
||||
$this->_parseType($options['where'], $key);
|
||||
$this->_parseType($options['where'], $key, $options['bind']);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -799,18 +803,21 @@ class Model
|
||||
* @param string $key 字段名
|
||||
* @return void
|
||||
*/
|
||||
protected function _parseType(&$data, $key)
|
||||
protected function _parseType(&$data, $key, &$bind)
|
||||
{
|
||||
if (!isset($this->options['bind'][':' . $key]) && isset($this->fields['_type'][$key])) {
|
||||
if (!isset($bind[':' . $key]) && isset($this->fields['_type'][$key])) {
|
||||
$fieldType = strtolower($this->fields['_type'][$key]);
|
||||
if (false !== strpos($fieldType, 'enum')) {
|
||||
// 支持ENUM类型优先检测
|
||||
} elseif (false === strpos($fieldType, 'bigint') && false !== strpos($fieldType, 'int')) {
|
||||
$data[$key] = intval($data[$key]);
|
||||
$bind[':' . $key] = [$data[$key], \PDO::PARAM_INT];
|
||||
$data[$key] = ':' . $key;
|
||||
} elseif (false !== strpos($fieldType, 'float') || false !== strpos($fieldType, 'double')) {
|
||||
$data[$key] = floatval($data[$key]);
|
||||
$bind[':' . $key] = [$data[$key], \PDO::PARAM_INT];
|
||||
$data[$key] = ':' . $key;
|
||||
} elseif (false !== strpos($fieldType, 'bool')) {
|
||||
$data[$key] = (bool) $data[$key];
|
||||
$bind[':' . $key] = [$data[$key], \PDO::PARAM_BOOL];
|
||||
$data[$key] = ':' . $key;
|
||||
} elseif (false !== strpos($fieldType, 'json') && is_array($data[$key])) {
|
||||
$data[$key] = json_encode($data[$key]);
|
||||
}
|
||||
|
||||
@@ -593,40 +593,26 @@ class Template
|
||||
$flag = substr($str, 0, 1);
|
||||
switch ($flag) {
|
||||
case '$': // 解析模板变量 格式 {$varName}
|
||||
$this->parseVar($str);
|
||||
switch ($this->config['tpl_var_identify']) {
|
||||
case 'array':
|
||||
$begin = 0;
|
||||
break;
|
||||
case 'obj':
|
||||
$begin = 1;
|
||||
break;
|
||||
default:
|
||||
// 如果是自动识别.语法,则要查找:之后的?号
|
||||
$begin = strpos($str, ':');
|
||||
}
|
||||
// 是否带有?号
|
||||
if (false !== $pos = strpos($str, '?', $begin)) {
|
||||
if (false !== $pos = strpos($str, '?')) {
|
||||
$array = preg_split('/([!=]={1,2}|(?<!-)[><]={0,1})/', substr($str, 0, $pos), 2, PREG_SPLIT_DELIM_CAPTURE);
|
||||
$name = trim($array[0]);
|
||||
$name = $array[0];
|
||||
$this->parseVar($name);
|
||||
$this->parseVarFunction($name);
|
||||
|
||||
$str = trim(substr($str, $pos + 1));
|
||||
$this->parseVar($str);
|
||||
$first = substr($str, 0, 1);
|
||||
if (isset($array[1])) {
|
||||
// 设置了判断条件
|
||||
// XXX: 加入这句原本是为解决变量末声明的问题,但$name中是多个条件时会解析错误,故注释掉
|
||||
/*if (strpos($name, '[')) {
|
||||
$name = 'isset(' . $name . ') && ' . $name;
|
||||
}*/
|
||||
$name .= $array[1] . trim($array[2]);
|
||||
$this->parseVar($array[2]);
|
||||
$name .= $array[1] . $array[2];
|
||||
if ('=' == $first) {
|
||||
// {$varname?='xxx'} $varname为真时才输出xxx
|
||||
$str = '<?php if( ' . $name . ' ) echo ' . substr($str, 1) . '; ?>';
|
||||
$str = '<?php if(' . $name . ') echo ' . substr($str, 1) . '; ?>';
|
||||
} else {
|
||||
$str = '<?php echo (' . $name . ') ? ' . $str . '; ?>';
|
||||
$str = '<?php echo (' . $name . ')?' . $str . '; ?>';
|
||||
}
|
||||
} elseif ($begin || ')' == substr($name, -1, 1)) {
|
||||
} elseif (')' == substr($name, -1, 1)) {
|
||||
// $name为对象或是自动识别,或者含有函数
|
||||
switch ($first) {
|
||||
case '?':
|
||||
@@ -651,18 +637,19 @@ class Template
|
||||
break;
|
||||
case ':':
|
||||
// {$varname?:'xxx'} $varname为真时输出$varname,否则输出xxx
|
||||
$str = '<?php echo !empty(' . $name . ') ? ' . $name . $str . '; ?>';
|
||||
$str = '<?php echo !empty(' . $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 . ')?' . $str . '; ?>';
|
||||
} else {
|
||||
$str = '<?php echo ' . $name . '?' . $str . '; ?>';
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->parseVar($str);
|
||||
$this->parseVarFunction($str);
|
||||
$str = '<?php echo ' . $str . '; ?>';
|
||||
}
|
||||
@@ -674,11 +661,14 @@ class Template
|
||||
break;
|
||||
case '~': // 执行某个函数
|
||||
$str = substr($str, 1);
|
||||
$this->parseVar($str);
|
||||
$str = '<?php ' . $str . '; ?>';
|
||||
break;
|
||||
case '-':
|
||||
case '+': // 输出计算
|
||||
$str = '<?php echo ' . $str . '; ?>';
|
||||
$str = substr($str, 1);
|
||||
$this->parseVar($str);
|
||||
$str = '<?php echo ' . $flag . $str . '; ?>';
|
||||
break;
|
||||
case '/': // 注释标签
|
||||
$flag2 = substr($str, 1, 1);
|
||||
@@ -777,9 +767,9 @@ class Template
|
||||
switch ($fun) {
|
||||
case 'default': // 特殊模板函数
|
||||
if (false === strpos($name, '(')) {
|
||||
$name = '((isset(' . $name . ') && (' . $name . ' !== \'\')?(' . $name . '):' . $args[1] . ')';
|
||||
$name = '(isset(' . $name . ') && (' . $name . ' !== \'\')?' . $name . ':' . $args[1] . ')';
|
||||
} else {
|
||||
$name = '((' . $name . ' !== \'\')?(' . $name . '):' . $args[1] . ')';
|
||||
$name = '(' . $name . ' !== \'\'?' . $name . ':' . $args[1] . ')';
|
||||
}
|
||||
break;
|
||||
default: // 通用模板函数
|
||||
@@ -981,9 +971,9 @@ class Template
|
||||
$begin = $this->config['tpl_begin'];
|
||||
$end = $this->config['tpl_end'];
|
||||
if (strlen(ltrim($begin, '\\')) == 1 && strlen(ltrim($end, '\\')) == 1) {
|
||||
$regex = $begin . '((?:[\$\:\-\+][a-wA-w_][\w\.\:\[\(\*\/\-\+\%_]|\/[\*\/])(?>[^' . $end . ']*))' . $end;
|
||||
$regex = $begin . '((?:[\$\:\-\+~][\$a-wA-w_][\w\.\:\[\(\*\/\-\+\%_]|\/[\*\/])(?>[^' . $end . ']*))' . $end;
|
||||
} else {
|
||||
$regex = $begin . '((?:[\$\:\-\+][a-wA-w_][\w\.\:\[\(\*\/\-\+\%_]|\/[\*\/])(?>(?:(?!' . $end . ').)*))' . $end;
|
||||
$regex = $begin . '((?:[\$\:\-\+~][\$a-wA-w_][\w\.\:\[\(\*\/\-\+\%_]|\/[\*\/])(?>(?:(?!' . $end . ').)*))' . $end;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -24,17 +24,36 @@ class Url
|
||||
* @param boolean|string $domain 是否显示域名 或者直接传入域名
|
||||
* @return string
|
||||
*/
|
||||
public static function build($url = '', $vars = '', $suffix = true, $domain = true)
|
||||
public static function build($url = '', $vars = '', $suffix = true, $domain = false)
|
||||
{
|
||||
// 解析URL
|
||||
$info = parse_url($url);
|
||||
$url = !empty($info['path']) ? $info['path'] : '';
|
||||
if (isset($info['fragment'])) {
|
||||
// 解析锚点
|
||||
$anchor = $info['fragment'];
|
||||
if (false !== strpos($anchor, '?')) {
|
||||
// 解析参数
|
||||
list($anchor, $info['query']) = explode('?', $anchor, 2);
|
||||
}
|
||||
if (false !== strpos($anchor, '@')) {
|
||||
// 解析域名
|
||||
list($anchor, $domain) = explode('@', $anchor, 2);
|
||||
}
|
||||
} elseif (false !== strpos($url, '@')) {
|
||||
// 解析域名
|
||||
list($url, $domain) = explode('@', $info['path'], 2);
|
||||
}
|
||||
|
||||
// 解析参数
|
||||
if (is_string($vars)) {
|
||||
// aaa=1&bbb=2 转换成数组
|
||||
parse_str($vars, $vars);
|
||||
}
|
||||
|
||||
if (strpos($url, '?')) {
|
||||
list($url, $params) = explode('?', $url);
|
||||
parse_str($params, $params);
|
||||
if (isset($info['query'])) {
|
||||
// 解析地址里面参数 合并到vars
|
||||
parse_str($info['query'], $params);
|
||||
$vars = array_merge($params, $vars);
|
||||
}
|
||||
|
||||
@@ -63,22 +82,24 @@ class Url
|
||||
|
||||
// URL后缀
|
||||
$suffix = self::parseSuffix($suffix);
|
||||
// 锚点
|
||||
$anchor = !empty($anchor) ? '#' . $anchor : '';
|
||||
// 参数组装
|
||||
if (!empty($vars)) {
|
||||
// 添加参数
|
||||
if (Config::get('url_common_param')) {
|
||||
$vars = urldecode(http_build_query($vars));
|
||||
$url .= $suffix . '?' . $vars;
|
||||
$url .= $suffix . $anchor . '?' . $vars;
|
||||
} else {
|
||||
foreach ($vars as $var => $val) {
|
||||
if ('' !== trim($val)) {
|
||||
$url .= $depr . $var . $depr . urlencode($val);
|
||||
}
|
||||
}
|
||||
$url .= $suffix;
|
||||
$url .= $suffix . $anchor;
|
||||
}
|
||||
} else {
|
||||
$url .= $suffix;
|
||||
$url .= $suffix . $anchor;
|
||||
}
|
||||
|
||||
// 检测域名
|
||||
@@ -136,6 +157,8 @@ class Url
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$domain = $domain . (strpos($domain, '.') ? '' : strstr($_SERVER['HTTP_HOST'], '.'));
|
||||
}
|
||||
$domain = (self::isSsl() ? 'https://' : 'http://') . $domain;
|
||||
} else {
|
||||
@@ -226,7 +249,9 @@ class Url
|
||||
$key = array_shift($route);
|
||||
}
|
||||
$route = $route[0];
|
||||
if (strpos($route, '?')) {
|
||||
if (is_array($route)) {
|
||||
$route = implode('\\', $route);
|
||||
} elseif (strpos($route, '?')) {
|
||||
$route = strstr($route, '?', true);
|
||||
}
|
||||
$var = self::parseVar($rule . '/' . $key);
|
||||
@@ -234,7 +259,9 @@ class Url
|
||||
}
|
||||
} else {
|
||||
$route = $val['route'];
|
||||
if (strpos($route, '?')) {
|
||||
if (is_array($route)) {
|
||||
$route = implode('\\', $route);
|
||||
} elseif (strpos($route, '?')) {
|
||||
$route = strstr($route, '?', true);
|
||||
}
|
||||
$var = self::parseVar($rule);
|
||||
|
||||
@@ -41,23 +41,39 @@ abstract class Driver
|
||||
protected $_linkID = null;
|
||||
// 数据库连接参数配置
|
||||
protected $config = [
|
||||
'type' => '', // 数据库类型
|
||||
'hostname' => '127.0.0.1', // 服务器地址
|
||||
'database' => '', // 数据库名
|
||||
'username' => '', // 用户名
|
||||
'password' => '', // 密码
|
||||
'hostport' => '', // 端口
|
||||
'dsn' => '', //
|
||||
'params' => [], // 数据库连接参数
|
||||
'charset' => 'utf8', // 数据库编码默认采用utf8
|
||||
'prefix' => '', // 数据库表前缀
|
||||
'debug' => false, // 数据库调试模式
|
||||
'deploy' => 0, // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
|
||||
'rw_separate' => false, // 数据库读写是否分离 主从式有效
|
||||
'master_num' => 1, // 读写分离后 主服务器数量
|
||||
'slave_no' => '', // 指定从服务器序号
|
||||
'db_like_fields' => '', // like字段自动替换为%%包裹
|
||||
'debug' => false, // 是否调试
|
||||
// 数据库类型
|
||||
'type' => '',
|
||||
// 服务器地址
|
||||
'hostname' => '127.0.0.1',
|
||||
// 数据库名
|
||||
'database' => '',
|
||||
// 用户名
|
||||
'username' => '',
|
||||
// 密码
|
||||
'password' => '',
|
||||
// 端口
|
||||
'hostport' => '',
|
||||
'dsn' => '',
|
||||
// 数据库连接参数
|
||||
'params' => [],
|
||||
// 数据库编码默认采用utf8
|
||||
'charset' => 'utf8',
|
||||
// 数据库表前缀
|
||||
'prefix' => '',
|
||||
// 数据库调试模式
|
||||
'debug' => false,
|
||||
// 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
|
||||
'deploy' => 0,
|
||||
// 数据库读写是否分离 主从式有效
|
||||
'rw_separate' => false,
|
||||
// 读写分离后 主服务器数量
|
||||
'master_num' => 1,
|
||||
// 指定从服务器序号
|
||||
'slave_no' => '',
|
||||
// like字段自动替换为%%包裹
|
||||
'db_like_fields' => '',
|
||||
// 是否开启数据库调试
|
||||
'debug' => false,
|
||||
];
|
||||
// 数据库表达式
|
||||
protected $exp = ['eq' => '=', 'neq' => '<>', 'gt' => '>', 'egt' => '>=', 'lt' => '<', 'elt' => '<=', 'notlike' => 'NOT LIKE', 'like' => 'LIKE', 'in' => 'IN', 'notin' => 'NOT IN', 'not in' => 'NOT IN', 'between' => 'BETWEEN', 'not between' => 'NOT BETWEEN', 'notbetween' => 'NOT BETWEEN'];
|
||||
@@ -153,7 +169,9 @@ abstract class Driver
|
||||
$this->queryStr = $str;
|
||||
if (!empty($this->bind)) {
|
||||
$that = $this;
|
||||
$this->queryStr = strtr($this->queryStr, array_map(function ($val) use ($that) {return $that->quote($val);}, $this->bind));
|
||||
$this->queryStr = strtr($this->queryStr, array_map(function ($val) use ($that) {
|
||||
return $that->quote(is_array($val) ? $val[0] : $val);
|
||||
}, $this->bind));
|
||||
}
|
||||
if ($fetchSql) {
|
||||
return $this->queryStr;
|
||||
@@ -212,7 +230,9 @@ abstract class Driver
|
||||
$this->queryStr = $str;
|
||||
if (!empty($this->bind)) {
|
||||
$that = $this;
|
||||
$this->queryStr = strtr($this->queryStr, array_map(function ($val) use ($that) {return $that->quote($val);}, $this->bind));
|
||||
$this->queryStr = strtr($this->queryStr, array_map(function ($val) use ($that) {
|
||||
return $that->quote(is_array($val) ? $val[0] : $val);
|
||||
}, $this->bind));
|
||||
}
|
||||
if ($fetchSql) {
|
||||
return $this->queryStr;
|
||||
@@ -409,7 +429,7 @@ abstract class Driver
|
||||
} elseif (is_scalar($val)) {
|
||||
// 过滤非标量数据
|
||||
if (0 === strpos($val, ':') && in_array($val, array_keys($this->bind))) {
|
||||
$set[] = $this->parseKey($key) . '=' . $this->quote($val);
|
||||
$set[] = $this->parseKey($key) . '=' . $val;
|
||||
} else {
|
||||
$name = count($this->bind);
|
||||
$set[] = $this->parseKey($key) . '=:' . $name;
|
||||
@@ -890,7 +910,7 @@ abstract class Driver
|
||||
// 过滤非标量数据
|
||||
$fields[] = $this->parseKey($key);
|
||||
if (0 === strpos($val, ':') && in_array($val, array_keys($this->bind))) {
|
||||
$values[] = $this->parseValue($val);
|
||||
$values[] = $val;
|
||||
} else {
|
||||
$name = count($this->bind);
|
||||
$values[] = ':' . $name;
|
||||
@@ -932,7 +952,7 @@ abstract class Driver
|
||||
$value[] = 'NULL';
|
||||
} elseif (is_scalar($val)) {
|
||||
if (0 === strpos($val, ':') && in_array($val, array_keys($this->bind))) {
|
||||
$value[] = $this->parseValue($val);
|
||||
$value[] = $val;
|
||||
} else {
|
||||
$name = count($this->bind);
|
||||
$value[] = ':' . $name;
|
||||
|
||||
@@ -324,7 +324,10 @@ class TagLib
|
||||
$_taglibs[$tag][0] = strlen(ltrim($this->tpl->config('taglib_begin'), '\\') . $tag);
|
||||
$_taglibs[$tag][1] = strlen(ltrim($this->tpl->config('taglib_end'), '\\'));
|
||||
}
|
||||
$result['expression'] = trim(substr($str, $_taglibs[$tag][0], -$_taglibs[$tag][1]));
|
||||
$result['expression'] = substr($str, $_taglibs[$tag][0], -$_taglibs[$tag][1]);
|
||||
// 清除自闭合标签尾部/
|
||||
$result['expression'] = rtrim($result['expression'], '/');
|
||||
$result['expression'] = trim($result['expression']);
|
||||
} elseif (empty($this->tags[$tag]) || !empty($this->tags[$tag]['attr'])) {
|
||||
throw new Exception('_XML_TAG_ERROR_:' . $tag);
|
||||
}
|
||||
|
||||
@@ -253,7 +253,7 @@ class Cx extends Taglib
|
||||
{
|
||||
$name = !empty($tag['expression']) ? $tag['expression'] : $tag['name'];
|
||||
$name = $this->autoBuildVar($name);
|
||||
$parseStr = '<?php switch(' . $name . '): ?>' . $content . '<?php endswitch;?>';
|
||||
$parseStr = '<?php switch(' . $name . '): ?>' . $content . '<?php endswitch; ?>';
|
||||
return $parseStr;
|
||||
}
|
||||
|
||||
@@ -270,20 +270,20 @@ class Cx extends Taglib
|
||||
$flag = substr($value, 0, 1);
|
||||
if ('$' == $flag || ':' == $flag) {
|
||||
$value = $this->autoBuildVar($value);
|
||||
$value = 'case ' . $value . ': ';
|
||||
$value = 'case ' . $value . ':';
|
||||
} elseif (strpos($value, '|')) {
|
||||
$values = explode('|', $value);
|
||||
$value = '';
|
||||
foreach ($values as $val) {
|
||||
$value .= 'case "' . addslashes($val) . '": ';
|
||||
$value .= 'case "' . addslashes($val) . '":';
|
||||
}
|
||||
} else {
|
||||
$value = 'case "' . $value . '": ';
|
||||
$value = 'case "' . $value . '":';
|
||||
}
|
||||
$parseStr = '<?php ' . $value . ' ?>' . $content;
|
||||
$isBreak = isset($tag['break']) ? $tag['break'] : '';
|
||||
if ('' == $isBreak || $isBreak) {
|
||||
$parseStr .= '<?php break;?>';
|
||||
$parseStr .= '<?php break; ?>';
|
||||
}
|
||||
return $parseStr;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user