如果另一个字段已完全通过验证,且不仅仅是被填写,则对该字段进行有条件的验证
realestate\app\Http\Controllers\AuthController.php 拥有注册验证规则和注册方法:
use Illuminate\Http\Request;
use Illuminate\Support\Facades\{Auth, Log};
use Illuminate\Validation\Rules\Password;
use Illuminate\Validation\Validator;
class AuthController extends Controller
{
private array $register_rules;
public function __construct(private UserService $service) {
$this->register_rules = [
"email" => "required|string|email",
"password" => ["required", "string", "different:email", Password::min(8)->mixedCase()->numbers()->symbols()],
"password2" => "same:password",
"phone" => "required|string|regex:/^\+381 \d{2} \d{6,7}$/mu",
"first_name" => "required|string|alpha",
"last_name" => "required|string|alpha",
"birth_date" => "required|date|before:-18 years"
];
}
public function register(Request $request)
{
// 2 Input validation & sanitization
// $validated = $request->validate($this->register_rules);
$validator = Validator::make($request->all(), $this->register_rules);
$validated = $validator->validate();
// ...
// 5 Security logging
Log::info(LogMessages::auth_controller["register_success"], ["user_id" => $user->id]);
return redirect()->route("listing_index");
} // [1]
}
password 不能为空,必须是字符串,并且由字母、数字和特殊字符混合组成。
仅当 password 为 非空且完全有效 时,才对 password2 与 password 进行一致性验证。
realestate\resources\views\auth\register.blade.php:
<div class="col-12">
<div class="input-group">
<div class="form-floating">
<input class="form-control" type="password" id="password" name="password">
<label for="password">Lozinka</label>
</div>
<div class="form-floating">
<input class="form-control" type="password" id="password2" name="password2">
<label for="password2">Potvrda lozinke</label>
</div>
</div>
@if ($errors->hasAny('password', 'password2'))
<div class="form-text text-danger">{{ __($errors->first('password')) }}</div>
<div class="form-text text-danger fw-bold">{{ __($errors->first('password2')) }}</div>
@endif
</div>
让 password 的错误显示在带有 _($errors->first('password') 的div中,而 password2 的错误显示在带有 _($errors->first('password2') 的div,并使用粗体文本。
尝试通过在 register 中添加 $validator->after 来解决,但 $validator 实例没有 errors() 方法。
$validator->after(function (Validator $validator) use ($request) {
$password = $request->get("password");
$password2 = $request->get("password2");
if (!$validator->errors()->has("password") && $password !== $password2) $validator->errors()->add("password2", _("password2.confirmed"));
});
解决方案
你这是在重复造轮子。此外,技术上并没有必要只在原密码有效时才验证确认。
$validator = Validator::make($request->all(), [
'password' => ['required', 'confirmed', Password::min(8)],
]);
// Require at least 8 characters...
Password::min(8)
// Require at least one letter...
Password::min(8)->letters()
// Require at least one uppercase and one lowercase letter...
Password::min(8)->mixedCase()
// Require at least one number...
Password::min(8)->numbers()
// Require at least one symbol...
Password::min(8)->symbols()
被验证的字段必须有一个与之匹配的字段,字段名为
{field}_confirmation。例如,如果被验证的字段是password,输入中必须存在一个匹配的password_confirmation字段。你也可以传一个自定义的确认字段名。例如,
confirmed:repeat_username将期望字段repeat_username与被验证的字段相匹配。
如果要使用这个,请记得把 password2 重命名为 password_confirmation(因为这是一个确认字段,而不是第二个密码,措辞更贴切)。
据我所知,没有像“只有当这个字段已被验证为有效时才验证”的规则,所以你要么坚持使用验证器的 after() 方法,要么添加一个自定义规则。
如果你的 $validator 没有 errors() 方法,你是在搞错。它应该在你通过 make() 初始化后就可用。