Laravel 4.2:排除 "Target not instantiable" 错误
Laravel 4.2: Troubleshooting "Target not instantiable" error
过去 2-3 天我一直被这个 "Target not instantiable" 错误所困扰,我不知道为什么。昨天,IRC #laravel 聊天室中有人建议在 Artisan 的 tinker 界面中使用 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'))
returns 可怕的 "Target not instantiable" 错误。
编辑: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')
);
});
}
}
我的表格class
<?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();
}
我认为问题出在 $app->make('Project\Frontend\Repo\Lead\LeadInterface')
。 Laravel 无法知道 class 在这里实例化什么。您必须通过以下方式告诉 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');
过去 2-3 天我一直被这个 "Target not instantiable" 错误所困扰,我不知道为什么。昨天,IRC #laravel 聊天室中有人建议在 Artisan 的 tinker 界面中使用 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'))
returns 可怕的 "Target not instantiable" 错误。
编辑: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')
);
});
}
}
我的表格class
<?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();
}
我认为问题出在 $app->make('Project\Frontend\Repo\Lead\LeadInterface')
。 Laravel 无法知道 class 在这里实例化什么。您必须通过以下方式告诉 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');