Merge remote-tracking branch 'origin/master'

This commit is contained in:
yunwuxin
2016-03-23 14:46:55 +08:00
18 changed files with 483 additions and 359 deletions

View File

@@ -23,9 +23,10 @@ defined('MODE_PATH') or define('MODE_PATH', THINK_PATH . 'mode' . DS); // 系统
defined('CORE_PATH') or define('CORE_PATH', LIB_PATH . 'think' . DS); defined('CORE_PATH') or define('CORE_PATH', LIB_PATH . 'think' . DS);
defined('TRAIT_PATH') or define('TRAIT_PATH', LIB_PATH . 'traits' . DS); defined('TRAIT_PATH') or define('TRAIT_PATH', LIB_PATH . 'traits' . DS);
defined('APP_PATH') or define('APP_PATH', dirname($_SERVER['SCRIPT_FILENAME']) . DS); defined('APP_PATH') or define('APP_PATH', dirname($_SERVER['SCRIPT_FILENAME']) . DS);
defined('ROOT_PATH') or define('ROOT_PATH', dirname(APP_PATH) . DS);
defined('APP_NAMESPACE') or define('APP_NAMESPACE', 'app'); defined('APP_NAMESPACE') or define('APP_NAMESPACE', 'app');
defined('COMMON_MODULE') or define('COMMON_MODULE', 'common'); defined('COMMON_MODULE') or define('COMMON_MODULE', 'common');
defined('RUNTIME_PATH') or define('RUNTIME_PATH', realpath(APP_PATH) . DS . 'runtime' . DS); defined('RUNTIME_PATH') or define('RUNTIME_PATH', ROOT_PATH . 'runtime' . DS);
defined('LOG_PATH') or define('LOG_PATH', RUNTIME_PATH . 'log' . DS); defined('LOG_PATH') or define('LOG_PATH', RUNTIME_PATH . 'log' . DS);
defined('CACHE_PATH') or define('CACHE_PATH', RUNTIME_PATH . 'cache' . DS); defined('CACHE_PATH') or define('CACHE_PATH', RUNTIME_PATH . 'cache' . DS);
defined('TEMP_PATH') or define('TEMP_PATH', RUNTIME_PATH . 'temp' . DS); defined('TEMP_PATH') or define('TEMP_PATH', RUNTIME_PATH . 'temp' . DS);

View File

@@ -52,6 +52,8 @@ return [
'default_controller' => 'Index', 'default_controller' => 'Index',
// 默认操作名 // 默认操作名
'default_action' => 'index', 'default_action' => 'index',
// 默认验证器
'default_validate' => '',
// 默认的空控制器名 // 默认的空控制器名
'empty_controller' => 'Error', 'empty_controller' => 'Error',
// 操作方法后缀 // 操作方法后缀

View File

@@ -28,6 +28,9 @@ class App
*/ */
public static function run() public static function run()
{ {
// 加载环境变量配置文件
Config::loadEnv(APP_PATH . 'env' . EXT);
// 初始化应用(公共模块) // 初始化应用(公共模块)
self::initModule(COMMON_MODULE, Config::get()); self::initModule(COMMON_MODULE, Config::get());
@@ -130,6 +133,7 @@ class App
break; break;
case 'PUT': case 'PUT':
parse_str(file_get_contents('php://input'), $vars); parse_str(file_get_contents('php://input'), $vars);
$vars = array_merge($_GET, $vars);
break; break;
default: default:
$vars = $_GET; $vars = $_GET;

View File

@@ -29,7 +29,6 @@ class Config
/** /**
* 解析配置文件或内容 * 解析配置文件或内容
*
* @param string $config 配置文件路径或内容 * @param string $config 配置文件路径或内容
* @param string $type 配置解析类型 * @param string $type 配置解析类型
* @param string $range 作用域 * @param string $range 作用域
@@ -46,7 +45,6 @@ class Config
/** /**
* 加载配置文件PHP格式 * 加载配置文件PHP格式
*
* @param string $file 配置文件名 * @param string $file 配置文件名
* @param string $name 配置名(如设置即表示二级配置) * @param string $name 配置名(如设置即表示二级配置)
* @param string $range 作用域 * @param string $range 作用域
@@ -63,9 +61,28 @@ class Config
return is_file($file) ? self::set(include $file, $name, $range) : self::$config[$range]; return is_file($file) ? self::set(include $file, $name, $range) : self::$config[$range];
} }
/**
* 加载环境变量配置文件
* @param string $file 配置文件名
* @param string $name 配置名(如设置即表示二级配置)
* @return void
*/
public static function loadEnv($file, $name = '')
{
if (is_file($file)) {
$env = include $file;
foreach ($env as $key => $val) {
if (!empty($name)) {
$_ENV[ENV_PREFIX . $name . '_' . $key] = $val;
} else {
$_ENV[ENV_PREFIX . $key] = $val;
}
}
}
}
/** /**
* 检测配置是否存在 * 检测配置是否存在
*
* @param string $name 配置参数名(支持二级配置 .号分割) * @param string $name 配置参数名(支持二级配置 .号分割)
* @param string $range 作用域 * @param string $range 作用域
* @return bool * @return bool
@@ -85,7 +102,6 @@ class Config
/** /**
* 获取配置参数 为空则获取所有配置 * 获取配置参数 为空则获取所有配置
*
* @param string $name 配置参数名(支持二级配置 .号分割) * @param string $name 配置参数名(支持二级配置 .号分割)
* @param string $range 作用域 * @param string $range 作用域
* @return mixed * @return mixed
@@ -119,7 +135,6 @@ class Config
/** /**
* 设置配置参数 name为数组则为批量设置 * 设置配置参数 name为数组则为批量设置
*
* @param string $name 配置参数名(支持二级配置 .号分割) * @param string $name 配置参数名(支持二级配置 .号分割)
* @param mixed $value 配置值 * @param mixed $value 配置值
* @param string $range 作用域 * @param string $range 作用域

View File

@@ -147,21 +147,33 @@ class Controller
* @param array $data 数据 * @param array $data 数据
* @param string|array $validate 验证器名或者验证规则数组 * @param string|array $validate 验证器名或者验证规则数组
* @param array $message 提示信息 * @param array $message 提示信息
* @param mixed $callback 回调方法(闭包)
* @return void * @return void
*/ */
public function validate($data, $validate, $message = []) public function validate($data, $validate, $message = [], $callback = null)
{ {
if (is_array($validate)) { if (is_array($validate)) {
$v = Loader::validate(); $v = Loader::validate(Config::get('default_validate'));
$v->rule($validate); $v->rule($validate);
} else { } else {
if (strpos($validate, '.')) {
// 支持场景
list($validate, $scene) = explode('.', $validate);
}
$v = Loader::validate($validate); $v = Loader::validate($validate);
if (!empty($scene)) {
$v->scene($scene);
}
} }
if (is_array($message)) { if (is_array($message)) {
$v->message($message); $v->message($message);
} }
if (is_callable($callback)) {
call_user_func_array($callback, [$v, &$data]);
}
if (!$v->check($data)) { if (!$v->check($data)) {
return $v->getError(); return $v->getError();
} else { } else {

View File

@@ -54,8 +54,6 @@ class Model
protected $scope = []; protected $scope = [];
// 字段映射定义 // 字段映射定义
protected $map = []; protected $map = [];
// 字段验证规则定义
protected $rule = [];
/** /**
* 架构函数 * 架构函数
@@ -991,12 +989,18 @@ class Model
if (!empty($this->options['validate'])) { if (!empty($this->options['validate'])) {
$info = $this->options['validate']; $info = $this->options['validate'];
if (is_array($info)) { if (is_array($info)) {
$validate = Loader::validate(); $validate = Loader::validate(Config::get('default_validate'));
$validate->rule($info['rule']); $validate->rule($info['rule']);
$validate->message($info['msg']); $validate->message($info['msg']);
} else { } else {
$name = is_string($info) ? $info : $this->name; $name = is_string($info) ? $info : $this->name;
if (strpos($name, '.')) {
list($name, $scene) = explode('.', $name);
}
$validate = Loader::validate($name); $validate = Loader::validate($name);
if (!empty($scene)) {
$validate->scene($scene);
}
} }
if (!$validate->check($data)) { if (!$validate->check($data)) {
$this->error = $validate->getError(); $this->error = $validate->getError();
@@ -1726,8 +1730,8 @@ class Model
public function order($field, $order = null) public function order($field, $order = null)
{ {
if (!empty($field)) { if (!empty($field)) {
if (!is_array($field)) { if (is_string($field)) {
$field = empty($order) ? [$field] : [(string) $field => (string) $order]; $field = empty($order) ? $field : [$field => $order];
} }
$this->options['order'] = $field; $this->options['order'] = $field;
} }

View File

@@ -32,58 +32,52 @@ class Validate
// 验证规则默认提示信息 // 验证规则默认提示信息
protected $typeMsg = [ protected $typeMsg = [
'require' => '不能为空', 'require' => ':attribute不能为空',
'number' => '必须是数字', 'number' => ':attribute必须是数字',
'float' => '必须是浮点数', 'float' => ':attribute必须是浮点数',
'boolean' => '必须是布尔值', 'boolean' => ':attribute必须是布尔值',
'email' => '格式不符', 'email' => ':attribute格式不符',
'array' => '必须是数组', 'array' => ':attribute必须是数组',
'accepted' => '必须是yes、on或者1', 'accepted' => ':attribute必须是yes、on或者1',
'date' => '格式不符合', 'date' => ':attribute格式不符合',
'alpha' => '只能是字母', 'alpha' => ':attribute只能是字母',
'alphaNum' => '只能是字母和数字', 'alphaNum' => ':attribute只能是字母和数字',
'alphaDash' => '只能是字母、数字和下划线_及破折号-', 'alphaDash' => ':attribute只能是字母、数字和下划线_及破折号-',
'activeUrl' => '不是有效的域名或者IP', 'activeUrl' => ':attribute不是有效的域名或者IP',
'url' => '不是有效的URL地址', 'url' => ':attribute不是有效的URL地址',
'ip' => '不是有效的IP地址', 'ip' => ':attribute不是有效的IP地址',
'dateFormat' => '必须使用日期格式 :rule', 'dateFormat' => ':attribute必须使用日期格式 :rule',
'in' => '必须在 :rule 范围内', 'in' => ':attribute必须在 :rule 范围内',
'notIn' => '不能在 :rule 范围内', 'notIn' => ':attribute不能在 :rule 范围内',
'between' => '只能在 :1 - :2 之间', 'between' => ':attribute只能在 :1 - :2 之间',
'notBetween' => '不能在 :1 - :2 之间', 'notBetween' => ':attribute不能在 :1 - :2 之间',
'length' => '长度不符合要求 :rule', 'length' => ':attribute长度不符合要求 :rule',
'max' => '长度不能超过 :rule', 'max' => ':attribute长度不能超过 :rule',
'min' => '长度不能小于 :rule', 'min' => ':attribute长度不能小于 :rule',
'after' => '日期不能小于 :rule', 'after' => ':attribute日期不能小于 :rule',
'before' => '日期不能超过 :rule', 'before' => ':attribute日期不能超过 :rule',
'expire' => '不在有效期内 :rule', 'expire' => '不在有效期内 :rule',
'allowIp' => '不允许的IP访问', 'allowIp' => '不允许的IP访问',
'denyIp' => '禁止的IP访问', 'denyIp' => '禁止的IP访问',
'confirm' => '和字段 :rule 不一致', 'confirm' => ':attribute和字段 :rule 不一致',
'egt' => '必须大于等于 :rule', 'egt' => ':attribute必须大于等于 :rule',
'gt' => '必须大于 :rule', 'gt' => ':attribute必须大于 :rule',
'elt' => '必须小于等于 :rule', 'elt' => ':attribute必须小于等于 :rule',
'lt' => '必须小于 :rule', 'lt' => ':attribute必须小于 :rule',
'eq' => '必须等于 :rule', 'eq' => ':attribute必须等于 :rule',
'unique' => '已存在', 'unique' => ':attribute已存在',
'regex' => '不符合指定规则', 'regex' => ':attribute不符合指定规则',
]; ];
// 当前验证场景 // 当前验证场景
protected $scene = null; protected $currentScene = null;
// 正则表达式 regex = ['zip'=>'\d{6}',...] // 正则表达式 regex = ['zip'=>'\d{6}',...]
protected $regex = []; protected $regex = [];
// 验证参数 // 验证场景 scene = ['edit'=>'name1,name2,...']
protected $config = [ protected $scene = [];
// 有值才验证 value_validate = [name1,name2,...]
'value_validate' => [],
// 存在就验证 exists_validate = [name1,name2,...]
'exists_validate' => [],
// 验证场景 scene = ['edit'=>'name1,name2,...']
'scene' => [],
];
// 验证失败错误信息 // 验证失败错误信息
protected $error = []; protected $error = [];
@@ -95,19 +89,11 @@ class Validate
* @access public * @access public
* @param array $rules 验证规则 * @param array $rules 验证规则
* @param array $message 验证提示信息 * @param array $message 验证提示信息
* @param array $config 验证参数
*/ */
public function __construct(array $rules = [], $message = [], $config = []) public function __construct(array $rules = [], $message = [])
{ {
$this->rule = array_merge($this->rule, $rules); $this->rule = array_merge($this->rule, $rules);
$this->message = array_merge($this->message, $message); $this->message = array_merge($this->message, $message);
$this->config = array_merge($this->config, $config);
if (is_string($this->config['value_validate'])) {
$this->config['value_validate'] = explode(',', $this->config['value_validate']);
}
if (is_string($this->config['exists_validate'])) {
$this->config['exists_validate'] = explode(',', $this->config['exists_validate']);
}
} }
/** /**
@@ -194,38 +180,23 @@ class Validate
return $this; return $this;
} }
/**
* 传入验证参数
* @access public
* @param string|array $name 参数名或者数组
* @param mixed $value 参数值
* @return Validate
*/
public function config($name, $value = null)
{
if (is_array($name)) {
$this->config = array_merge($this->config, $name);
} else {
$this->config[$name] = $value;
}
return $this;
}
/** /**
* 设置验证场景 * 设置验证场景
* @access public * @access public
* @param string $name 场景名 * @param string|array $name 场景名或者场景设置数组
* @param mixed $fields 要验证的字段 * @param mixed $fields 要验证的字段
* @return Validate * @return Validate
*/ */
public function scene($name, $fields = null) public function scene($name, $fields = null)
{ {
if (is_null($fields)) { if (is_array($name)) {
$this->scene = array_merge($this->scene, $name);
}if (is_null($fields)) {
// 设置当前场景 // 设置当前场景
$this->scene = $name; $this->currentScene = $name;
} else { } else {
// 设置验证场景 // 设置验证场景
$this->config['scene'][$name] = $fields; $this->scene[$name] = $fields;
} }
return $this; return $this;
} }
@@ -261,34 +232,43 @@ class Validate
// 分析验证规则 // 分析验证规则
$scene = $this->getScene($scene); $scene = $this->getScene($scene);
// 读取提示信息
if (isset($rules['__message__'])) {
$this->message($rules['__message__']);
unset($rules['__message__']);
}
foreach ($rules as $key => $rule) { foreach ($rules as $key => $item) {
// field => rule1|rule2... field=>['rule1','rule2',...]
if (is_numeric($key)) {
// [field,rule1|rule2,msg1|msg2]
$key = $item[0];
$rule = $item[1];
if (isset($item[2])) {
$msg = is_string($item[2]) ? explode('|', $item[2]) : $item[2];
} else {
$msg = [];
}
} else {
$rule = $item;
$msg = [];
}
if (strpos($key, '|')) { if (strpos($key, '|')) {
// 支持 字段|描述 用于返回默认错误 // 字段|描述 用于指定属性名称
list($key, $title) = explode('|', $key); list($key, $title) = explode('|', $key);
} else { } else {
$title = $key; $title = $key;
} }
// 场景检测 // 场景检测
if (!empty($scene) && !in_array($key, $scene)) { if (!empty($scene)) {
continue; if ($scene instanceof \Closure && !call_user_func_array($scene, [$key, &$data])) {
continue;
} elseif (is_array($scene) && !in_array($key, $scene)) {
continue;
}
} }
// 获取数据 支持二维数组 // 获取数据 支持二维数组
$value = $this->getDataValue($data, $key); $value = $this->getDataValue($data, $key);
if ((isset($this->config['value_validate']) && in_array($key, $this->config['value_validate']) && '' == $value) // 字段验证
|| (isset($this->config['exists_validate']) && in_array($key, $this->config['exists_validate']) && is_null($value))) { $result = $this->checkItem($key, $value, $rule, $data, $title, $msg);
// 不满足自动验证条件
continue;
}
// 验证字段规则
$result = $this->checkItem($key, $value, $rule, $data, $title);
if (true !== $result) { if (true !== $result) {
// 没有返回true 则表示验证失败 // 没有返回true 则表示验证失败
@@ -316,9 +296,10 @@ class Validate
* @param mixed $rules 验证规则 * @param mixed $rules 验证规则
* @param array $data 数据 * @param array $data 数据
* @param string $title 字段描述 * @param string $title 字段描述
* @return string|true * @param array $msg 提示信息
* @return mixed
*/ */
protected function checkItem($field, $value, $rules, &$data, $title = '') protected function checkItem($field, $value, $rules, &$data, $title = '', $msg = [])
{ {
if ($rules instanceof \Closure) { if ($rules instanceof \Closure) {
// 匿名函数验证 支持传入当前字段和所有字段两个数据 // 匿名函数验证 支持传入当前字段和所有字段两个数据
@@ -328,7 +309,7 @@ class Validate
if (is_string($rules)) { if (is_string($rules)) {
$rules = explode('|', $rules); $rules = explode('|', $rules);
} }
$error = []; $i = 0;
foreach ($rules as $key => $rule) { foreach ($rules as $key => $rule) {
if ($rule instanceof \Closure) { if ($rule instanceof \Closure) {
$result = call_user_func_array($rule, [$value, &$data]); $result = call_user_func_array($rule, [$value, &$data]);
@@ -347,34 +328,34 @@ class Validate
} else { } else {
$info = $type = $key; $info = $type = $key;
} }
// 验证类型
$callback = isset($this->type[$type]) ? $this->type[$type] : [$this, $type]; // 如果不是require 有数据才会行验证
// 验证数据 if (0 === strpos($info, 'require') || !empty($value)) {
$result = call_user_func_array($callback, [$value, $rule, &$data, $field]); // 验证类型
$callback = isset($this->type[$type]) ? $this->type[$type] : [$this, $type];
// 验证数据
$result = call_user_func_array($callback, [$value, $rule, &$data, $field]);
} else {
$result = true;
}
} }
if (false === $result) { if (false === $result) {
// 验证失败 返回错误信息 // 验证失败 返回错误信息
if (isset($this->message[$field . '.' . $info])) { if (isset($msg[$i])) {
$error[] = $this->message[$field . '.' . $info]; $message = $msg[$i];
} elseif (isset($this->message[$field . '.'])) {
$error[] = $this->message[$field . '.'];
} else { } else {
$error[] = $this->getTypeMsg($title ?: $field, $info, $rule); $message = $this->getRuleMsg($field, $title, $info, $rule);
} }
} elseif (is_string($result)) { return $message;
$error[] = $result; } elseif (true !== $result) {
} elseif (is_array($result)) { // 返回自定义错误信息
// 自定义错误信息数组
return $result; return $result;
} }
} $i++;
if (!empty($error)) {
$result = implode(',', $error);
} }
} }
// 验证失败返回错误信息 return true !== $result ? $result : true;
return $result;
} }
/** /**
@@ -541,26 +522,38 @@ class Validate
* 验证是否唯一 * 验证是否唯一
* @access protected * @access protected
* @param mixed $value 字段值 * @param mixed $value 字段值
* @param mixed $rule 验证规则 格式:数据表,字段名,排除ID * @param mixed $rule 验证规则 格式:数据表,字段名,排除ID,主键名
* @param array $data 数据 * @param array $data 数据
* @param string $field 验证字段名 * @param string $field 验证字段名
* @return bool * @return bool
*/ */
protected function unique($value, $rule, $data, $field) protected function unique($value, $rule, $data, $field)
{ {
$rule = explode(',', $rule); if (is_string($rule)) {
$rule = explode(',', $rule);
}
$model = Loader::table($rule[0]); $model = Loader::table($rule[0]);
$key = isset($rule[3]) ? $rule[3] : $model->getPk();
$field = isset($rule[1]) ? $rule[1] : $field; $field = isset($rule[1]) ? $rule[1] : $field;
if (strpos($field, '^')) {
// 支持多个字段验证
$fields = explode('^', $field);
foreach ($fields as $field) {
$map[$field] = $data[$field];
}
} elseif (strpos($field, '=')) {
parse_str($field, $map);
} else {
$map[$field] = $data[$field];
}
$key = strval(isset($rule[3]) ? $rule[3] : $model->getPk());
if (isset($rule[2])) { if (isset($rule[2])) {
$except = $rule[2]; $map[$key] = ['neq', $rule[2]];
} elseif (isset($data[$key])) { } elseif (isset($data[$key])) {
$except = $data[$key]; $map[$key] = ['neq', $data[$key]];
}
$map[$field] = $value;
if (isset($except)) {
$map[$key] = ['neq', $except];
} }
if ($model->where($map)->field($key)->find()) { if ($model->where($map)->field($key)->find()) {
return false; return false;
} }
@@ -589,18 +582,18 @@ class Validate
*/ */
protected function filter($value, $rule) protected function filter($value, $rule)
{ {
if (is_int($rule)) { if (is_string($rule) && strpos($rule, ',')) {
$param = null;
} elseif (is_string($rule) && strpos($rule, ',')) {
list($rule, $param) = explode(',', $rule); list($rule, $param) = explode(',', $rule);
} elseif (is_array($rule)) { } elseif (is_array($rule)) {
$param = isset($rule[1]) ? $rule[1] : null; $param = isset($rule[1]) ? $rule[1] : null;
} else {
$param = null;
} }
return false !== filter_var($value, is_int($rule) ? $rule : filter_id($rule), $param); return false !== filter_var($value, is_int($rule) ? $rule : filter_id($rule), $param);
} }
/** /**
* 验证某个字段的值等于某个值的时候必须 * 验证某个字段等于某个值的时候必须
* @access protected * @access protected
* @param mixed $value 字段值 * @param mixed $value 字段值
* @param mixed $rule 验证规则 * @param mixed $rule 验证规则
@@ -617,6 +610,24 @@ class Validate
} }
} }
/**
* 验证某个字段有值的情况下必须
* @access protected
* @param mixed $value 字段值
* @param mixed $rule 验证规则
* @param array $data 数据
* @return bool
*/
protected function requireWith($value, $rule, $data)
{
$val = $this->getDataValue($data, $rule);
if (!empty($val)) {
return !empty($value);
} else {
return true;
}
}
/** /**
* 验证是否在范围内 * 验证是否在范围内
* @access protected * @access protected
@@ -835,28 +846,39 @@ class Validate
} }
/** /**
* 获取验证规则的默认提示信息 * 获取验证规则的错误提示信息
* @access protected * @access protected
* @param string $attribute 字段名 * @param string $attribute 字段英文
* @param string $type 验证类型名称 * @param string $title 字段描述名
* @param mixed $rule 验证规则 * @param string $type 验证规则名称
* @param mixed $rule 验证规则数据
* @return string * @return string
*/ */
protected function getTypeMsg($attribute, $type, $rule) protected function getRuleMsg($attribute, $title, $type, $rule)
{ {
if (isset($this->typeMsg[$type])) { if (isset($this->message[$attribute . '.' . $type])) {
$msg = $this->message[$attribute . '.' . $type];
} elseif (isset($this->message[$attribute])) {
$msg = $this->message[$attribute];
} elseif (isset($this->typeMsg[$type])) {
$msg = $this->typeMsg[$type];
} else {
$msg = $title . '规则错误';
}
// TODO 多语言支持
if (is_string($msg) && false !== strpos($msg, ':')) {
// 变量替换
if (strpos($rule, ',')) { if (strpos($rule, ',')) {
$array = array_pad(explode(',', $rule), 3, ''); $array = array_pad(explode(',', $rule), 3, '');
} else { } else {
$array = array_pad([], 3, ''); $array = array_pad([], 3, '');
} }
return (false === strpos($this->typeMsg[$type], ':attribute') ? $attribute : '') . str_replace( $msg = str_replace(
[':rule', ':attribute', ':1', ':2', ':3'], [':attribute', ':rule', ':1', ':2', ':3'],
[(string) $rule, $attribute, $array[0], $array[1], $array[2]], [$title, (string) $rule, $array[0], $array[1], $array[2]],
$this->typeMsg[$type]); $msg);
} else {
return $attribute . '规则错误';
} }
return $msg;
} }
/** /**
@@ -869,12 +891,12 @@ class Validate
{ {
if (empty($scene)) { if (empty($scene)) {
// 读取指定场景 // 读取指定场景
$scene = $this->scene; $scene = $this->currentScene;
} }
if (!empty($scene) && isset($this->config['scene'][$scene])) { if (!empty($scene) && isset($this->scene[$scene])) {
// 如果设置了验证适用场景 // 如果设置了验证适用场景
$scene = $this->config['scene'][$scene]; $scene = $this->scene[$scene];
if (is_string($scene)) { if (is_string($scene)) {
$scene = explode(',', $scene); $scene = explode(',', $scene);
} }

View File

@@ -53,8 +53,9 @@ class File
} else { } else {
$current_uri = "cmd:" . implode(' ', $_SERVER['argv']); $current_uri = "cmd:" . implode(' ', $_SERVER['argv']);
} }
$runtime = number_format(microtime(true) - START_TIME, 6); $runtime = microtime(true) - START_TIME;
$reqs = number_format(1 / $runtime, 2); $reqs = number_format(1 / $runtime, 2);
$runtime = number_format($runtime, 6);
$time_str = " [运行时间:{$runtime}s] [吞吐率:{$reqs}req/s]"; $time_str = " [运行时间:{$runtime}s] [吞吐率:{$reqs}req/s]";
$memory_use = number_format((memory_get_usage() - START_MEM) / 1024, 2); $memory_use = number_format((memory_get_usage() - START_MEM) / 1024, 2);
$memory_str = " [内存消耗:{$memory_use}kb]"; $memory_str = " [内存消耗:{$memory_use}kb]";

View File

@@ -41,8 +41,9 @@ class Sae
} else { } else {
$current_uri = "cmd:" . implode(' ', $_SERVER['argv']); $current_uri = "cmd:" . implode(' ', $_SERVER['argv']);
} }
$runtime = number_format(microtime(true) - START_TIME, 6); $runtime = microtime(true) - START_TIME;
$reqs = number_format(1 / $runtime, 2); $reqs = number_format(1 / $runtime, 2);
$runtime = number_format($runtime, 6);
$time_str = " [运行时间:{$runtime}s] [吞吐率:{$reqs}req/s]"; $time_str = " [运行时间:{$runtime}s] [吞吐率:{$reqs}req/s]";
$memory_use = number_format((memory_get_usage() - START_MEM) / 1024, 2); $memory_use = number_format((memory_get_usage() - START_MEM) / 1024, 2);
$memory_str = " [内存消耗:{$memory_use}kb]"; $memory_str = " [内存消耗:{$memory_use}kb]";

View File

@@ -59,8 +59,9 @@ class Socket
if (!$this->check()) { if (!$this->check()) {
return false; return false;
} }
$runtime = number_format(microtime(true) - START_TIME, 6); $runtime = microtime(true) - START_TIME;
$reqs = number_format(1 / $runtime, 2); $reqs = number_format(1 / $runtime, 2);
$runtime = number_format($runtime, 6);
$time_str = " [运行时间:{$runtime}s][吞吐率:{$reqs}req/s]"; $time_str = " [运行时间:{$runtime}s][吞吐率:{$reqs}req/s]";
$memory_use = number_format((memory_get_usage() - START_MEM) / 1024, 2); $memory_use = number_format((memory_get_usage() - START_MEM) / 1024, 2);
$memory_str = " [内存消耗:{$memory_use}kb]"; $memory_str = " [内存消耗:{$memory_use}kb]";

View File

@@ -43,8 +43,9 @@ class Trace
return false; return false;
} }
// 获取基本信息 // 获取基本信息
$runtime = number_format(microtime(true) - START_TIME, 6); $runtime = microtime(true) - START_TIME;
$reqs = number_format(1 / $runtime, 2); $reqs = number_format(1 / $runtime, 2);
$runtime = number_format($runtime, 6);
$mem = number_format((memory_get_usage() - START_MEM) / 1024, 2); $mem = number_format((memory_get_usage() - START_MEM) / 1024, 2);
// 页面Trace信息 // 页面Trace信息

View File

@@ -31,28 +31,31 @@ trait View
{ {
if (empty($this->trueTableName)) { if (empty($this->trueTableName)) {
$tableName = ''; $tableName = '';
foreach ($this->viewFields as $key => $view) { $len = 0;
foreach ($this->viewFields as $name => $view) {
// 获取数据表名称 // 获取数据表名称
if (isset($view['_table'])) { if (isset($view['_table'])) {
// 2011/10/17 添加实际表名定义支持 可以实现同一个表的视图 // 2011/10/17 添加实际表名定义支持 可以实现同一个表的视图
$tableName .= $view['_table']; $tableName .= $view['_table'];
} else { } else {
$class = $key . 'Model'; $tableName .= \think\Loader::model($name)->getTableName();
$model = class_exists($class) ? new $class() : M($key);
$tableName .= $model->getTableName();
} }
// 表别名定义 // 表别名定义
$tableName .= !empty($view['_as']) ? ' ' . $view['_as'] : ' ' . $key; $tableName .= !empty($view['_as']) ? ' ' . $view['_as'] : ' ' . $name;
// 支持ON 条件定义 // 支持ON 条件定义
$tableName .= !empty($view['_on']) ? ' ON ' . $view['_on'] : ''; $tableName .= !empty($view['_on']) ? ' ON ' . $view['_on'] : '';
// 指定JOIN类型 例如 RIGHT INNER LEFT 下一个表有效 if (!empty($view['_type'])) {
$type = !empty($view['_type']) ? $view['_type'] : ''; // 指定JOIN类型 例如 RIGHT INNER LEFT 下一个表有效
$tableName .= ' ' . strtoupper($type) . ' JOIN '; $type = strtoupper($view['_type']);
$len = strlen($type . '_JOIN '); $tableName .= ' ' . $type . ' JOIN ';
if ($view == end($this->viewFields)) {
$len = strlen($type) + 7;
}
}
} }
$tableName = substr($tableName, 0, -$len); $this->trueTableName = $len ? substr($tableName, 0, -$len) : $tableName;
$this->trueTableName = $tableName;
} }
return $this->trueTableName; return $this->trueTableName;
} }
@@ -64,26 +67,43 @@ trait View
*/ */
protected function _options_filter(&$options) protected function _options_filter(&$options)
{ {
if (isset($options['field'])) { $viewFields = [];
$options['field'] = $this->checkFields($options['field']); foreach ($this->viewFields as $name => $val) {
} else { $k = isset($val['_as']) ? $val['_as'] : $name;
$options['field'] = $this->checkFields(); $val = $this->_checkFields($name, $val);
foreach ($val as $key => $field) {
if (is_numeric($key)) {
$viewFields[$k . '.' . $field] = $field;
} elseif ('_' != substr($key, 0, 1)) {
// 以_开头的为特殊定义
if (false !== strpos($key, '*') || false !== strpos($key, '(') || false !== strpos($key, '.')) {
//如果包含* 或者 使用了sql方法 则不再添加前面的表名
$viewFields[$key] = $field;
} else {
$viewFields[$k . '.' . $key] = $field;
}
}
}
} }
if (empty($options['field'])) {
$options['field'] = '*';
}
$options['field'] = $this->checkFields($options['field'], $viewFields);
if (isset($options['group'])) { if (isset($options['group'])) {
$options['group'] = $this->checkGroup($options['group']); $options['group'] = $this->checkGroup($options['group'], $viewFields);
} }
if (isset($options['where'])) { if (isset($options['where'])) {
$options['where'] = $this->checkCondition($options['where']); $options['where'] = $this->checkCondition($options['where'], $viewFields);
} }
if (isset($options['order'])) { if (isset($options['order'])) {
$options['order'] = $this->checkOrder($options['order']); $options['order'] = $this->checkOrder($options['order'], $viewFields);
} }
} }
/** /**
* 检查是否定义了所有字段 * 检查是否定义了所有字段
* @access protected * @access protected
* @param string $name 模型名称 * @param string $name 模型名称
* @param array $fields 字段数组 * @param array $fields 字段数组
* @return array * @return array
*/ */
@@ -94,161 +114,143 @@ trait View
$fields = array_merge($fields, \think\Loader::model($name)->getFields()); $fields = array_merge($fields, \think\Loader::model($name)->getFields());
unset($fields[$pos]); unset($fields[$pos]);
} }
return $fields; return $fields;
} }
/** /**
* 检查条件中的视图字段 * 检查条件中的视图字段
* @access protected * @access protected
* @param mixed $data 条件表达式 * @param mixed $data 条件表达式
* @param array $fields 视图字段数组
* @return array * @return array
*/ */
protected function checkCondition($where) protected function checkCondition($where, $viewFields)
{ {
if (is_array($where)) { if (is_array($where)) {
$view = []; $_where = [];
// 检查视图字段 foreach ($where as $field => $value) {
foreach ($this->viewFields as $key => $val) { if (false !== $k = array_search($field, $viewFields, true)) {
$k = isset($val['_as']) ? $val['_as'] : $key; // 存在视图字段
$val = $this->_checkFields($key, $val); $_where[$k] = $value;
foreach ($where as $name => $value) { } else {
if (false !== $field = array_search($name, $val, true)) { $_where[$field] = $value;
// 存在视图字段
$_key = is_numeric($field) ? $k . '.' . $name : $k . '.' . $field;
$view[$_key] = $value;
unset($where[$name]);
}
} }
} }
$where = array_merge($where, $view); return $_where;
} else {
return $where;
} }
return $where;
} }
/** /**
* 检查Order表达式中的视图字段 * 检查Order表达式中的视图字段
* @access protected * @access protected
* @param string $order 字段 * @param string|array $order 字段
* @param array $fields 视图字段数组
* @return string * @return string
*/ */
protected function checkOrder($order = '') protected function checkOrder($order = '', $viewFields)
{ {
if (is_string($order) && !empty($order)) { if (empty($order)) {
$orders = explode(',', $order); return '';
$_order = []; } elseif (is_string($order)) {
foreach ($orders as $order) { $order = explode(',', $order);
$array = explode(' ', $order);
$field = $array[0];
$sort = isset($array[1]) ? $array[1] : 'ASC';
// 解析成视图字段
foreach ($this->viewFields as $name => $val) {
$k = isset($val['_as']) ? $val['_as'] : $name;
$val = $this->_checkFields($name, $val);
if (false !== $_field = array_search($field, $val, true)) {
// 存在视图字段
$field = is_numeric($_field) ? $k . '.' . $field : $k . '.' . $_field;
break;
}
}
$_order[] = $field . ' ' . $sort;
}
$order = implode(',', $_order);
} }
return $order; $_order = [];
foreach ($order as $key => $field) {
if (is_numeric($key)) {
if ($pos = strpos($field, ' ')) {
$sort = substr($field, $pos);
$field = substr($field, 0, $pos);
} else {
$sort = '';
}
} else {
$sort = ' ' . $field;
$field = $key;
}
if (false !== $k = array_search($field, $viewFields, true)) {
// 存在视图字段
$field = $k . $sort;
}
$_order[] = $field;
}
return $_order;
} }
/** /**
* 检查Group表达式中的视图字段 * 检查Group表达式中的视图字段
* @access protected * @access protected
* @param string $group 字段 * @param string $group 字段
* @param array $fields 视图字段数组
* @return string * @return string
*/ */
protected function checkGroup($group = '') protected function checkGroup($group = '', $viewFields)
{ {
if (!empty($group)) { if (empty($group)) {
$groups = explode(',', $group); return '';
$_group = []; } elseif (is_string($group)) {
foreach ($groups as $field) { $group = explode(',', $group);
// 解析成视图字段
foreach ($this->viewFields as $name => $val) {
$k = isset($val['_as']) ? $val['_as'] : $name;
$val = $this->_checkFields($name, $val);
if (false !== $_field = array_search($field, $val, true)) {
// 存在视图字段
$field = is_numeric($_field) ? $k . '.' . $field : $k . '.' . $_field;
break;
}
}
$_group[] = $field;
}
$group = implode(',', $_group);
} }
return $group; foreach ($group as &$field) {
if (false !== $k = array_search($field, $viewFields, true)) {
// 存在视图字段
$field = $k;
}
}
return implode(',', $group);
} }
/** /**
* 检查fields表达式中的视图字段 * 检查fields表达式中的视图字段
* @access protected * @access protected
* @param string $fields 字段 * @param string $fields 字段
* @param array $fields 视图字段数组
* @return string * @return string
*/ */
protected function checkFields($fields = '') protected function checkFields($fields = '*', $viewFields)
{ {
if (empty($fields) || '*' == $fields) { var_dump($fields);
// 获取全部视图字段 if (is_string($fields)) {
$fields = []; if ('*' == $fields) {
foreach ($this->viewFields as $name => $val) { return $viewFields;
$k = isset($val['_as']) ? $val['_as'] : $name; } else {
$val = $this->_checkFields($name, $val);
foreach ($val as $key => $field) {
if (is_numeric($key)) {
$fields[] = $k . '.' . $field . ' AS ' . $field;
} elseif ('_' != substr($key, 0, 1)) {
// 以_开头的为特殊定义
if (false !== strpos($key, '*') || false !== strpos($key, '(') || false !== strpos($key, '.')) {
//如果包含* 或者 使用了sql方法 则不再添加前面的表名
$fields[] = $key . ' AS ' . $field;
} else {
$fields[] = $k . '.' . $key . ' AS ' . $field;
}
}
}
}
$fields = implode(',', $fields);
} else {
if (!is_array($fields)) {
$fields = explode(',', $fields); $fields = explode(',', $fields);
} }
// 解析成视图字段 }
$array = []; $_fields = [];
foreach ($fields as $key => $field) { foreach ($fields as $key => $field) {
if (strpos($field, '(') || strpos(strtolower($field), ' as ')) { if (is_numeric($key)) {
// 使用了函数或者别名 if ($pos = strpos($field, ' ')) {
$array[] = $field; $alias = substr($field, $pos);
unset($fields[$key]); $field = substr($field, 0, $pos);
} else {
$alias = ' AS ' . $field;
} }
} else {
$alias = ' AS ' . $field;
$field = $key;
} }
foreach ($this->viewFields as $name => $val) { if (strpos($field, '(')) {
$k = isset($val['_as']) ? $val['_as'] : $name; if (preg_match_all('/(?<!\s)\b(\w+)\b(?![\.\(])/', $field, $matches, PREG_OFFSET_CAPTURE)) {
$val = $this->_checkFields($name, $val); // 倒序找出的字段数组,以便从后向前替换
foreach ($fields as $key => $field) { $items = array_reverse($matches[0]);
if (false !== $_field = array_search($field, $val, true)) { foreach ($items as $item) {
// 存在视图字段 if (false !== $k = array_search($item[0], $viewFields, true)) {
if (is_numeric($_field)) { $field = substr_replace($field, $k, $item[1], strlen($item[0]));
$array[] = $k . '.' . $field . ' AS ' . $field;
} elseif ('_' != substr($_field, 0, 1)) {
if (false !== strpos($_field, '*') || false !== strpos($_field, '(') || false !== strpos($_field, '.')) {
//如果包含* 或者 使用了sql方法 则不再添加前面的表名
$array[] = $_field . ' AS ' . $field;
} else {
$array[] = $k . '.' . $_field . ' AS ' . $field;
}
} }
} }
} }
} elseif (false !== $k = array_search($field, $viewFields, true)) {
// 存在视图字段
$field = $k . $alias;
} }
$fields = implode(',', $array); $_fields[] = $field;
} }
return $fields;
return $_fields;
} }
} }

View File

@@ -124,6 +124,8 @@ class controllerTest extends \PHPUnit_Framework_TestCase
$viewFetch = $view->fetch($template, ['name' => 'ThinkPHP']); $viewFetch = $view->fetch($template, ['name' => 'ThinkPHP']);
$controllerFetch = $controller->fetch($template, ['name' => 'ThinkPHP']); $controllerFetch = $controller->fetch($template, ['name' => 'ThinkPHP']);
$this->assertEquals($controllerFetch, $viewFetch); $this->assertEquals($controllerFetch, $viewFetch);
$controllerFetch = $controller->display($template, ['name' => 'ThinkPHP']);
$this->assertEquals($controllerFetch, $viewFetch);
} }
public function testShow() public function testShow()
@@ -155,4 +157,31 @@ class controllerTest extends \PHPUnit_Framework_TestCase
$controller->engine('php'); $controller->engine('php');
$this->assertEquals('php', $view->engine); $this->assertEquals('php', $view->engine);
} }
public function testValidate()
{
$controller = new Foo;
$data = [
'username' => 'username',
'nickname' => 'nickname',
'password' => '123456',
'repassword' => '123456',
'email' => 'abc@abc.com',
'sex' => '0',
'age' => '20',
'code' => '1234',
];
$validate = [
['username', 'length:5,15', '用户名长度为5到15个字符'],
['nickname', 'require', '请填昵称'],
['password', '[\w-]{6,15}', '密码长度为6到15个字符'],
['repassword', 'confirm:password', '两次密码不一到致'],
['email', 'filter:validate_email', '邮箱格式错误'],
['sex', 'in:0,1', '性别只能为为男或女'],
['age', 'between:1,80', '年龄只能在10-80之间'],
];
$result = $controller->validate($data, $validate);
$this->assertTrue($result);
}
} }

View File

@@ -0,0 +1,28 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
/**
* Db类测试
*/
namespace tests\thinkphp\library\think;
use \think\Db;
class dbTest extends \PHPUnit_Framework_TestCase
{
public function testConnect()
{
Db::connect('mysql://root@127.0.0.1/test#utf8');
Db::execute('show databases');
}
}

View File

@@ -118,7 +118,7 @@ class debugTest extends \PHPUnit_Framework_TestCase
{ {
$useMem = Debug::getUseMem(); $useMem = Debug::getUseMem();
$this->assertLessThan(20, explode(" ", $useMem)[0]); $this->assertLessThan(30, explode(" ", $useMem)[0]);
} }
/** /**
@@ -135,7 +135,7 @@ class debugTest extends \PHPUnit_Framework_TestCase
$str .= "mem"; $str .= "mem";
} }
$memPeak = Debug::getMemPeak($start, $end); $memPeak = Debug::getMemPeak($start, $end);
$this->assertLessThan(400, explode(" ", $memPeak)[0]); $this->assertLessThan(500, explode(" ", $memPeak)[0]);
} }
/** /**

View File

@@ -42,6 +42,30 @@ class loaderTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(true, Loader::autoload('top\test\Hello')); $this->assertEquals(true, Loader::autoload('top\test\Hello'));
} }
public function testAddNamespaceAlias()
{
Loader::addNamespaceAlias('top', 'top\test');
Loader::addNamespaceAlias(['top' => 'top\test', 'app' => 'app\index']);
//$this->assertEquals(true, Loader::autoload('top\Hello'));
}
public function testTable()
{
Loader::table('', [
'connection' => [
'type' => 'mysql',
'database' => 'test',
'username' => 'root',
'password' => '',
]]);
Loader::db('mysql://root@127.0.0.1/test#utf8');
}
public function testInstance()
{
Loader::instance('\think\Validate');
}
public function testImport() public function testImport()
{ {
$this->assertEquals(true, Loader::import('think.log.driver.Sae')); $this->assertEquals(true, Loader::import('think.log.driver.Sae'));

View File

@@ -36,62 +36,30 @@ class modelTest extends \PHPUnit_Framework_TestCase
public function testValidate() public function testValidate()
{ {
/* $model = new Model('', $this->getConfig());
$model = new Model('', $this->getConfig()); $data = [
$data = $_POST = [ 'username' => 'username',
'username' => 'username', 'nickname' => 'nickname',
'nickname' => 'nickname', 'password' => '123456',
'password' => '123456', 'repassword' => '123456',
'repassword' => '123456', 'email' => 'abc@abc.com',
'mobile' => '13800000000', 'sex' => '0',
'email' => 'abc@abc.com', 'age' => '20',
'sex' => '0', 'code' => '1234',
'age' => '20', ];
'code' => '1234',
];
$validate = [ $validate = [
'__pattern__' => [ ['username', 'length:5,15', '用户名长度为5到15个字符'],
'mobile' => '/^1(?:[358]\d|7[6-8])\d{8}$/', ['nickname', 'require', '请填昵称'],
'require' => '/.+/', ['password', '[\w-]{6,15}', '密码长度为6到15个字符'],
], ['repassword', 'confirm:password', '两次密码不一到致'],
'__all__' => [ ['email', 'filter:validate_email', '邮箱格式错误'],
'code' => function ($value, $data) { ['sex', 'in:0,1', '性别只能为为男或女'],
return '1234' != $value ? 'code error' : true; ['age', 'between:1,80', '年龄只能在10-80之间'],
}, ];
], $result = $model->validate($validate)->create($data);
'user' => [ $this->assertEmpty($model->getError());
['username', [ & $this, 'checkName'], '用户名长度为5到15个字符', 'callback', 'username'],
['username', function ($value, $data) {
return 'admin' == $value ? '此用户名已被使用' : true;
}],
'nickname' => ['require', '请填昵称'],
'password' => ['[\w-]{6,15}', '密码长度为6到15个字符'],
'repassword' => ['password', '两次密码不一到致', 'confirm'],
'mobile' => ['mobile', '手机号错误'],
'email' => ['validate_email', '邮箱格式错误', 'filter'],
'sex' => ['0,1', '性别只能为为男或女', 'in'],
'age' => ['1,80', '年龄只能在10-80之间', 'between'],
'__option__' => [
'scene' => [
'add' => 'username,nickname,password,repassword,mobile,email,age,code',
'edit' => 'nickname,password,repassword,mobile,email,sex,age,code',
],
'value_validate' => 'email',
'exists_validate' => 'password,repassword,code',
'patch' => true,
],
],
];
Config::set('validate', $validate);
$result = $model->validate('user.add')->create();
$this->assertEmpty($model->getError());
unset($data['password'], $data['repassword']);
$data['email'] = '';
$result = $model->validate('user.edit')->create($data);
$this->assertEmpty($model->getError());
*/
} }
public function checkName($value, $field) public function checkName($value, $field)

View File

@@ -47,39 +47,40 @@ class validateTest extends \PHPUnit_Framework_TestCase
public function testRule() public function testRule()
{ {
$rule = [ $rule = [
'name' => 'require|alphaNum|max:25', 'name' => 'require|alphaNum|max:25|expire:2016-1-1,2026-1-1',
'account' => 'alphaDash|min:4|length:4,30', 'account' => 'requireIf:name,thinkphp|alphaDash|min:4|length:4,30',
'age' => 'number|between:1,120', 'age' => 'number|between:1,120',
'email' => 'email', 'email' => 'requireWith:name|email',
'url' => 'activeUrl', 'host' => 'activeUrl',
'url' => 'url',
'ip' => 'ip', 'ip' => 'ip',
'score' => 'float|gt:60', 'score' => 'float|gt:60|notBetween:90,100|notIn:70,80|lt:100|elt:100|egt:60',
'status' => 'integer|in:0,1,2', 'status' => 'integer|in:0,1,2',
'begin_time' => 'after:2016-3-18', 'begin_time' => 'after:2016-3-18',
'end_time' => 'before:2016-10-01', 'end_time' => 'before:2016-10-01',
'info' => 'require|array', 'info' => 'require|array',
'info.name' => 'require|length:8|alpha|same:thinkphp',
'value' => 'same:100', 'value' => 'same:100',
'bool' => 'boolean', 'bool' => 'boolean',
]; ];
$data = [ $data = [
'name' => 'thinkphp', 'name' => 'thinkphp',
'account' => 'liuchen', 'account' => 'liuchen',
'age' => 10, 'age' => 10,
'email' => 'thinkphp@qq.com', 'email' => 'thinkphp@qq.com',
'url' => 'thinkphp.cn', 'host' => 'thinkphp.cn',
'url' => 'http://thinkphp.cn/topic',
'ip' => '114.34.54.5', 'ip' => '114.34.54.5',
'score' => '89.15', 'score' => '89.15',
'status' => 1, 'status' => 1,
'begin_time' => '2016-3-20', 'begin_time' => '2016-3-20',
'end_time' => '2016-5-1', 'end_time' => '2016-5-1',
'info' => [1, 2, 3], 'info' => [1, 2, 3, 'name' => 'thinkphp'],
'zip' => '200000', 'zip' => '200000',
'date' => '16-3-8', 'date' => '16-3-8',
'ok' => 'yes', 'ok' => 'yes',
'value' => 100, 'value' => 100,
'bool' => 'true', 'bool' => 'true',
]; ];
$validate = new Validate($rule); $validate = new Validate($rule);
$validate->rule('zip', '/^\d{6}$/'); $validate->rule('zip', '/^\d{6}$/');
@@ -104,19 +105,6 @@ class validateTest extends \PHPUnit_Framework_TestCase
]); ]);
} }
public function testConfig()
{
$validate = new Validate();
$validate->config('value_validate', ['name', 'age', 'email']);
$validate->config([
'value_validate' => ['name', 'age', 'email'],
'exists_validate' => ['zip'],
'scene' => [
'edit' => ['name', 'age', 'email'],
],
]);
}
public function testMake() public function testMake()
{ {
$rule = [ $rule = [
@@ -169,4 +157,25 @@ class validateTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(true, $result); $this->assertEquals(true, $result);
} }
public function testSetTypeMsg()
{
$rule = [
'name|名称' => 'require|max:25',
'age' => 'number|between:1,120',
'email' => 'email',
['sex', 'in:1,2', '性别错误'],
];
$data = [
'name' => '',
'age' => 10,
'email' => 'thinkphp@qq.com',
'sex' => '3',
];
$validate = new Validate($rule);
$validate->setTypeMsg('require', ':attribute必须');
$result = $validate->batch()->check($data);
$this->assertFalse($result);
$this->assertEquals(['name' => '名称必须', 'sex' => '性别错误'], $validate->getError());
}
} }