PHP表单提交参数验证类(可修改)

2020-08-14 11:27:59 浏览数 (1)

代码语言:javascript复制
<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

/**
 * 表单验证类(参考 原ci  CI_Form_validation 而修改)
 * 自行扩展里头验证器
 */
class CI_Form_validation {

	protected $CI;
	protected $_model;
	//属性值及规则数组
	protected $_field_data			= array();
	//错误所提示的信息
	protected $_error_messages		= array();
	//收集到的错误
	protected $_error_array 		= array();
	//是否验证所有内容
	protected $_is_vail_all			= FALSE;
	//验证字段
	public $rule_field = array();

	// private $_validation_data = array();


	public function __get($key){

		return $this->_field_data[$key]['content'];

	}

	public function __set($key,$value){

		$this->_field_data[$key]['content'] = $value;

	}

	public function get_data(){

		$content = array();
		foreach ($this->_field_data as $key => $value) {
			$content[$key] = $value['content'];
		}
		return $content;

	}

	/**
	 * 获取有验证规则的数据
	 * @return [type] [description]
	 */
	public function get_safe_data(){
		$content = array();
		foreach ($this->_field_data as $key => $value) {

			if(in_array($key, $this->rule_field))
				$content[$key] = $value['content'];
		}
		return $content;
	}

	/**
	 * 属性赋值
	 * @param [type] $data [description]
	 */
	public function set_data($data){
		$this->_set_data($data);
	}

	/**
	 * 属性赋值
	 * @param $data
	 */
	protected function _set_data($data){
		foreach ($data as $key => $value) {
			if(is_array($value)){
				foreach($value as $vkey => $vvalue){
					$value[$key.'.'.$vkey] = $vvalue;
				}
				$this->_set_data($value);
			}
			$this->_field_data[$key]['content'] = $value;
		}
	}

	/**
	 * Constructor
	 */
	public function __construct($rules = array())
	{
		$this->CI =& get_instance();
		$this->_model = $this->CI;
	}

	/**
	 * 设置规则
	 * @param [type] $field         属性
	 * @param string $label         属性名称
	 * @param array  $rules         规则
	 * @param [type] $error_message [description]
	 */
	public function set_rule($field, $label = '', $rules = array(), $error_message=null){
		$add_rule = false;
		if(strstr($field,'.')){
			$search_field = substr($field,0,strrpos($field,'.'));
			$fields = array_keys($this->_field_data);
			foreach($fields as $fk => $fv){
				if($fv == $search_field){
					$add_rule = true;
				}
			}
		}else{
			$add_rule = true;
		}

		if($add_rule){
			if(is_string($rules))
				$rules =  explode('|', $rules);

			$this->_field_data[$field]['field'] = $field;
			$this->_field_data[$field]['label'] = $label;
			$this->_field_data[$field]['rules'] = $rules;

			if($error_message){
				foreach ($rules as $rule) {
					$this->_error_messages[$field][$rule] = $error_message;
				}
			}
			array_push($this->rule_field, $field);
			return $this;
		}
	}

	/**
	 * 批量设置规则
	 * @param Array $data [description]
	 */
	public function set_rules(Array $data){
		foreach ($data as $key => $value) {
			$this->set_rule($value[0],$value[1],$value[2]);
		}
	}

	/**
	 * 验证所有属性,并收集错误
	 * @return [type] [description]
	 */
	public function run(){
		$this->_validate_data($this->_field_data);
		//判断是否验证通过
		if(count($this->_error_array)>0){
			return false;
		}
		return true;

	}

	/**
	 ** 验证所有属性,并收集错误
	 * @param array $form_data
	 */
	protected function _validate_data($form_data = []){
		foreach($form_data as $key => $field) {
			if(!empty($field['rules'])){
				//非必需属性,且为空,不做验证,返回true
				if(!in_array('required', $field['rules']) && empty($field['content'])){
					$result = true;
				}
				//必需属性,且为空,不做验证,返回false
				elseif(in_array('required', $field['rules']) && empty($field['content'])){
					array_push($this->_error_array, $field['label'].'不得为空');
					$result = false;
				}
				// 属性不为空,则验证
				else{
					$result = $this->_execute($key,$field['label'],$field['rules'],$field['content']);
				}
				// 验证到错误,则不继续往下验证
				if($this->_is_vail_all==false && $result == false){
					break;
				}
			}
		}
	}

	/**
	 * Executes the Validation routines
	 *
	 * @param	array
	 * @param	array
	 * @param	mixed
	 * @param	int
	 * @return	mixed
	 */
	protected function _execute($field, $label, $rules, $content){

		//循环验证规则
		foreach ($rules as $rule){

			if($rule == 'required'){
				$result = true;
				continue;
			}

			$param = FALSE;
			if ( preg_match('/(.*?)[(.*)]/', $rule, $match)){

				$rule = $match[1];
				$param = $match[2];
			}

			if( method_exists($this->_model, $rule)){

				$result = $this->_model->$rule( $field, $content, $param, $this);
			}
			elseif( method_exists($this, $rule)){

				$result = $this->$rule($field, $content, $param);
			}
			else{

				log_message('debug', 'Unable to find callback validation rule: '.$rule);
				$result = FALSE;
			}

			// 验证到错误,则不继续往下验证
			if($this->_is_vail_all==false && $result == false){

				break;
			}
		}

		return $result;
	}


	public function get_label_by_field($field){

		return $this->_field_data[$field]['label'];
	}

	/**
	 * 获取最新的一条错误信息
	 * @return [type] [description]
	 */
	public function get_newone_error(){
		if(empty($this->_error_array)){
			return null;
		}else{
			return end($this->_error_array);
		}
	}

	/**
	 * 添加错误信息
	 * @param [type] $msg [description]
	 */
	public function add_error($msg){
		array_push($this->_error_array, $msg);
	}

	/**
	 * reset form
	 * @return [type] [description]
	 */
	public function reset(){
		$this->_field_data	= array();
		//错误所提示的信息
		$this->_error_messages = array();
		//收集到的错误
		$this->_error_array = array();
		//是否验证所有内容
		$this->_is_vail_all	= FALSE;
		//验证字段
		$this->rule_field = array();

	}

	/**
	 * 以下方法为验证器
	 *
	 */

	/**
	 * 安全字段不做验证
	 * @param  [type] $field   [description]
	 * @param  [type] $content [description]
	 * @param  [type] $param   [description]
	 * @return [type]          [description]
	 */
	public function safe($field, $content, $param){
		return true;
	}


	/**
	 * 验证最大长度
	 *
	 * @param [type] $field
	 *            [description]
	 * @param [type] $content
	 *            [description]
	 * @param [type] $param
	 *            [description]
	 * @return [type] [description]
	 */
	public function max_length($field, $content, $param)
	{
		if (mb_strlen($content) > $param) {
			$msg = $this->get_label_by_field($field) . '不得超过' . $param . '字符';
			$method_arr = explode(':', __METHOD__);
			$method = $method_arr[count($method_arr) - 1];
			$this->add_error($msg, $field, $method);
			return false;
		}
		return true;
	}

	/**
	 * 验证最小长度
	 *
	 * @param [type] $field
	 *            [description]
	 * @param [type] $content
	 *            [description]
	 * @param [type] $param
	 *            [description]
	 * @return [type] [description]
	 */
	public function min_length($field, $content, $param)
	{
		if (mb_strlen($content) < $param) {
			$msg = $this->get_label_by_field($field) . '不得少于' . $param . '字符';
			$method_arr = explode(':', __METHOD__);
			$method = $method_arr[count($method_arr) - 1];
			$this->add_error($msg, $field, $method);
			return false;
		}
		return true;
	}

	/**
	 * 验证是否为数字
	 *
	 * @param [type] $field
	 *            [description]
	 * @param [type] $content
	 *            [description]
	 * @param [type] $param
	 *            [description]
	 * @return [type] [description]
	 */
	public function numeric($field, $content, $param)
	{
		if (! is_numeric($content)) {
			$msg = $this->get_label_by_field($field) . '必需为数字';
			$method_arr = explode(':', __METHOD__);
			$method = $method_arr[count($method_arr) - 1];
			$this->add_error($msg, $field, $method);
			return false;
		}
		return true;
	}


	/**
	 * 验证参数是否在字符串中
	 * @param  [type] $field   [description]
	 * @param  [type] $content [description]
	 * @param  [type] $param   [description]
	 * @return [type]          [description]
	 */
	public function in_key_string($field, $content, $param){

		$arr = explode(',', $param);
		if(!in_array($content, $arr)){
			$msg = $this->get_label_by_field($field).'不合法';
			$this->add_error($msg);
			return false;
		}
		return true;
	}

	/**
	 * 验证是否为日期格式 (类似:2011-10-02)
	 * @param  [type] $field   [description]
	 * @param  [type] $content [description]
	 * @param  [type] $param   [description]
	 * @return [type]          [description]
	 */
	public function date_format($field, $content, $param){
		$pattern = '/^([1-2]d{3})-(0?[1-9]|10|11|12)-([1-2]?[0-9]|0[1-9]|30|31)$/i';
		if(!preg_match($pattern, $content)){
			$msg = $this->get_label_by_field($field).'必需为正确的日期格式';
			$this->add_error($msg);
			return false;
		}
		return true;
	}

	/**
	 * 验证时间格式(类似 08:00:00,24小时制度,从00:00:00到23:59:59)
	 */
	public function time_format($field, $content, $param){
		$pattern = '/^([0-1]d|2[0-3]):([0-5]d):([0-5]d)$/i';
		if (! preg_match($pattern, $content)) {
			$msg = $this->get_label_by_field($field) . '必需为正确的时间格式';
			$method_arr = explode(':', __METHOD__);
			$method = $method_arr[count($method_arr) - 1];
			$this->add_error($msg, $field, $method);
			return false;
		}
		return true;
	}

	/**
	 * 验证邮箱
	 * @param  [type] $field   [description]
	 * @param  [type] $content [description]
	 * @param  [type] $param   [description]
	 * @return [type]          [description]
	 */
	public function email($field, $content, $param){
		$pattern = "/^([a-z0-9 _-] )(.[a-z0-9 _-] )*@([a-z0-9-] .) [a-z]{2,6}$/ix";
		if(!preg_match($pattern, $content)){
			$msg = $this->get_label_by_field($field).'必需为正确的格式';
			$this->add_error($msg);
			return false;
		}
		return true;
	}

	/**
	 * 身份证验证
	 * (1、15位或18位,如果是15位,必需全是数字。2、如果是18位,最后一位可以是数字或字母Xx,其余必需是数字。)
	 * @param  [type] $field   [description]
	 * @param  [type] $content [description]
	 * @param  [type] $param   [description]
	 * @return [type]          [description]
	 */
	public function card_id($field, $content, $param){
		$pattern = "/^(d{15}$|^d{18}$|^d{17}(d|X|x))$/";
		if(!preg_match($pattern, $content)){
			$msg = $this->get_label_by_field($field).'必需为正确的格式';
			$this->add_error($msg);
			return false;
		}
		return true;
	}

	/**
	 * 验证手机号码
	 * @param  [type] $field   [description]
	 * @param  [type] $content [description]
	 * @param  [type] $param   [description]
	 * @return [type]          [description]
	 */
	public function phone($field, $content, $param){
		$pattern = "/^1[3|4|5|7|8][0-9]{9}$/";
		if(!preg_match($pattern, $content)){
			$msg = $this->get_label_by_field($field).'必需为正确的格式';
			$this->add_error($msg);
			return false;
		}
		return true;
	}

	/**
	 * 验证qq号码
	 * @param  [type] $field   [description]
	 * @param  [type] $content [description]
	 * @param  [type] $param   [description]
	 * @return [type]          [description]
	 */
	public function qq($field, $content, $param){
		$pattern = "/^[1-9]d{4,}$/";
		if(!preg_match($pattern, $content)){
			$msg = $this->get_label_by_field($field).'必需为正确的格式';
			$this->add_error($msg);
			return false;
		}
		return true;
	}

	/**
	 * 固定电话
	 * @param  [type] $field   [description]
	 * @param  [type] $content [description]
	 * @param  [type] $param   [description]
	 * @return [type]          [description]
	 */
	public function tel($field, $content, $param){
		$pattern = "/^d{2,5}-d{7,8}(-d{1,})?$/";
		if(!preg_match($pattern, $content)){
			$msg = $this->get_label_by_field($field).'必需为正确的格式';
			$this->add_error($msg);
			return false;
		}
		return true;
	}

	public function city_required($field, $content, $param){
		if(empty($content) || $content=='9999'){
			$msg = $this->get_label_by_field($field).'必需选择到城市';
			$this->add_error($msg);
			return false;
		}
		return true;
	}


	/**
	 * 验证最大值,包含等于
	 */
	public function max($field, $content, $param){
		if (intval($content) > intval($param)) {
			$msg = $this->get_label_by_field($field) . '不得大于' . $param . '';
			$method_arr = explode(':', __METHOD__);
			$method = $method_arr[count($method_arr) - 1];
			$this->add_error($msg, $field, $method);
			return false;
		}
		return true;
	}

	/**
	 * 验证最小值,包含等于
	 */
	public function min($field, $content, $param){
		if (intval($content) < intval($param)) {
			$msg = $this->get_label_by_field($field) . '不得小于' . $param . '';
			$method_arr = explode(':', __METHOD__);
			$method = $method_arr[count($method_arr) - 1];
			$this->add_error($msg, $field, $method);
			return false;
		}
		return true;
	}


}

用法:先引入上面文件,在调用,以下为调用方法。

代码语言:javascript复制
        /** =====数据验证===== */
        $this->load->library('form_validation');
        $rules = [
            ['otaOrderId','订单标号','required'],
            ['supplierId','供应商id','required'],
            ['supplierPhone','供应商手机号','required|phone'],
            ['contact','订单联系人','required'],
            ['contact.phone','订单联系人手机号','required|phone'],
            ['contact.name','订单联系人姓名','required'],
            ['items','订单产品','required'],
            ['items.id','合作方产品ID','required'],
            ['items.sku','合作方产品sku','required'],
            ['items.name','产品名称','required'],
            ['items.props','产品sku属性','required'],
            ['items.qty','下单数量','required|numeric'],
            ['items.extra.name','产品额外信息字段名','required'],
            ['items.extra.content','产品额外信息字段值','required'],
        ];
        // 设置表单规则
        $this->form_validation->set_rules($rules);

        // 给表单赋值
        $this->form_validation->set_data($body);

        //表单验证是否符合规则
        $result = $this->form_validation->run();
        if( $result === false){
            $error = $this->form_validation->get_newone_error();
            $this->output(self::PARAM_IS_INVALID,$error);
        }
        /** =====数据验证结束=====*/

0 人点赞