php實現表單驗證類

<?php
/**
 *  用法
 *  use Validate\Validator;
 *  
 *  $rules = [ 
 *       ['name|名字', 'require|email|in:7,8,9|max:10|min:6|between:6,8|length:2', '名字不能爲空|名字必須必須爲正確的郵件地址'],
 *       ['test|測試', 'require'],
 *   ];
 *  $data = ['name' => '8gAg:'];
 *  $validator = new Validator($rules);
 *  $validator->addRule(['name|名字', 'regex', '/^[0-8|a-z]+$/', '正則驗證失敗哦']);  //可以爲二維數組,有|的正則驗證只能通過addRule。
 *  $validator->validate($data);
 *  $validator->getAllErrors(); //獲取所有驗證錯誤 array
 *  $validator->getError();  //獲取第一條驗證錯誤 string
 *  Validator::in('7,8,9', 8);  //靜態調用
 *  Validator::isEmail('[email protected]');
 */
namespace Validate;

class Validator {
    
    //錯誤信息
    private $error = [];
    
    //傳入的驗證規則
    private $validate = [];
    
    //需要驗證的參數
    private $data = [];
    
    //添加的規則
    private $add_rules = [];
    
    //默認錯誤提示
    private $error_msg = [
        'require' => ':attribute不能爲空',
        'number'  => ':attribute必須爲數字',
        'array'   => ':attribute必須爲數組',
        'float'   => ':attribute必須爲浮點數',
        'boolean' => ':attribute必須爲布爾值',
        'email'   => ':attribute必須爲正確的郵件地址',
        'url'     => ':attribute必須爲正確的url格式',
        'ip'      => ':attribute必須爲正確的ip地址',
        'timestamp' => ':attribute必須爲正確的時間戳格式',
        'date'    => ':attribute必須爲正確的日期格式',
        'regex'   => ':attribute格式不正確',
        'in'      => ':attribute必須在:range內',
        'notIn'   => ':attribute必須不在:range內',
        'between'  => ':attribute必須在:1-:2範圍內',
        'notBetween' => ':attribute必須不在:1-:2範圍內',
        'max'     => ':attribute最大值爲:1',
        'min'     => ':attribute最小值爲:1',
        'length'  => ':attribute長度必須爲:1',
        'confirm' => ':attribute和:1不一致',
        'gt'      => ':attribute必須大於:1',
        'lt'      => ':attribute必須小於:1',
        'egt'     => ':attribute必須大於等於:1',
        'elt'     => ':attribute必須小於等於:1',
        'eq'      => ':attribute必須等於:1',
    ];

    public function __construct($validate = null) {
       $this->validate = $validate;

	}
    
    /**
     * [validate 驗證]
     * @param  [type] $data [需要驗證的參數]
     * @return [type]       [boolean]
     */
	public function validate($data) {
		$this->data = $data;
        foreach ($this->validate as $key => $item) {
        	$item_len = count($item);
        	$name = $item[0];
        	$rules = $item[1];

        	$rules = explode('|', $rules);

        	$message = $item_len > 2 ? explode('|', $item[2]) : null;
            
            $this->check($name, $rules, $message); 
        }

        if(!empty($this->add_rules)) {
        	$this->checkAddRules();
        }

        return empty($this->error) ? TRUE : FALSE;
	}
    
    /**
     * [check 單個字段驗證]
     * @param  [type] $name    [description]
     * @param  [type] $rules   [description]
     * @param  [type] $message [description]
     * @return [type]          [null]
     */
	private function check($name, $rules, $message) {
		//$title = $name;
		$rule_name = $title = $name;
		if(strpos($name, '|')) {
			$rule_name = explode('|', $name)[0];
			$title = explode('|', $name)[1];
		}
        foreach ($rules as $i => $rule) {
		    $validate_data = isset($this->data[$rule_name]) ? $this->data[$rule_name] : null;
        	
        	$result = $this->checkResult($rule, $validate_data);
        	if(!$result) {
        		$error_info = isset($message[$i]) ? $message[$i] : $this->getMessage($title, $rule);
                if($error_info) {
                	array_push($this->error, $error_info);
                }
        	}
        }
	}
    
    /**
     * [getMessage 獲取驗證失敗的信息]
     * @param  [type] $name [字段名]
     * @param  [type] $rule [驗證規則]
     * @return [type]       [string OR fail false]
     */
	private function getMessage($name, $rule) {
		$value1 = '';
		$value2 = '';
		$range = '';
		$error_key = $rule;
        if(strpos($rule, ':')) {
        	$exp_arr = explode(':', $rule);
        	$error_key = $exp_arr[0];
        	$range = $exp_arr[1];
        	$message_value = explode(',', $exp_arr[1]);
        	$value1 = isset($message_value[0]) ? $message_value[0] : '';
        	$value2 = isset($message_value[1]) ? $message_value[1] : '';
        }
        if(isset($this->error_msg[$error_key])) {
        	return str_replace([':attribute', ':range', ':1', ':2'], [$name, $range, $value1, $value2], $this->error_msg[$error_key]);
        }
		return false;
	}
    
    /**
     * [checkResult 字段驗證]
     * @param  [type] $rule          [驗證規則]
     * @param  [type] $validate_data [需要驗證的數據]
     * @return [type]                [boolean]
     */
	private function checkResult($rule, $validate_data) {
        switch ($rule) {
        	case 'require':
        		    return $validate_data != '';
        		break;
        	case 'number':
        		    return filter_var($validate_data, FILTER_SANITIZE_NUMBER_INT);
        		break;
        	case 'array':
        		    return is_array($validate_data);
        		break;
        	case 'float':
        		    return filter_var($validate_data, FILTER_VALIDATE_FLOAT);
        		break;
        	case 'boolean':
        		    return filter_var($validate_data, FILTER_VALIDATE_BOOLEAN);
        		break;
        	case 'email':
        		    return filter_var($validate_data, FILTER_VALIDATE_EMAIL);
        		break;
        	case 'url':
        		    return filter_var($validate_data, FILTER_SANITIZE_URL);
        	case 'ip':
        		    return filter_var($validate_data, FILTER_VALIDATE_IP);
        		break;
        	case 'timestamp':
        		    return strtotime(date('Y-m-d H:i:s',$validate_data)) == $validate_data;
        		break;
        	case 'date': //2017-11-17 12:12:12
        		    return strtotime($validate_data);
        		break;
        	default:
        	        if(strpos($rule, ':')) {
        	        	$rule_arr = explode(':', $rule);
        	        	$func_name =  substr($rule, strpos($rule, ':')+1);
        		        return call_user_func_array([$this, $rule_arr[0]], [$func_name, $validate_data]); 
        		    }else{
        		    	return call_user_func_array([$this, $rule], [$rule, $validate_data]); 
        		    }
        		break;
        }
	}
    
    /**
     * [regex 正則驗證]
     * @param  [type] $rule [description]
     * @param  [type] $data [description]
     * @return [type]       [description]
     */
	public static function regex($rule, $data) {
        return filter_var($data, FILTER_VALIDATE_REGEXP,  ["options" => ["regexp" => $rule]]);

	}
    
    /**
     * [addRule 添加規則格式 []]
     * @param [type] $rule [description]
     */
	public function addRule($rule) {
		if(is_array(current($rule))) {
			$this->add_rules = array_merge($this->add_rules, $rule);
		}else{
			array_push($this->add_rules, $rule);
		}
	}
    
    /**
     * [checkAddRules 添加新的規則的驗證]
     * @return [type] [description]
     */
	public function checkAddRules() {
		foreach ($this->add_rules as $key => $item) {
			$name = $item[0];
        	$message = isset($item[3]) ? $item[3] : null;
        	$rule_name = $title = $name;
			if(strpos($name, '|')) {
				$rule_name = explode('|', $name)[0];
				$title = explode('|', $name)[1];
			}
			$validate_data = isset($this->data[$rule_name]) ? $this->data[$rule_name] : null;
        	
       	    $result = $this->checkResult($item[1].':'.$item[2], $validate_data);
       	 	if(!$result) {
        		$error_info = isset($message) ? $message : $this->getMessage($title, $item[1]);
            	if($error_info) {
                	array_push($this->error, $error_info);
            	}
        	} 
		}
	}

	/**
	 * [in description]
	 * @param  [type] $rule [驗證規則]
	 * @param  [type] $data [需要驗證的數據]
	 * @return [type]       [boolean]
	 */
	public static function in($rule, $data) {
		if(!is_array($rule)) {
			$rule = explode(',', $rule);
		}
        return in_array($data, $rule);
	}
    
    /**
	 * [in description]
	 * @param  [type] $rule [驗證規則]
	 * @param  [type] $data [需要驗證的數據]
	 * @return [type]       [boolean]
	 */
	public static function notIn($rule, $data) {
        return !$this->in($data, $rule);
	}
    
    /**
	 * [in description]
	 * @param  [type] $rule [驗證規則]
	 * @param  [type] $data [需要驗證的數據]
	 * @return [type]       [boolean]
	 */
	public static function between($rule, $data) {
		$rule = explode(',', $rule);
        return $data >= $rule[0] && $data <= $rule[1];
	}
    
    /**
	 * [in description]
	 * @param  [type] $rule [驗證規則]
	 * @param  [type] $data [需要驗證的數據]
	 * @return [type]       [boolean]
	 */
	public static function notBetween($rule, $data) {
		return !$this->between($rule, $data);
	}

    /**
	 * [in description]
	 * @param  [type] $rule [驗證規則]
	 * @param  [type] $data [需要驗證的數據]
	 * @return [type]       [boolean]
	 */
	public static function max($rule, $data) {
		return $data <= $rule;
	}

    /**
	 * [in description]
	 * @param  [type] $rule [驗證規則]
	 * @param  [type] $data [需要驗證的數據]
	 * @return [type]       [boolean]
	 */
	public static function min($rule, $data) {
		return $data >= $rule;
	}
    
    /**
	 * [in description]
	 * @param  [type] $rule [驗證規則]
	 * @param  [type] $data [需要驗證的數據]
	 * @return [type]       [boolean]
	 */
	public static function length($rule, $data) {
		$length = is_array($data) ? count($data) : strlen($data);
		return $length == $rule;
	}
    
    /**
	 * [in description]
	 * @param  [type] $rule [驗證規則]
	 * @param  [type] $data [需要驗證的數據]
	 * @return [type]       [boolean]
	 */
	public static function confirm($rule, $data) {
		return isset($this->data[$rule]) && $data == $this->data[$rule];
	}

	public static function gt($rule, $data) {
		return $data > $rule;
	}

    public static function lt($rule, $data) {
		return $data < $rule;
	}

	public static function egt($rule, $data) {
		return $data >= $rule;
	}

    public static function elt($rule, $data) {
		return $data <= $rule;
	}

	public static function eq($rule, $data) {
		return $data == $rule;
	}

    /**
	 * [in 獲取驗證失敗的第一條信息]
	 * @return [type]  [string]
	 */
	public function getError() {

        return count($this->error) > 0 ? $this->error[0] : null;
	}
    
    /**
     * [getAllErrors 獲取所有驗證失敗的信息]
     * @return [type] [array]
     */
	public function getAllErrors() {
        return $this->error;
	}
    
    /**
     * [__call 調用自定義函數或者]
     * @param  [type] $func [驗證規則,函數名]
     * @param  [type] $data [驗證數據]
     * @return [type]       [boollean]
     */
	function __call($func, $data) {
		$func_arr = get_defined_functions();
		if(in_array($func,$func_arr['user'])) {
			return call_user_func($func, $data);
		}else{
			array_push($this->error, '沒有' . $func . '這個方法');
		}
  	}
    
    /**
     * [__callStatic 靜態方法調用自定義函數或者]
     * @param  [type] $func [驗證規則,函數名]
     * @param  [type] $data [驗證數據]
     * @return [type]       [boollean]
     */
  	public static function __callStatic($func, $data) {
  		if(substr($func, 0, 2) == 'is') {
			return call_user_func_array([new self, 'checkResult'], [strtolower(substr($func, 2)), $data[0]]);
		} 
  	}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章