php Laravel 5 - 接口不可实例化
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29690056/
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 5 - Interface is not instantiable
提问by Andrew Kulakov
I know that this question was asked so many times, but none of answers helped me.
我知道这个问题被问了很多次,但没有一个答案对我有帮助。
I'm getting exception in Laravel 5
我在 Laravel 5 中遇到异常
BindingResolutionException in Container.php line 785:
Target [App\Contracts\CustomModelInterface] is not instantiable.
What I've done without success:
我所做的没有成功:
- Register
App\Providers\AppRepositoryProvider
inapp.php
providers php artisan clear-compiled
- Everything works if I replace interfaces on repositories in MyService, but I feel that it's wrong (should it be handled by IoC container?).
App\Providers\AppRepositoryProvider
在app.php
提供者中注册php artisan clear-compiled
- 如果我在 MyService 中替换存储库上的接口,一切正常,但我觉得这是错误的(应该由 IoC 容器处理吗?)。
Structure:
结构:
app
- Contracts
- CustomModelInterface.php
- Models
- CustomModel.php
- Repositories
- CustomModelRepository.php
- Providers
- AppRepositoryProvider.php
- Services
- MyService.php
App\Contracts\CustomModelInterface.php
App\Contracts\CustomModelInterface.php
<?php namespace App\Contracts;
interface CustomModelInterface {
public function get();
}
App\Repositories\CustomModelRepository.php
App\Repositories\CustomModelRepository.php
<?php namespace App\Repositories;
use App\Contracts\CustomModelInterface;
use App\Models\CustomModel;
class CustomModelRepository implements CustomModelInterface {
private $Model;
public function __construct(CustomModel $model) {
$this->Model = $model;
}
public function get() {
return 'result';
}
}
App\Services\MyService.php (Keep business logic / layer between controller and repositories)
App\Services\MyService.php(在控制器和存储库之间保留业务逻辑/层)
<?php namespace App\Services;
use App\Contracts\CustomModelInterface;
class MyService {
private $Model;
public function __construct(CustomModelInterface $customModel) {
$this->Model= $customModel;
}
public function getAll() {
return $this->Model->get();
}
}
App\Providers\AppRepositoryProvider.php
App\Providers\AppRepositoryProvider.php
<?php namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppRepositoryProvider extends ServiceProvider {
public function boot() {}
public function register() {
$models = array(
'CustomModel'
);
foreach ($models as $idx => $model) {
$this->app->bind("App\Contracts\{$model}Interface", "App\Repositories\{$model}Repository");
}
}
}
My controller looks like:
我的控制器看起来像:
<?php namespace App\Http\Controllers;
use App\Services\MyService;
class SuperController extends Controller {
private $My;
public function __construct(MyService $myService) {
$this->My = $myService;
}
public function getDetails() {
return $this->My->getAll();
}
}
composer.json
作曲家.json
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App\": "app/",
"App\Models\": "app/Models/",
"App\Contracts\": "app/Contracts/",
"App\Repositories\": "app/Repositories/"
}
},
采纳答案by Andrew Kulakov
Thank you everyone, but problem was in my AppRepositoryProvider. As it's binding exception, then obviously the problem was with binding :)
谢谢大家,但问题出在我的 AppRepositoryProvider 中。由于它是绑定异常,那么显然问题出在绑定上:)
Correct file is:
正确的文件是:
<?php namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppRepositoryProvider extends ServiceProvider {
public function boot() {}
public function register() {
$models = array(
'CustomModel',
'CustomModel2',
'CustomModel3'
);
foreach ($models as $model) {
$this->app->bind("App\Contracts\{$model}Interface", "App\Repositories\{$model}Repository");
}
}
}
Note, that I'm using "App\Contracts\\{$model}Interface"
(not escaping "{" symbol) and it generate correct string App\Contracts\CustomModelInterface
instead of App\Contracts\{$model}Interface
(with unexpected escaping).
请注意,我正在使用"App\Contracts\\{$model}Interface"
(不转义“{”符号)并且它生成正确的字符串App\Contracts\CustomModelInterface
而不是App\Contracts\{$model}Interface
(意外转义)。
回答by Vlad Visinescu
Every time I create a new repository/contract pair I make sure I do the following:
每次创建新的存储库/合约对时,我都会确保执行以下操作:
- check the classes used in the service provider (copy/paste the namespaces)
- register a new binding in config/app.php
- php artisan optimize
- 检查服务提供者中使用的类(复制/粘贴命名空间)
- 在 config/app.php 中注册一个新的绑定
- php工匠优化
Many hours of useless debugging led me to this short checklist.
许多小时的无用调试使我找到了这个简短的清单。
回答by Beulah Ana
For me, I forgot to bind in app->providers->RepositoryServiceProvider
the repository like this in the register method
对我来说,我忘记app->providers->RepositoryServiceProvider
在注册方法中像这样绑定到存储库中
public function register()
{
$this->app->bind(
\App\Play\Contracts\PatientRepository::class,
\App\Play\Modules\PatientModule::class
);
}
Make sure your RepositoryServiceProvide
r is registered in AppServiceProvider
.
确保您的RepositoryServiceProvide
r 已在AppServiceProvider
.
public function register()
{
$this->app->register(RepositoryServiceProvider::class);
}
回答by Connor Leech
I got past this error running:
我克服了这个错误运行:
php artisan config:clear
php artisan clear-compiled
php artisan optimize
php artisan config:cache
Related to:
相关:
Target is not instantiable. Laravel 5 - App binding service provider
回答by Sougata Bose
On App\Services\MyService.php
you are passing that interface with dependency injection which tries to instantiate that -
在App\Services\MyService.php
你逝去的依赖注入该接口它试图实例化-
public function __construct(CustomModelInterface $customModel) {
$this->Model= $customModel;
}
which is wrong.
这是错误的。
Try implement that in that class - class MyService implements CustomModelInterface {
and use the function of that interface like -
尝试在该类中实现它 -class MyService implements CustomModelInterface {
并使用该接口的功能 -
$this->get();
Or you are using it - class CustomModelRepository implements CustomModelInterface {
或者你正在使用它 - class CustomModelRepository implements CustomModelInterface {
So if you do -
所以如果你这样做——
public function __construct(CustomModelRepository $customModel) {
$this->Model= $customModel;
}
then also you can access the interface methods.
然后你也可以访问接口方法。
回答by Kenny Body
I've just experienced an issue similar to this and the cause of my error was that I had set $defer
to true
in the service provider class but I had not implemented the required provides()
method.
我刚刚遇到了一个与此类似的问题,我的错误的原因是我在服务提供者类中设置$defer
了true
,但我没有实现所需的provides()
方法。
If you have deferred the creation of your class until it is need rather than it being loaded eagerly, then you need to also implement the provides
method which should simply return an array of the classes that the provider provides. In the case of an interface, I believe it should be the name of the interface rather than the concrete class.
如果您推迟了类的创建,直到需要它而不是急切地加载它,那么您还需要实现该provides
方法,该方法应该简单地返回提供者提供的类的数组。在接口的情况下,我认为它应该是接口的名称而不是具体的类。
E.g.
例如
public method provides(): array
{
return [
MyInterface::class,
];
}
Current documentation: https://laravel.com/docs/5.5/providers#deferred-providers
当前文档:https: //laravel.com/docs/5.5/providers#deferred-providers
I hope this helps somebody else.
我希望这对其他人有帮助。
回答by Umang Soni
Don't worry guys. I have a solution to your problem.
别担心,伙计们。我有一个解决你的问题的方法。
I have an example for you.
我有一个例子给你。
Step1: php artisan make:repository Repository/Post//By adding this command you can create a repository and eloquent files
Step1: php artisan make:repository Repository/Post//添加这个命令就可以创建repository和eloquent文件
Step2: After adding that file you have to add/use this repository in the controller in which you want to use.
步骤 2:添加该文件后,您必须在要使用的控制器中添加/使用此存储库。
for eg: use App\Repositories\Contracts\PostRepository;
例如:使用 App\Repositories\Contracts\PostRepository;
Step3: After adding that repo in your controller if you will run the app you will get an error like " Interface is not instantiable". It comes because you have created a repo and used in a controller, but laravel don't know where this repository is register and bind with which eloquent. So that it throws an error.
第 3 步:在您的控制器中添加该 repo 后,如果您将运行该应用程序,您将收到类似“接口不可实例化”的错误消息。这是因为你已经创建了一个 repo 并在一个控制器中使用,但是 laravel 不知道这个存储库在哪里注册并绑定到哪个 eloquent。所以它会抛出一个错误。
Step4: To solve this error you have to bind your repo with your eloquent in AppServiceProvider. E.g:
步骤 4:要解决此错误,您必须将您的 repo 与AppServiceProvider 中的 eloquent 绑定。例如:
AppServiceProvider.php file
AppServiceProvider.php 文件
<?php
namespace App\Providers;
// **Make sure that your repo file path and eloquent path must be correct.**
use App\Repositories\Contracts\PostRepository; // **Use your repository here**
use App\Repositories\Eloquent\EloquentPostRepository; **// Use your eloquent here**
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider {
/**
* Register any application services.
*
* @return void
*/
public function register() {
**// And bind your repository and eloquent here. **
$this->app->bind(PostRepository::class, EloquentPostRepository::class);
}
}
Step5: After binding repo and eloquent you can use all method of repo in your controller. Enjoy.....
第五步:绑定 repo 和 eloquent 后,您可以在控制器中使用所有 repo 方法。享受.....
Please let me know if you have any query.
如果您有任何疑问,请告诉我。
回答by jibril90
The problem is solved by adding your repository in app/providers/AppServiceProvider like the example below.
通过在 app/providers/AppServiceProvider 中添加您的存储库来解决该问题,如下例所示。
public function register()
{
$this->app->singleton(UserRepository::class, EloquentUser::class);
}
Dont forget the name space
不要忘记命名空间
use Test\Repositories\EloquentUser;
use Test\Repositories\UserRepository;
It worked for me
它对我有用
回答by Softmixt
execute this command :
执行这个命令:
composer dump-autoload
回答by Lea de Groot
Note that this can also be caused by the _constructor on the class being declared private, or otherwise being blocked... If it cant call the constructor, the binding will fail
请注意,这也可能是由于类上的 _constructor 被声明为私有导致的,或者以其他方式被阻塞......如果它无法调用构造函数,则绑定将失败