Laravel 4 目标接口不可实例化
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15236878/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Laravel 4 target interface is not instantiable
提问by isimmons
This is related to this question How to register a namespace in laravel 4but I believe I got that worked out and namespaces are working now.
这与How to register a namespace in laravel 4这个问题有关,但我相信我已经解决了这个问题并且命名空间现在正在工作。
There is a new problem I've run into. I believe the error is coming from trying to type hint in the controller constructor and has to do with using namespaces and using ioc.
我遇到了一个新问题。我相信错误来自试图在控制器构造函数中输入提示,并且与使用命名空间和使用 ioc 有关。
BindingResolutionException: Target [App\Models\Interfaces\PostRepositoryInterface] is not instantiable.
The method below worked perfectly until I tried to introduce namespaces. I can remove all the namespaces and put the interface and repositories in the same directory but would like to know how to make namespaces work with this method of using the ioc.
下面的方法工作得很好,直到我尝试引入命名空间。我可以删除所有命名空间并将接口和存储库放在同一目录中,但想知道如何使用这种使用 ioc 的方法使命名空间工作。
Here are the relevant files.
以下是相关文件。
routes.php
路由文件
Route::resource('posts', 'PostsController');
PostController.php
后控制器.php
<?php
use App\Models\Interfaces\PostRepositoryInterface;
class PostsController extends BaseController {
public function __construct( PostRepositoryInterface $posts )
{
$this->posts = $posts;
}
}
PostRepositoryInterface.php
PostRepositoryInterface.php
<?php namespace App\Models\Interfaces;
interface PostRepositoryInterface {
public function all();
public function find($id);
public function store($data);
}
EloquentPostRepository.php
EloquentPostRepository.php
<?php namespace App\Models\Repositories;
use App\Models\Interfaces\PostRepositoryInterface;
class EloquentPostRepository implements PostRepositoryInterface {
public function all()
{
return Post::all();
//after above edit it works to this point
//error: App\Models\Repositories\Post not found
//because Post is not in this namespace
}
public function find($id)
{
return Post::find($id);
}
public function store($data)
{
return Post::save($data);
}
}
And you can see composer dump-autoload did it's job.
你可以看到 composer dump-autoload 完成了它的工作。
composer/autoload_classmap.php
作曲家/autoload_classmap.php
return array(
'App\Models\Interfaces\PostRepositoryInterface' => $baseDir . '/app/models/interfaces/PostRepositoryInterface.php',
'App\Models\Repositories\EloquentPostRepository' => $baseDir . '/app/models/repositories/EloquentPostRepository.php',
....
)
Any ideas where or what I need to change to make this work with namepaces like it does without them?
任何想法我需要改变什么地方或什么才能使这个与命名空间一起工作,就像没有它们一样?
Thanks
谢谢
回答by patricksayshi
I know this question has already been answered but I'd like to remind future readers that another common cause of this "target interface is not instantiable
" error is to have forgotten to register a service provider in app/config/app.php
.
我知道这个问题已经得到解答,但我想提醒未来的读者,这个“ target interface is not instantiable
”错误的另一个常见原因是忘记在app/config/app.php
.
This only applies if you're extending the ServiceProvider class, not if you're using App::bind()
.
这仅适用于扩展 ServiceProvider 类的情况,而不适用于使用App::bind()
.
I've made that mistake one too many times not to post something about it. So before you go down the lengthy path outlined above, make sure to register those providers!
我已经犯了太多次这样的错误,以至于不想发布有关它的信息。因此,在您踏上上述冗长的道路之前,请务必注册这些提供商!
回答by isimmons
Ok, the short answer: Use the complete namespace in App::bind() to fix the first error. Then in EloquentPostRepository.php because it has a declared namespace it tries to treat any other external class calls as if they are in the same namespace. Adding a simple 'use Post;' lets PHP know that 'Post' is not in the same namespace (App\Models\Repositories). I assume this is because once a namespace is used, other classes by default have a namespace of whatever the class name is. I thought it would be easiest to just re-post all of the code corrected and working.
好的,简短的回答:使用 App::bind() 中的完整命名空间来修复第一个错误。然后在 EloquentPostRepository.php 中,因为它有一个声明的命名空间,它试图将任何其他外部类调用视为在同一个命名空间中。添加一个简单的“使用帖子;” 让 PHP 知道“Post”不在同一个命名空间(App\Models\Repositories)中。我认为这是因为一旦使用了命名空间,默认情况下其他类都有一个与类名称相同的命名空间。我认为最简单的方法是重新发布所有更正和工作的代码。
routes.php
路由文件
<?php
App::bind('App\Models\Interfaces\PostRepositoryInterface', 'App\Models\Repositories\EloquentPostRepository');
Route::resource('posts', 'PostsController');
PostController.php
后控制器.php
<?php
use App\Models\Interfaces\PostRepositoryInterface;
class PostsController extends BaseController {
public function __construct(PostRepositoryInterface $posts)
{
$this->posts = $posts;
}
EloquentPostRepository.php
EloquentPostRepository.php
<?php namespace App\Models\Repositories;
use App\Models\Interfaces\PostRepositoryInterface;
use Post;
class EloquentPostRepository implements PostRepositoryInterface {
public function all()
{
return Post::all();
}
public function find($id)
{
return Post::find($id);
}
public function store($data)
{
return Post::save($data);
}
}
PostRepositoryInterface.php
PostRepositoryInterface.php
<?php namespace App\Models\Interfaces;
interface PostRepositoryInterface {
public function all();
public function find($id);
public function store($data);
}
Post.phpNothing relevant here other than showing it has no declared namespace
Post.php除了显示它没有声明的命名空间外,这里没有任何相关内容
<?php
class Post extends BaseModel {
public static $rules = [
'title' => 'required',
'body' => 'required',
'author_id' => 'required|numeric'
];
public static $factory = [
'title' => 'string',
'body' => 'text'
];
public function user()
{
return $this->belongsTo('User', 'author_id');
}
}