7

これは、この質問に関連しています。laravel4に名前空間を登録する方法ですが、うまくいき、名前空間が機能していると思います。

私が遭遇した新しい問題があります。エラーは、コントローラーコンストラクターにヒントを入力しようとしたことが原因であり、名前空間の使用とiocの使用に関係していると思います。

BindingResolutionException: Target [App\Models\Interfaces\PostRepositoryInterface] is not instantiable.

以下の方法は、名前空間を導入しようとするまでは完全に機能していました。すべての名前空間を削除し、インターフェイスとリポジトリを同じディレクトリに配置できますが、iocを使用するこの方法で名前空間を機能させる方法を知りたいです。

関連するファイルは次のとおりです。

ルート.php

Route::resource('posts', 'PostsController');

PostController.php

<?php
use App\Models\Interfaces\PostRepositoryInterface;
class PostsController extends BaseController {

    public function __construct( PostRepositoryInterface $posts )
    {
        $this->posts = $posts; 
    }

}

PostRepositoryInterface.php

<?php namespace App\Models\Interfaces;
interface PostRepositoryInterface {
    public function all();
    public function find($id);
    public function store($data);
}

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

そして、あなたは作曲家のダンプを見ることができます-autoloadはそれが仕事をしました。

composer / 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',

    ....
    )

これをネームパックなしで機能させるために、どこで、または何を変更する必要があるかについてのアイデアはありますか?

ありがとう

4

2 に答える 2

37

この質問はすでに回答済みですが、この " target interface is not instantiable"エラーのもう1つの一般的な原因は、にサービスプロバイダーを登録するのを忘れたことですapp/config/app.php

これは、を使用している場合ではなく、ServiceProviderクラスを拡張している場合にのみ適用されますApp::bind()

私はそれについて何かを投稿しないように何度もその間違いを犯しました。したがって、上記の長い道のりを進む前に、必ずそれらのプロバイダーを登録してください。

于 2013-09-26T19:27:30.573 に答える
13

簡単に言えば、App :: bind()で完全な名前空間を使用して、最初のエラーを修正します。次に、EloquentPostRepository.phpでは、宣言された名前空間があるため、他の外部クラス呼び出しを同じ名前空間にあるかのように処理しようとします。単純な'usePost;'を追加します。'Post'が同じ名前空間(App \ Models \ Repository)にないことをPHPに通知します。これは、名前空間が使用されると、他のクラスにはデフォルトでクラス名が何であれ名前空間が含まれるためだと思います。修正して機能しているすべてのコードを再投稿するのが最も簡単だと思いました。

ルート.php

<?php

App::bind('App\Models\Interfaces\PostRepositoryInterface',  'App\Models\Repositories\EloquentPostRepository');

Route::resource('posts', 'PostsController');

PostController.php

<?php
use App\Models\Interfaces\PostRepositoryInterface;

class PostsController extends BaseController {

    public function __construct(PostRepositoryInterface $posts)
    {
        $this->posts = $posts;
    }

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

<?php namespace App\Models\Interfaces;
interface PostRepositoryInterface {
    public function all();
    public function find($id);
    public function store($data);
}

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

}
于 2013-03-06T04:32:11.610 に答える