0

我正在尝试在验证后使用passedValidation() 函数在formRequest 中实现强制转换方法。

一切看起来都不错,但是在passedValidation() 中的演员表并没有出现在$request->validated() 中,但是在$request->all() 中是可见的。

我的表格请求

<?php
    
    namespace App\Http\Requests\Models\Company;
    
    use App\Http\Requests\CustomFormRequest;
    use Illuminate\Support\Facades\Auth;
    use Propaganistas\LaravelPhone\PhoneNumber;
    

    class CompanyFormRequest extends CustomFormRequest
    {
 
        protected function prepareForValidation()
        {
            $this->merge([
                             'is_presting' => !$this->missing('is_presting') 
                                             && $this->input('is_presting'),
                         ]);
        }
    
        public function rules () : array
        {
           
            
            return [
                'name' => [ 'required' , 'string' ] ,
                'street' => [ 'string' , 'nullable' ] ,
                'city' => [ 'string' , 'nullable' ] ,
                'post_code' => [ 'string' , 'nullable' ] ,
                'TVA' => [ 'string' , 'nullable' ] ,
                'language' => [ 'required' , 'string' ] ,
                'bank' => [ 'string' , 'nullable' ] ,
                'email' => [ 'string' , 'email' , 'nullable' ] ,
                'website' => [ 'string' , 'url' , 'nullable' ] ,
                'latitude' => [ 'numeric' , 'nullable' ] ,
                'longitude' => [ 'numeric' , 'nullable' ] ,
                'reference' => [ 'string' , 'nullable' ] ,
                'is_presting' => [ 'boolean' ] ,
                'phone_country' => [ 'required_with:phone_field' , 'string' ] ,
                'phone_field' => [ 'required_with:phone_country' , 'phone:'.$this->input('phone_country') ] ,
            
            ];
        }
        
        public function authorize () : bool
        {
            return app () -> runningInConsole () 
                || ( Auth ::check () && Auth ::user () -> can ( 'manage_content' ) );
        }
    
        protected function passedValidation ()
        {
           $this->merge( [
                             'phone_field' => 
                                 (string) PhoneNumber ::make ( $this -> input ( 'phone_field' ) , 
                                                               $this -> input ( 'phone_country' ) )
                         ]);
        }
    
    }

$request->all() 验证前

array:16 [▼
  "name" => "De Greef SCA"
  "street" => "chemin Gérard 527"
  "city" => "Tournai"
  "post_code" => "6485"
  "TVA" => "BE0958232035"
  "language" => "fr_FR"
  "bank" => "BE96227410211607"
  "phone_field" => "0471321102"
  "phone_country" => "BE"
  "email" => "jpauwels@example.org"
  "website" => "http://devos.org/ab-et-itaque-a.html"
  "latitude" => -64.420589
  "longitude" => 65.667543
  "reference" => "OMZ"
  "active" => true
  "is_presting" => true
]

$request->validated() 验证后

array:16 [▼
  "name" => "De Greef SCA"
  "street" => "chemin Gérard 527"
  "city" => "Tournai"
  "post_code" => "6485"
  "TVA" => "BE0958232035"
  "language" => "fr_FR"
  "bank" => "BE96227410211607"
  "phone_field" => "0471321102"
  "phone_country" => "BE"
  "email" => "jpauwels@example.org"
  "website" => "http://devos.org/ab-et-itaque-a.html"
  "latitude" => -64.420589
  "longitude" => 65.667543
  "reference" => "OMZ"
  "active" => true
  "is_presting" => true
]

$request->all() 验证后

array:16 [▼
  "name" => "De Greef SCA"
  "street" => "chemin Gérard 527"
  "city" => "Tournai"
  "post_code" => "6485"
  "TVA" => "BE0958232035"
  "language" => "fr_FR"
  "bank" => "BE96227410211607"
  "phone_field" => "+32471321102"
  "phone_country" => "BE"
  "email" => "jpauwels@example.org"
  "website" => "http://devos.org/ab-et-itaque-a.html"
  "latitude" => -64.420589
  "longitude" => 65.667543
  "reference" => "OMZ"
  "active" => true
  "is_presting" => true
]

我们在 $request->all() 中看到验证后在 'phone_field' 上很好地执行了强制转换,但为什么它没有出现在 $request->validated() 中?

谢谢。

4

2 回答 2

0

猜猜您可能需要与经过验证的数据合并。如果您使用的是最新版本的 Laravel,您可以使用该safe()方法

$validated = $request->safe()->merge([
    'phone_field' => (string) PhoneNumber::make ( 
        $this->input('phone_field'), $this->input('phone_country') 
    )
)];

如果您希望 FormRequest 类封装合并,您可以定义一个自定义方法validatedWithCasts,然后在控制器或其他任何地方使用此方法


class CompanyFormRequest extends CustomFormRequest
{
 
    // ...other methods and rules
    
    public function validatedWithCasts ()
    {
        return $this->safe()->merge([
            'phone_field' => (string) PhoneNumber::make ( 
                $this->input('phone_field'), $this->input('phone_country') 
            )

        ]);
    }
    
}

然后在控制器中你可以像这样使用它

$request->validatedWithCasts();
于 2021-09-16T17:33:26.240 回答
0

这是因为$request->all()&$request->validated()在不同的类上有不同的实现。您可以在FormRequest源代码中看到它。简而言之:

  • $request->all()接受 $request 中的输入,因为它出现在函数调用中
  • 另一方面,$request->validated()实际上是validated()在底层 Validator 对象上调用函数。如果你跟踪它,所有的输入都是在 FormRequest创建 Validator 对象时传递的。因此,您对 $request 输入passedValidation()所做的任何事情都不会影响已经传递给 Validator 对象的输入。

我希望我的解释是可以理解的。

于 2021-09-16T11:30:47.073 回答