Php Laravel 5.1当一种方法需要一个字段,而另一种方法不需要字段时,如何对两种方法使用相同的表单请求规则?

Php Laravel 5.1当一种方法需要一个字段,而另一种方法不需要字段时,如何对两种方法使用相同的表单请求规则?,php,forms,validation,laravel,laravel-5.1,Php,Forms,Validation,Laravel,Laravel 5.1,我有一个有3个文件输入字段的表单,用户应该上传至少一个文件。我有一个表单请求,我正在其中验证它们,如下所示: public function rules() { $this->prepInput(); return [ 'comment' => 'max:2000', 'source' => 'different:target', 'file1'=>'required

我有一个有3个文件输入字段的表单,用户应该上传至少一个文件。我有一个表单请求,我正在其中验证它们,如下所示:

public function rules()
    {
     $this->prepInput();
        return [
            'comment' => 'max:2000',
            'source' => 'different:target',
            'file1'=>'required_without_all:file2,file3|between:1,15360|mimes:txt,pdf',
            'file2'=>'required_without_all:file1,file3|between:1,15360|mimes:txt,pdf',
            'file3'=>'required_without_all:file1,file2|between:1,15360|mimes:txt,pdf'

        ];
    } 
myprojects/{myprojects}/edit | myprojects.edit | App\Http\Controllers\MyProjectsController@edit

为了更新相同的表单,我在控制器中使用了
update
方法,这与
store
方法几乎相同。唯一的区别是更新表单中不需要文件。有没有办法将相同的表单请求与
存储
更新
方法一起使用,并选择性地应用所需的规则?

就像使用方法一样
$this->prepInput()我建议您更改一点代码以重用

  • 必须为创建和编辑两条管线创建命名管线。我假设您使用的是足智多谋的路由
  • 像下面那样更改代码

    public function isEditRequestCalled()
    {
      return app('router')->getCurrentRoute()->getName() == 'YOUR_EDIT_ROUTE_NAME';
    }
    
  • 在您的请求方法中,您可以这样更改

        public function rules()
        {
          $this->prepInput();
          return $this->isEditRequestCalled() ? [
            //YOUR EDIT RULES GOES HERE
          ] : [//YOUR CREATE RULES GOES HERE
            'comment' => 'max:2000',
            'source' => 'different:target',
            'file1'=>'required_without_all:file2,file3|between:1,15360|mimes:txt,pdf',
            'file2'=>'required_without_all:file1,file3|between:1,15360|mimes:txt,pdf',
            'file3'=>'required_without_all:file1,file2|between:1,15360|mimes:txt,pdf'
    
          ];
        }
    

    我使用了以下技巧,效果很好:

     public function rules()
        {
        $this->prepInput();
            $rules= [
                'comment' => 'max:2000',
                'source' => 'different:target',
                'file1'=>'required_without_all:file2,file3|between:1,15360|mimes:txt,pdf',
                'file2'=>'required_without_all:file1,file3|between:1,15360|mimes:txt,pdf',
                'file3'=>'required_without_all:file1,file2|between:1,15360|mimes:txt,pdf'
    
            ];
            if($this->myprojects){
                $rules['file1'] = 'between:1,15360|mimes:txt,pdf';
                $rules['file2'] = 'between:1,15360|mimes:txt,pdf';
                $rules['file3'] = 'between:1,15360|mimes:txt,pdf';
            }
    
              return  $rules;
        }
    
    以下是我的路线信息:

    public function rules()
        {
         $this->prepInput();
            return [
                'comment' => 'max:2000',
                'source' => 'different:target',
                'file1'=>'required_without_all:file2,file3|between:1,15360|mimes:txt,pdf',
                'file2'=>'required_without_all:file1,file3|between:1,15360|mimes:txt,pdf',
                'file3'=>'required_without_all:file1,file2|between:1,15360|mimes:txt,pdf'
    
            ];
        } 
    
    myprojects/{myprojects}/edit | myprojects.edit | App\Http\Controllers\MyProjectsController@edit
    

    因此我的
    myprojects
    实体的id是
    $this->myprojects
    。如果为空,则创建一个
    myprojects
    ,如果有值,则更新相应的
    myprojects
    我使用单独的
    规则
    类,基本上只存储
    $rules
    $messages
    我需要在
    FormRequest
    类中使用和重用

    class RulePrep
    {
        /**
         * @var array
         */
        public $rules = [];
    
        /**
         * @var array
         */
        public $messages = [];
    }
    
    class RuleProjects
    {
        /**
         * @var array
         */
        public $rules = [];
    
        /**
         * @var array
         */
        public $messages = [];
    }
    
    你可以试试吗?
    您需要单独的FormRequest类,但它可能比捆绑在一个包含条件逻辑的类中更整洁。

    我基本上为两个请求使用一个抽象基类,然后在子类中添加任何必需的规则。这将保持干燥,并为添加规则提供了一种灵活的方法。例如:

    抽象类CompanyBaseRequest扩展了FormRequest
    {
    ...
    公共职能规则()
    {
    返回[
    'name'=>['required'、'string'、'max:255'],
    'category_id'=>['required','exists:公司_categories,id'],
    'short_description'=>['required','string','max:2000'],
    'video'=>['nullable'、'file'、'mimes:mp4'、'max:30000'],
    ];
    }
    }
    
    然后是两个子类:

    类CompanyStoreRequest扩展了CompanyBaseRequest
    {
    ...
    公共职能规则()
    {
    返回数组_merge(父::规则()[
    'logo'=>['required','file','mimes:png,jpg,jpeg','max:1024'],
    ]);
    }
    }
    
    类CompanyUpdateRequest扩展CompanyBaseRequest
    {
    ...
    公共职能规则()
    {
    返回数组_merge(父::规则()[
    'logo'=>['nullable','file','mimes:png,jpg,jpeg','max:1024'],
    ]);
    }
    }
    
    您应该在需要的地方使用这些子类中的一个,它们都包含来自基类的规则和来自它们自身的规则


    这与公认的答案相比更好,因为表单本身以自己的名义明确说明了它们所做的事情,而不是只使用一个条件(不清楚它们检查了什么)。

    是的,我使用的是资源路由。除了命名路由,还有其他解决方案吗?您必须首先使用条件才能在两个操作中使用它。因此,您需要一种机制来区分两个操作,这就是为什么命名路由更简单。您可以使用此解决方案,并在存储和更新方法中插入请求类。这非常容易。这是实现这一点的逻辑方法,并且还利用了OOP。