【问题标题】:Laravel 4.2: Troubleshooting "Target not instantiable" errorLaravel 4.2:解决“目标不可实例化”错误
【发布时间】:2015-04-05 11:31:21
【问题描述】:

在过去的 2-3 天里,我一直被这个“目标不可实例化”错误所困扰,我不知道为什么。昨天,IRC #laravel 聊天室中的某个人建议在 Artisan 的修补程序界面中使用 var_dump(App::make('Project\Frontend\Repo\Lead\LeadInterface')),我已经完成并得到了以下回复:

class Project\Frontend\Repo\Lead\EloquentLead#798 (1) {
  protected $lead =>
  class Lead#809 (21) {
    // bunch of info about the model etc relating to the interface and it's repo class
  }
}

#laravel 中的一位成员指出,这意味着接口已被实例化,这很好,但后来我意识到这不是我遇到问题的接口。

以下是我的设置方式。显然没有实例化的接口是 ValidableInterface (代码的最后一部分)并运行var_dump(App::make('Project\Backend\Service\Validation\ValidableInterface')) 返回可怕的“目标不可实例化”错误。

编辑:new LeadFormLaravelValidator( $app['validator'] ) 扩展了实现 ValidableInterface 的 AbstractLaravelValidator。

我的代码是否遗漏了一些明显的问题?

我的服务提供商

<?php namespace Project\Frontend\Service\Form;

use Illuminate\Support\ServiceProvider;
use Project\Frontend\Service\Form\Lead\LeadForm;
use Project\Frontend\Service\Form\Lead\LeadFormLaravelValidator;

class FormServiceProvider extends ServiceProvider {

/**
 * Register the binding
 *
 * @return void
 */
public function register()
{
    $app = $this->app;

    $app->bind('Project\Frontend\Service\Form\Lead\LeadForm', function($app)
    {
        return new LeadForm(
            new LeadFormLaravelValidator( $app['validator'] ),
            $app->make('Project\Frontend\Repo\Lead\LeadInterface')
        );
    });
}

}

我的表单类

<?php namespace Project\Frontend\Service\Form\Lead;

use Project\Backend\Service\Validation\ValidableInterface;
use Project\Frontend\Repo\Lead\LeadInterface;

class LeadForm {

/**
 * Form Data
 *
 * @var array
 */
protected $data;

/**
 * Validator
 *
 * @var \Project\Backend\Service\Validation\ValidableInterface
 */
protected $validator;

/**
 * Lead repository
 *
 * @var \Project\Frontend\Repo\Lead\LeadInterface
 */
protected $lead;

public function __construct(ValidableInterface $validator, LeadInterface $lead)
{
    $this->validator = $validator;
    $this->lead = $lead;
}

我的验证规则

<?php namespace Project\Frontend\Service\Form\Lead;

use Project\Backend\Service\Validation\AbstractLaravelValidator;

class LeadFormLaravelValidator extends AbstractLaravelValidator {

/**
 * Validation rules
 *
 * @var Array
 */
protected $rules = array(
    'name'              => 'required|regex:/^[a-zA-Z-\s]+$/',
    'email'             => 'email',
    'cell'              => 'required|numeric|digits_between:10,11',
);

/**
 * Validation messages
 *
 * @var Array
 */
protected $messages = array(
    'regex'                 => 'The :attribute may only contain letters, dashes and spaces.',
    'digits_between'        => 'The :attribute must be 10 numbers long.',
);

}

我的抽象验证器

<?php namespace Project\Backend\Service\Validation;

use Illuminate\Validation\Factory;

abstract class AbstractLaravelValidator implements ValidableInterface {

/**
 * 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(Factory $validator)
{
    $this->validator = $validator;
}

/**
 * Set data to validate
 *
 * @return \Project\Backend\Service\Validation\AbstractLaravelValidator
 */
public function with(array $data)
{
    $this->data = $data;

    return $this;
}

/**
 * Validation passes or fails
 *
 * @return Boolean
 */
public function passes()
{
    $validator = $this->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;
}

}

我的验证器界面

<?php namespace Project\Backend\Service\Validation;

interface ValidableInterface {

/**
 * Add data to validation against
 *
 * @param array
 * @return \Project\Backend\Service\Validation\ValidableInterface  $this
 */
public function with(array $input);

/**
 * Test if validation passes
 *
 * @return boolean
 */
public function passes();

/**
 * Retrieve validation errors
 *
 * @return array
 */
public function errors();

}

【问题讨论】:

    标签: php laravel ioc-container instantiation


    【解决方案1】:

    我相信问题出在$app-&gt;make('Project\Frontend\Repo\Lead\LeadInterface')。 Laravel 无法知道要在这里实例化什么类。你必须通过这样做来告诉 Laravel:

    $app->bind('Project\Frontend\Repo\Lead\LeadInterface', 'Your\Implementation\Of\LeadInterface');
    

    编辑

    很奇怪,因为您手动实例化 LeadForm 并注入 LeadFormLaravelValidator,所以您得到了该异常。但是,这应该可以解决问题:

    $app->bind('Project\Backend\Service\Validation\ValidableInterface', 
               'Project\Frontend\Service\Form\Lead\LeadFormLaravelValidator');
    

    【讨论】:

    • 感谢您的回复@lukasgeiter。我会尝试您的建议并回复您。
    • 那行不通。 LeadInterface 是顺便实例化的,因为如果您阅读我的问题的第一部分,您会看到它在我执行 var_dump() 时返回数据。我将使用此信息更新问题,以便更清楚。问题在于new LeadFormLaravelValidator( $app['validator'] )
    • 我根据您在编辑中的建议尝试了很多东西,但都没有奏效。我得到的唯一不同的错误是:“传递给 Project\Frontend\Service\Form\Lead\LeadForm::__construct() 的参数 1 必须是 Project\Backend\Service\Validation\ValidableInterface 的实例,给定 null”...当我这样做时... return new LeadForm( $app->bind('Project\Backend\Service\Validation\ValidableInterface', 'Project\Frontend\Service\Form\Lead\LeadFormLaravelValidator'), $app->make( 'Project\Frontend\Repo\Lead\LeadInterface') );
    • 不,您不应该在构造函数调用中执行 $app-&gt;bind() 调用。就在您的 register() 方法中的另一个 $app-&gt;bind() 之前。
    • 我认为这对我来说是不对的。我会快速测试一下。
    猜你喜欢
    • 1970-01-01
    • 2015-03-01
    • 2015-06-07
    • 2016-06-22
    • 2013-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-05
    相关资源
    最近更新 更多