此类根据官方 core/lib/ext/verify.class.php 结合个人使用习惯修改而成
验证器类: common\lib\validation.class.php
<?php
/**
自动验证类
在模型文件中定义名为$roles的验证规则
protected $roles = array(
'nickname' => array(
'notnull' => array('both', '请填写昵称!',[$params]),
'length' => array('add', '昵称 长度必须在5-16 之间',[$params]),
'unique' => array('update', '昵称已存在!', [$params]),
),
);
//在模型文件中自定义验证方法的约定:
1.验证方法命名必须以check_开头
2.最多接受2个参数,$value为要验证的值,$params参数视情况使用,多个值使用数组传递
3.只返回true或false
4.多利用$valid_timing、$valid_data成员属性
protected function check_age($value,[$params]){
if($value < 1 || $value > 100) { return false; }else{ return true; }
}
*/
namespace lib;
use \z\db;
class validation extends db
{
//验证时机
protected $valid_timing;
//要验证的数据
protected $valid_data;
/**
* [create 主动验证]
* @param string $data [待验证的数据]
* @param string $timing ['add':添加数据时验证,'update':更新数据时验证,'both':添加和更新数据时都验证]
* @return boolean
*/
public function create($data = null, $timing = 'both')
{
if (empty($this->roles)) {return true;}
if (empty($data)) {$data = $_POST;}
$this->valid_data = $data;
$this->valid_timing = $timing;
$true_count = 0;
foreach ($this->roles as $field => &$role) {
$must = false;
if (isset($role['must'])) {
$must = $role['must'];
unset($role['must']);
}
if (!isset($data[$field]) && !$must) {
//表单数据无此项 且 验证规则must不为true 验证通过
$true_count++;
} elseif ($this->check_role($role, $data[$field])) {
$true_count++;
}
}
return $true_count == count($this->roles);
}
/**
* 验证一个字段的规则
* @param array $role 验证规则
* @param string $value 字段值
* @return boolean
*/
private function check_role($role, $value)
{
$true_count = 0;
foreach ($role as $role_name => &$role_value) {
$role_timing = $role_value[0];
if ($role_timing != $this->valid_timing and $role_timing != 'both') {
$true_count++;
} else {
$role_errmsg = $role_value[1];
$role_params = isset($role_value[2]) ? $role_value[2] : null;
$check_method = 'check_' . $role_name;
$ret = call_user_func(array($this, $check_method), $value, $role_params);
if ($ret) {
$true_count++;
} else {
parent::$dberror[] = $role_errmsg;
break; //有一个为假就停止验证
}
}
}
return $true_count == count($role);
}
#验证唯一值
/**
* 验证是否唯一值
* @param $value第一个参数为要验证的值;
* @param $key = func_get_arg(1) = 字段名;
* @return boolean
*/
private function check_unique($value)
{
$params = func_get_arg(1);
$key = is_array($params) ? $params[0] : $params;
if (!$key) {
parent::$dberror[] = 'check_unique参数错误';
return false;
}
if ('update' == $this->valid_timing) {
$pre = $this->exe();
$data = $pre->fetch(\PDO::FETCH_ASSOC);
if ($data[$key] == $value) {
return true;
}
}
$bind_key = ':' . $key;
$bind[$bind_key] = $value;
$sql = 'SELECT * FROM ' . $this->table . ' WHERE `' . $key . '`=' . $bind_key;
$pre = self::db()->prepare($sql);
$pre->execute($bind);
if ($pre->fetch(\PDO::FETCH_ASSOC)) {
return false;
} else {
return true;
}
}
#验证是否为空
/**
* 验证是否为空
* @param $value要验证的值
* @return boolean
*/
public static function check_notnull($value)
{
if ($value == '') {
return false;
} else {
return true;
}
}
#验证长度
/**
* 验证值的长度
* @param $value第一个参数为要验证的值
* @param $params = func_get_arg(1) $params[0] 最小值,$params[1] 最大值
* @return boolean
*/
public static function check_length($value)
{
$params = func_get_arg(1);
if (!is_array($params)) {
dump_file('check_length params error', 'validation_error.html');
}
$min = $params[0];
$max = $params[1];
$length = mb_strlen($value, 'UTF-8'); //兼容中文
if ($length < $min || $length > $max) {
return false;
} else {
return true;
}
}
#验证邮箱
/**
* 验证是否是邮箱
* @param $value为要验证的值
* @return boolean
*/
public static function check_email($value)
{
$preg = '/^[\w\.\-]+@[\w\-]+(\.\w+)+$/';
return preg_match($preg, $value);
}
#验证数字
/**
* 验证是否是数字
* @param $value为要验证的值
* @return boolean
*/
public static function check_number($value)
{
return is_numeric($value);
}
#验证两个值是否相同
/**
* 验证2个值是否相同
* @param $value为要验证的值
* @param $params = func_get_arg(1) $params[0] 为要比较的值
* @return boolean
*/
public static function check_eq($value)
{
$params = func_get_arg(1);
$eq_value = is_array($params) ? $params[0] : $params;
if ($value == $eq_value) {
return true;
} else {
return false;
}
}
#验证值的范围
/**
* 验证值的范围
* @param $value为要验证的值
* @param $params = func_get_arg(1) $params[0] 最小值,$params[1] 最大值
* @return boolean
*/
public static function check_between($value)
{
$params = func_get_arg(1);
if (!is_array($params)) {
dump_file('check_between params error', 'validation_error.html');
}
$min = $params[0];
$max = $params[1];
if ($value < $min || $value > $max) {
return false;
} else {
return true;
}
}
#正则验证
/**
* 通过正则验证
* @param $value为要验证的值
* @param $params = func_get_arg(1) $params[0] 正则表达式
* @return boolean
*/
public static function check_preg($value)
{
$params = func_get_arg(1);
$preg = is_array($params) ? $params[0] : $params;
return preg_match($preg, $value);
}
#验证ID
/**
* 验证是否合法id
* @param $value为要验证的值
* @return boolean
*/
public static function check_id($value)
{
return preg_match('/^[1-9][0-9]*$/', $value);
}
}
在模型中使用实例
<?php
namespace m;
use \lib\validation as V;
class sys_category extends V/*extends db*/
{
/* 自动验证规则
* 时机参数:both|add|update
* //'must' => true, //$data数组必须存在此键名
* //'notnull' => array('both','请输入0停用|1禁选|2正常!'), //此键值不能为空
*/
protected $roles = array(
'pid' => array(
'must' => true,
'notnull' => array('both', '请选择上级分类!'),
),
'title' => array(
'notnull' => array('both', '请输入分类名称!'),
'notsibling' => array('both', '本级已存在此名称!'),
),
'sort' => array(
'notnull' => array('both', '请输入排序数值!'),
),
'status' => array(
'notnull' => array('both', '请选择使用状态!'),
),
);
/**
* 获取多条数据
* @return array
*/
public function getList()
{
$order = 'pid asc,sort desc';
return $this->order($order)->select();
} //获取多条数据
/**
* 获取多条数据
* @return array
*/
public function getTop()
{
$where = array();
$where['pid'] = 0;
$order = 'pid asc,sort desc';
return $this->where($where)->order($order)->select();
} //获取多条数据
/**
* 表单数据处理
* @param string $scene 模式 add|edit
* @return mixed 数据操作后的返回值
*/
public function processForm($scene = 'add')
{
//$_POST预处理
$_POST['on_off'] = isset($_POST['on_off']) ? 1 : 0;
//数据操作
if ($scene == 'add') {
return $this->add($_POST);
} elseif ($scene == 'edit') {
$where['id'] = ID('ID');
return $this->where($where)->save($_POST);
}
} //表单数据处理
/**
* 获取一条数据
* @return array
*/
public function getInfo()
{
$where['id'] = ID();
return $this->where($where)->find();
} //获取一条数据
/**
* 验证是否同级中有相同名称
* @param $value为要验证的值;
* @return boolean
*/
protected function check_notsibling($value)
{
if (!$this->valid_data) {
parent::$dberror[] = '要验证的数据不存在';
return false;
}
$bind[':pid'] = $this->valid_data['pid'];
$bind[':title'] = $value;
if ('update' == $this->valid_timing) {
$bind[':id'] = $this->valid_data['ID'];
$sql = 'SELECT * FROM ' . $this->table . ' WHERE `id`<>:id and `title`=:title and pid=:pid';
} else {
$sql = 'SELECT * FROM ' . $this->table . ' WHERE `title`=:title and pid=:pid';
}
$pre = self::db()->prepare($sql);
$pre->execute($bind);
if ($pre->fetch(\PDO::FETCH_ASSOC)) {
return false;
} else {
return true;
}
} //验证同级中是否有相同名称
}
在模型文件中自定义验证方法说明
1. 验证方法命名必须以check_开头
2. 最多接受2个参数,$value为要验证的值。$params从$roles数组传递进来(如果有),多个值使用数组传递
3. 只能返回true或false
4. 可结合使用validation中的成员属性 $this->valid_timing,$this->valid_data,parent::$dberror[],$this->table