// +---------------------------------------------------------------------- namespace app\common\library; use think\Validate; /** * thinkphp 框架表单验证Validate的扩展类 * @author setsu * */ class ValidateExtend extends Validate { public function __construct(array $rules = [], array $message = [], array $field = []) { parent::__construct($rules, $message, $field); parent::$typeMsg['isEmpty'] = ':attribute不能为空值'; } /** * 重构父类Validate的is方法,增加验证规则 * @access protected * @param mixed $value 字段值 * @param string $rule 验证规则 * @param array $data 验证数据 * @return bool */ public function is($value, $rule, $data = []) { switch ($rule) { case 'mobile': // 手机号码验证 $result = $this->regex($value, '/^(13[0-9]|14[0-9]|15[0-9]|16[0-9]|17[0-9]|18[0-9]|19[0-9])[0-9]{8}$/'); break; case 'positiveInteger': //正整数 $result = $this->regex($value, '/^[1-9][0-9]*$/'); break; default: $result = parent::is($value, $rule, $data); } return $result; } /** * 身份证号码格式验证 */ protected function identityNumber($value) { $vCity = [ '11', '12', '13', '14', '15', '21', '22', '23', '31', '32', '33', '34', '35', '36', '37', '41', '42', '43', '44', '45', '46', '50', '51', '52', '53', '54', '61', '62', '63', '64', '65', '71', '81', '82', '91', ]; if (!preg_match('/^([\d]{17}[xX\d]|[\d]{15})$/', $value)) { return false; } if (!in_array(substr($value, 0, 2), $vCity)) { return false; } else { $value = preg_replace('/[xX]$/i', 'a', $value); } $vLength = strlen($value); if ($vLength == 18) { $vBirthday = substr($value, 6, 4) . '-' . substr($value, 10, 2) . '-' . substr($value, 12, 2); } else { $vBirthday = '19' . substr($value, 6, 2) . '-' . substr($value, 8, 2) . '-' . substr($value, 10, 2); } if (date('Y-m-d', strtotime($vBirthday)) != $vBirthday) { return false; } if ($vLength == 18) { $vSum = 0; for ($i = 17; $i >= 0; $i--) { $vSubStr = substr($value, 17 - $i, 1); $vSum += (pow(2, $i) % 11) * (($vSubStr == 'a') ? 10 : intval($vSubStr, 11)); } if ($vSum % 11 != 1) { return false; } } return true; } /** * 密码强度检测 * Password规则调整:至少$length位,密码至少要包含字母、数字、符号中的两种, * ******************规则结果:密码强度大于等于2的通过 * * @param $value 密码 * @param $rule 要求的最小密码强度 * * @return boolean * */ public function passwordStrength($value, $rule) { if (empty($value)) { return false; } $strong = 0; if (preg_match('/[0-9]+/', $value)) { $strong++; } if (preg_match('/[a-zA-Z]+/', $value)) { $strong++; } if (preg_match('/[^A-Za-z0-9]+/', $value)) { $strong++; } return $strong >= $rule; } /** * 判断值是否为空 * @param $value * @return bool */ public function isEmpty($value) { if (is_string($value)) { $value = trim($value); } if (empty($value)) { return false; } return true; } /** * 递归验证数组数据 * @param $value * @param $rule * @return bool */ public function recursiveCheck($value, $rule) { $flag = true; array_walk_recursive($value, function ($item, $key) use ($rule, &$flag) { if (true !== parent::is($item, $rule)) { $flag = false; var_dump($item, $rule); } }); return $flag; } /** * 是否有效的私钥 * @param $private_key string * @return bool */ public function isValidPrivateKey($private_key) { if (empty($private_key)) { return false; } $resource_id = openssl_pkey_get_private($private_key); if (empty($resource_id)) { return false; } return true; } /** * 是否有效的公钥 * @param $public_key string * @return bool */ public function isValidPublicKey($public_key) { if (empty($public_key)) { return false; } $resource_id = openssl_pkey_get_public($public_key); if (empty($resource_id)) { return false; } return true; } /** * 是否有效的密钥对(判断是否能否互相加密解密) * @param $private_key string * @param $public_key string * @return bool */ public function isValidRsaKey($private_key, $public_key) { if (!$this->isValidPublicKey($public_key)) { return false; } if (!$this->isValidPrivateKey($private_key)) { return false; } //数据原文 $data = time(); // 使用公钥加密 openssl_public_encrypt($data, $encrypted, openssl_pkey_get_public($public_key)); $encrypted = base64_encode($encrypted); // 使用秘钥看是否能够解密,能的话,说明就是配对的 openssl_private_decrypt(base64_decode($encrypted), $decrypted, openssl_pkey_get_private($private_key)); if ($data != $decrypted) { return false; } return true; } /** * 身份证验证 * @param $idCard * * @return bool */ function validateIDCard($idCard) { // 正则表达式验证格式 if (!preg_match('/^\d{17}[\dXx]$/', $idCard)) { return false; } // 加权因子 $weight = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]; // 校验码对应值 $validate = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']; $sum = 0; // 计算前17位的加权和 for ($i = 0; $i < 17; $i++) { $sum += intval($idCard[$i]) * $weight[$i]; } // 计算校验码 $mod = $sum % 11; $expectedValidateCode = $validate[$mod]; // 校验最后一位 $lastChar = strtoupper($idCard[17]); return $lastChar === $expectedValidateCode; } }