#php #laravel #validation #laravel-5.8
#php #laravel #проверка #laravel-5.8
Вопрос:
Я не знаю, является ли это недостатком сна или отсутствием чего-то очевидного, но у меня возникла такая проблема: я создал пользовательское правило проверки, и мне нужно передать значение запроса через конструктор для выполнения проверки.
Это моя настройка:
Пользовательское правило проверки
/** Rules/RouteValidationRule.php */
namespace AppRules;
use IlluminateContractsValidationRule;
class RouteValidationRule implements Rule {
private $action;
public function __construct(string $action)
{
$this->action = $action; // doing dd($action) output the correct value.
}
// a dd('Hi'); inside here is just ignored:
public function passes($attribute, $value)
{
if ($this->action === 'complete')
return (isset($value['delivery_route']))
amp;amp; (count($value['delivery_route']) >= 2);
else
return true;
}
public function message() { /** */ }
}
Запрос формы
/** UpdateOrderRequest.php */
namespace AppHttpRequests;
use AppRulesOrderStatusesRule;
use AppRulesRouteValidationRule;
use IlluminateFoundationHttpFormRequest;
class UpdateOrderRequest extends FormRequest {
public function authorize() { /** */ }
public function rules()
{
return [
'action' => ['required', new OrderStatusesRule],
'meta.delivery_route' => [
'array',
new RouteValidationRule($this->get('action')), // <---
],
];
}
}
Но дело в том, что значение достигает конструктора пользовательского правила, но оно не доходит до passes()
метода, оно просто игнорирует это и продолжает, как если бы это было нормально.
PD: я проверял каждый шаг dd()
.
Заранее спасибо.
Обновить
/** MyController.php */
/**
* @param UpdateOrderRequest $request
* @return mixed
*/
public function handle(UpdateOrderRequest $request) // the RequestForm is injected
{
dd('I passed'); // <-- is reaching this statement when it shouldn't
}
Комментарии:
1. Можете ли вы также вставить метод обработчика контроллера? Также не может ли быть так, что проверка вашего запроса завершается неудачно на предыдущем шаге, и поэтому оно не достигнет вашего правила проверки из-за стратегии быстрого выхода?
2. @Tacsiazuma В том-то и дело, что он проходит проверку и достигает контроллера. Я добавлю соответствующий код, как было предложено.
3. И если вы проверите запрос в своем контроллере, он содержит указанное поле? Что произойдет, если вы добавите ‘required’ как правило?
4. @Tacsiazuma если я добавляю
required
как правило в этот атрибут, он завершается ошибкой при отсутствии (как и ожидалось), но затем, когда я добавляю параметр и повторяю запрос, он передаетrequired
, но игнорируетpasses()
пользовательское правило. И да, атрибут достигает контроллера, это действительно странно
Ответ №1:
Причина, по которой ваше правило не будет выполняться, заключается в том, что тестируемый атрибут отсутствует в Request
or null . Если вы хотите, чтобы правило выполнялось независимо от того, присутствует оно или нет, пусть ваше правило ImplicitRule
не реализует Rule
, например:
class RouteValidationRule implements ImplicitRule {
Ответ №2:
Я взломал аналогичное решение и обнаружил, что оно просто игнорирует проверку, если поле, подлежащее проверке, отсутствует (за исключением случаев, когда required также добавляется в качестве правила проверки):
Route::any('/', function (UpdateOrderRequest $orderRequest) {
dd($orderRequest);
});
Я добавил dd(‘pass’) внутри метода passes:
public function passes($attribute, $value)
{
dd('pass');
if ($this->action === 'complete')
return (isset($value['delivery_route']))
amp;amp; (count($value['delivery_route']) >= 2);
else
return true;
}
Затем отправлен запрос с postman:
POST / HTTP/1.1
Host: localhost:8888
Content-Type: application/json
cache-control: no-cache
Postman-Token: 848f7181-2c28-46a5-b508-4cb35083315e
{
"action" : "something",
"meta" : {
"delivery_route" : "something else"
}
}------WebKitFormBoundary7MA4YWxkTrZu0gW--
Он столкнулся с методом passes и повторил ‘pass’ обратно. Затем я переименовал «delivery_route» выше, и он оказался в контроллере.
Из документов по проверке Laravel:
По умолчанию, когда проверяемый атрибут отсутствует или содержит пустую строку, обычные правила проверки, включая пользовательские расширения, не выполняются.
Комментарии:
1. Я не понимаю этого решения, или это подтверждение, которое не является проблемой с моей стороны? (возможно, возможная ошибка)
2. Я поместил атрибут present со значением, которое должно было прервать проверку, но все равно прошло.
3. Я думаю, потому что имя поля не совпадает. Читайте о неявных расширениях в laravel.com/docs/5.8/validation
4. Я сделал запрос с теми же именами атрибутов, честно говоря, действительно странные вещи.
5. Можете ли вы попробовать это с помощью запроса JSON (если это еще не так) и обновить свой вопрос с помощью тела запроса?