本文目录导读:

在 Laravel 中自定义身份证验证有多种方式,我为您提供几种常用且完整的实现方案:
使用 Validator Extend(推荐)
创建自定义验证规则
在 AppServiceProvider 的 boot 方法中注册:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Validator;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
Validator::extend('identity_card', function ($attribute, $value, $parameters, $validator) {
// 身份证号码验证逻辑
return $this->validateIdentityCard($value);
}, '身份证号码格式不正确');
Validator::replacer('identity_card', function ($message, $attribute, $rule, $parameters) {
return str_replace(':attribute', $attribute, $message);
});
}
/**
* 身份证验证核心逻辑
*/
private function validateIdentityCard($idCard)
{
// 去除空格
$idCard = strtoupper(trim($idCard));
// 长度验证
if (strlen($idCard) != 18 && strlen($idCard) != 15) {
return false;
}
// 18位验证
if (strlen($idCard) == 18) {
return $this->validate18IdCard($idCard);
}
// 15位验证
if (strlen($idCard) == 15) {
return $this->validate15IdCard($idCard);
}
return false;
}
/**
* 验证18位身份证
*/
private function validate18IdCard($idCard)
{
// 正则基本格式验证
if (!preg_match('/^\d{17}[\dX]$/', $idCard)) {
return false;
}
// 验证出生日期
$birthday = substr($idCard, 6, 8);
if (!$this->validateBirthday($birthday)) {
return false;
}
// 验证校验码
$verifyCode = $this->getIdCardVerifyCode($idCard);
if (substr($idCard, 17, 1) != $verifyCode) {
return false;
}
return true;
}
/**
* 验证15位身份证
*/
private function validate15IdCard($idCard)
{
// 正则基本格式验证
if (!preg_match('/^\d{15}$/', $idCard)) {
return false;
}
// 验证出生日期(15位身份证出生日期格式为:yymmdd)
$birthday = '19' . substr($idCard, 6, 6);
if (!$this->validateBirthday($birthday)) {
return false;
}
return true;
}
/**
* 验证出生日期
*/
private function validateBirthday($birthday)
{
$year = substr($birthday, 0, 4);
$month = substr($birthday, 4, 2);
$day = substr($birthday, 6, 2);
// 检查日期是否有效
if (!checkdate((int)$month, (int)$day, (int)$year)) {
return false;
}
// 检查年份范围(假设当前年份为2024年)
$currentYear = date('Y');
if ($year < 1900 || $year > $currentYear) {
return false;
}
return true;
}
/**
* 计算18位身份证校验码
*/
private function getIdCardVerifyCode($idCard)
{
// 加权因子
$weightFactor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
// 校验码对应值
$verifyCode = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
$idCard17 = substr($idCard, 0, 17);
$sum = 0;
for ($i = 0; $i < 17; $i++) {
$sum += intval($idCard17[$i]) * $weightFactor[$i];
}
$mod = $sum % 11;
return $verifyCode[$mod];
}
}
在控制器中使用
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function store(Request $request)
{
$request->validate([
'identity_card' => 'required|identity_card',
]);
// 验证通过,继续处理
}
}
创建自定义验证规则类
创建规则类
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class IdentityCardRule implements Rule
{
/**
* 验证规则名称
*/
protected $ruleName = '身份证号码';
/**
* 判断验证规则是否通过
*/
public function passes($attribute, $value)
{
$idCard = strtoupper(trim($value));
// 长度验证
if (strlen($idCard) != 18 && strlen($idCard) != 15) {
return false;
}
// 18位验证
if (strlen($idCard) == 18) {
return $this->validate18IdCard($idCard);
}
// 15位验证
if (strlen($idCard) == 15) {
return $this->validate15IdCard($idCard);
}
return false;
}
/**
* 获取验证错误消息
*/
public function message()
{
return ':attribute 格式不正确,请输入有效的' . $this->ruleName;
}
private function validate18IdCard($idCard)
{
if (!preg_match('/^\d{17}[\dX]$/', $idCard)) {
return false;
}
$birthday = substr($idCard, 6, 8);
if (!$this->validateBirthday($birthday)) {
return false;
}
$verifyCode = $this->getIdCardVerifyCode($idCard);
return substr($idCard, 17, 1) == $verifyCode;
}
private function validate15IdCard($idCard)
{
if (!preg_match('/^\d{15}$/', $idCard)) {
return false;
}
$birthday = '19' . substr($idCard, 6, 6);
return $this->validateBirthday($birthday);
}
private function validateBirthday($birthday)
{
$year = (int)substr($birthday, 0, 4);
$month = (int)substr($birthday, 4, 2);
$day = (int)substr($birthday, 6, 2);
return checkdate($month, $day, $year) &&
$year >= 1900 &&
$year <= (int)date('Y');
}
private function getIdCardVerifyCode($idCard)
{
$weightFactor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
$verifyCode = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
$idCard17 = substr($idCard, 0, 17);
$sum = 0;
for ($i = 0; $i < 17; $i++) {
$sum += (int)$idCard17[$i] * $weightFactor[$i];
}
return $verifyCode[$sum % 11];
}
}
在控制器中使用
use App\Rules\IdentityCardRule;
public function store(Request $request)
{
$request->validate([
'identity_card' => ['required', new IdentityCardRule],
]);
}
使用表单请求验证
创建表单请求
php artisan make:request StoreUserRequest
编辑表单请求类
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use App\Rules\IdentityCardRule;
class StoreUserRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'name' => 'required|string|max:255',
'identity_card' => ['required', new IdentityCardRule],
];
}
public function messages()
{
return [
'identity_card.required' => '请输入身份证号码',
];
}
}
在控制器中使用
use App\Http\Requests\StoreUserRequest;
public function store(StoreUserRequest $request)
{
// 验证已通过,可以直接获取验证过的数据
$validated = $request->validated();
// 继续处理业务逻辑
}
简化版验证(快速入门)
如果您只需要基本验证,可以使用更简单的版本:
// 在 AppServiceProvider 中
Validator::extend('identity_card', function ($attribute, $value, $parameters, $validator) {
$idCard = strtoupper(trim($value));
// 基本格式验证
if (!preg_match('/^\d{17}[\dX]$/', $idCard) && !preg_match('/^\d{15}$/', $idCard)) {
return false;
}
// 验证出生日期
if (strlen($idCard) == 18) {
$birthday = substr($idCard, 6, 8);
} else {
$birthday = '19' . substr($idCard, 6, 6);
}
$year = substr($birthday, 0, 4);
$month = substr($birthday, 4, 2);
$day = substr($birthday, 6, 2);
return checkdate((int)$month, (int)$day, (int)$year);
}, '身份证号码格式不正确');
推荐使用
- 方案一(Validator Extend):如果您需要全局使用,推荐此方法
- 方案二(自定义规则类):如果您需要更复杂的验证逻辑,推荐此方法
- 方案三(表单请求验证):如果您使用表单请求进行验证,推荐此方法
选择适合您项目需求的方案即可,如果还需要其他扩展功能,请告诉我!
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播