Laravel 5 __construct()参数传递错误

时间:2015-05-25 03:56:38

标签: laravel laravel-4 laravel-5 laravel-validation

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

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

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

<?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,它看起来像这样

<?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中,验证我所做的一切是构建验证规则,然后在看起来像这样的服务中调用它

<?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,我做了同样的事情,当我尝试执行代码时,它返回我的错误

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中运行得非常好但是一旦我升级它就不再工作了。我也知道我可以像这样进行验证

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()
        );
    }
}

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

任何可以指导我的建议或解决方案?提前谢谢!

1 个答案:

答案 0 :(得分:2)

在Laravel 5中,您有类似的东西,可以更好地处理验证并使验证变得简洁。它被称为Form Request Validation。这个想法是相同的 - 有不同的类来处理不同场景下的验证。

因此,无论何时需要验证,您都可以创建新的FormRequest,如下所示:

php artisan make:request RegisterFormRequest

将在app/Http/Requests下生成一个新课程。在那里,您可以看到它有两种方法authorizerules。在第一个中,您可以检查给定的用户是否被赋予此请求。在第二种方法中,您可以定义规则,就像在验证器中一样。

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',
    );
}

然后你可以改变你的控制器方法:

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

这里有一些很酷的东西。第一个 - 该类将由IoC容器在您的控制器方法中自动构建,您不需要做一些特殊的事情。第二个很酷的事情是验证检查在Request对象传递给控制器​​之前完成,因此如果发生任何验证错误,您将根据规则集重定向到所有错误。这意味着您可以使用postCreateProfile方法编写代码,如果执行此代码,则可以在此位置传递验证,并且不需要您进行额外检查。

我建议您迁移代码以使用Laravel 5表单请求,因为您需要的内容已在框架中实现,而且基本上这是将一个版本迁移到另一个版本的重点。您还可以查看documentation以获取更多示例。