Пустая строка проверяется на необязательное целое число

Я должен проверить поле ввода моего API, где значение должно быть целым числом от 1 до 100 или null или он даже не установлен (не требуется).

Таким образом, мое правило проверки таково: 'privacy_status' => "nullable|integer|min:1|max:100",

Это работает нормально, пока я не получу пустую строку в качестве значения. Так как проверка Laravel на пустой строке проверяется только в том случае, если поле неявно, все остальные мои правила integer, nullable or min, max игнорируются

protected function isValidatable($rule, $attribute, $value)
{
    return $this->presentOrRuleIsImplicit($rule, $attribute, $value) &&
       $this->passesOptionalCheck($attribute) &&
       $this->isNotNullIfMarkedAsNullable($attribute, $value) &&
       $this->hasNotFailedPreviousRuleIfPresenceRule($rule, $attribute);
}

protected function presentOrRuleIsImplicit($rule, $attribute, $value)
{
    if (is_string($value) && trim($value) === '') {
        return $this->isImplicit($rule);
    }

    return $this->validatePresent($attribute, $value) || $this->isImplicit($rule);
}

Есть ли способ проверить это правильно?

2 ответа

Решение

РЕДАКТИРОВАТЬ

Вы всегда можете создать собственное правило проверки.

Validator::extendImplicit('fail_on_empty_string', function($attribute, $value, $parameters)
{
    return $value === "" ? false : $value;
});

Вы можете использовать новое правило следующим образом:

'privacy_status' => "fail_on_empty_string|nullable|integer|min:1|max:100",

Старый ответ

Это описано в документации Laravel и является ошибкой, которую вы сами себе представили (хотя, вероятно, неосознанно): https://laravel.com/docs/5.6/validation:

По умолчанию Laravel включает промежуточное программное обеспечение TrimStrings и ConvertEmptyStringsToNull в глобальный стек промежуточного программного обеспечения вашего приложения. Эти промежуточные программы перечислены в стеке классом App\Http\Kernel. Из-за этого вам часто нужно помечать ваши "необязательные" поля запроса как обнуляемые, если вы не хотите, чтобы валидатор считал нулевые значения недействительными.

Пустые строки автоматически приводятся к нулю, что по вашей проверке вполне нормально. Либо отключите промежуточное программное обеспечение, либо измените его, либо измените правила проверки.

Вы можете просто передать ему заполненное правило. Это позволит полю обнуляться, и если оно присутствует в запросе; это не может быть пустым.

'privacy_policy' => 'filled|integer|min:1|max:100'

Если вы хотите разрешить пустую строку, когда она присутствует, вместо этого измените на настоящее правило.

'privacy_policy' => 'present|nullable|integer|min:1|max:100'

Обновить

Я добавил юнит-тест, чтобы доказать, что это работает правильно.

public function index()
{
    request()->validate([
        'privacy_policy' => 'filled|integer|min:1|max:100'
    ]);

    return response();
}

Тогда в тесте:

$this->get(route('test'))->assertStatus(200); // True
$this->get(route('test'), ['privacy_policy' => ''])->assertStatus(200); // False
$this->get(route('test'), ['privacy_policy' => 5])->assertStatus(200); // True
Другие вопросы по тегам