Laravel 5 __construct()参数传递错误 [英] Laravel 5 __construct() argument passing error

查看:459
本文介绍了Laravel 5 __construct()参数传递错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我正在尝试将所有验证规则分组到文件夹中的相应文件中,以便于维护.下面是我的文件夹结构外观:

So I am trying to group all my validation rules into its respective files in folders for easy maintenance. Below is how my folder structures look:

Project
--app
--config
--(more folders)
--domains
----App
--------Entities
--------Repositories
--------Services
--------Validators
----Core
--------Validators

所以我想实现的是在 Core \ Validators 下,我创建了一个LaravelValidator.php,看起来像这样

So what I wanted to achieve is under Core\Validators I created a LaravelValidator.php which look like this

<?php namespace Core\Validators;

use Validator;

abstract class LaravelValidator {

        /**
         * Validator
         *
         * @var \Illuminate\Validation\Factory
         */
        protected $validator;

        /**
         * Validation data key => value array
         *
         * @var Array
         */
        protected $data = array();

        /**
         * Validation errors
         *
         * @var Array
         */
        protected $errors = array();

        /**
         * Validation rules
         *
         * @var Array
         */
        protected $rules = array();

        /**
         * Custom validation messages
         *
         * @var Array
         */
        protected $messages = array();

        public function __construct(Validator $validator)
        {
                $this->validator = $validator;
        }

        /**
         * Set data to validate
         *
         * @return \Services\Validations\AbstractLaravelValidator
         */
        public function with(array $data)
        {
                $this->data = $data;

                return $this;
        }

        /**
         * Validation passes or fails
         *
         * @return Boolean
         */
        public function passes()
        {
                $validator = Validator::make(
                        $this->data,
                        $this->rules,
                        $this->messages
                );

                if ($validator->fails())
                {
                        $this->errors = $validator->messages();

                        return false;
                }

                return true;
        }

        /**
         * Return errors, if any
         *
         * @return array
         */
        public function errors()
        {
                return $this->errors;
        }

}

然后在我的 App \ Validators 中创建了文件名RegistrationFormValidator.php,看起来像这样

Then in my App\Validators I created a file name RegistrationFormValidator.php which look like this

<?php namespace App\Validators\Profile;

class RegistrationFormValidator extends \Core\Validators\LaravelValidator 
{
    protected $rules = array(
        'first_name'    =>  'required',
        'last_name'     =>  'required',
        'username'      =>  'required',
        'password'      =>  'required',
        'rTPassword'    =>  'required',
        'profile_url'   =>  'required',
        'email'         =>  'required|email',
        'gender'        =>  'required',
        'dob'           =>  'required',
    ); 
}

通常在laravel 4.2中,要验证我所做的所有事情就是构造验证规则,然后在如下所示的服务中调用它

so usually in laravel 4.2, to validate something all i do is construct the validation rules and then call it in services which look like this

<?php namespace App\Services\Profile;

    /*
    |-----------------------------------------------------------
    |   This section injects the repositories being used  
    |   in this service.
    |-----------------------------------------------------------
    */

    use App\Repositories\Profile\ProfileRepository;
    use Core\ValidationFailedException;
    use App\Validators\Profile\RegistrationFormValidator;
    use Validator;

class ProfileService implements ProfileServiceInterface
{
    protected $_profile;
    protected $v;

    /*
    |-----------------------------------------------------------
    |   All construsted models variables must carry 
    |   the '_' sign to identify it as a model variable
    |-----------------------------------------------------------
    */

    public function __construct(ProfileRepository $_profile, RegistrationFormValidator $v)
    {
        $this->_profile = $_profile;
        $this->v = $v;
    }

    /*
    |-----------------------------------------------------------
    |   1.  All try and catch error handling must be done
    |       in the respective controllers.
    |
    |   2.  All data formattings must be done in this section
    |       then pass to repository for storing.
    |
    |   3.  No controller actions allown in this section
    |-----------------------------------------------------------
    */

    public function createProfile($array)
    {

        if($this->v->passes())
        {
           //save into db
        } 
        else 
        {
            throw new ValidationFailedException(
                    'Validation Fail',
                    null,
                    $this->v->errors()
                    );
        }
    }
}

但是问题是,一旦我升级到laravel 5,我就会做同样的事情,当我尝试执行代码时,它会向我返回此错误

But the problem is once i upgraded into laravel 5 i did the same thing and when i try to execute the code it returns me with this error

ErrorException in ProfileService.php line 26:
Argument 2 passed to App\Services\Profile\ProfileService::__construct() must be an instance of App\Validators\Profile\RegistrationFormValidator, none given

我的代码在L4.2中绝对可以正常工作,但是一旦我升级,它就无法工作了.我也知道我可以像这样进行验证

My code works absolutely fine in L4.2 but once i upgraded it wont work anymore. I also know that i can do validation like such

public function createProfile($array)
{
    $v = Validator::make($array, [
        'first_name'    =>  'required',
        'last_name'     =>  'required',
        'username'      =>  'required',
        'password'      =>  'required',
        'rTPassword'    =>  'required',
        'profile_url'   =>  'required',
        'email'         =>  'required|email',
        'gender'        =>  'required',
        'dob'           =>  'required',
    ]); 

    if($v->passes())
    {

    } 
    else 
    {
        throw new ValidationFailedException(
                'Validation Fail',
                null,
                $v->errors()
        );
    }
}

但是问题是,如果我有更多的验证规则或方案,它将淹没整个服务文件.

But the problem is if i would have more validation rules or scenario it will flood the whole service file.

有什么建议或解决方案可以指导我吗?预先感谢!

Any suggestions or solutions that will guide me? thanks in advance!

推荐答案

在Laravel 5中,您有类似的东西,它可以更好地进行验证,并使验证简洁明了.它称为表单请求验证.这里的想法是相同的-拥有不同的类来处理不同场景下的验证.

In Laravel 5 you have something similar, which handles better the validation and makes validation clean and easy. It is called Form Request Validation. The idea there is the same - to have different classes that handle validation in different scenarios.

因此,每当需要验证时,都可以创建新的FormRequest,如下所示:

So whenever you need a validation you can create new FormRequest, like this:

php artisan make:request RegisterFormRequest

将在app/Http/Requests下生成一个新类.在那里您可以看到它有两个方法authorizerules.在第一个中,您可以检查是否允许给定用户发出此请求.在第二种方法中,您可以定义规则,就像在验证器中一样.

A new class will be generated under app/Http/Requests. There you can see it has two methods authorize and rules. In the first one you can make a check if given user is allwed to make this request. In the second method you can define your rules, just like in the validator.

public functions rules() {
    return array(
        'first_name'    =>  'required',
        'last_name'     =>  'required',
        'username'      =>  'required',
        'password'      =>  'required',
        'rTPassword'    =>  'required',
        'profile_url'   =>  'required',
        'email'         =>  'required|email',
        'gender'        =>  'required',
        'dob'           =>  'required',
    );
}

然后您可以像这样更改控制器方法:

Then you can change your controller method like this:

public function postCreateProfile(RegisterFormRequest $request) {
    // your code here
}

这里有一些很酷的东西.第一个-该类将由IoC容器自动注入到您的控制器方法中,而无需执行任何特殊操作.第二件很酷的事情是,在将Request对象传递到控制器之前完成了验证检查,因此,如果发生任何验证错误,您将根据您的规则集将所有错误均重定向回去.这意味着使用postCreateProfile方法编写代码,您可以假定如果执行此代码,则验证会在此位置通过,并且您不需要其他检查.

The are a few cool things here. First one - the class will be automatically constructed in injected in your controller method by the IoC container, you don't need to do something special. The second cool thing is that the validation check is done before the Request object is passed to the controller, so if any validation error occurs you will be redirected back with all errors according to your rules set. This means that writing your code in the postCreateProfile method you can assume if this code get executed the validation is passed at this position and no additional check are needed by you.

我建议您迁移代码以使用Laravel 5 Form Requests,因为所需的东西已经在框架中实现了,是的,基本上,这就是将一个版本迁移到另一个版本的关键所在.您还可以查看文档以获取更多示例.

I suggest you to migrate your code to use Laravel 5 Form Requests, because what you need is already implemented in the framework, and yes basically this is the point of the migration of one version to another. You can also check the documentation for more examples.

这篇关于Laravel 5 __construct()参数传递错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆