Laravel Interfaces

39,975

In my recent laravel 5 project, I'm used to prepare my logics as Repository method. So here's my current directory structure. For example we have 'Car'.

So first I just create directory call it libs under app directory and loaded it to composer.json

"autoload": {
        "classmap": [
            "database",
            "app/libs" //this is the new changes (remove this comment)
        ]
    }

after that I create a subfolder call it Car . Under the Car folder create two file 'CarEloquent.php' for eloquent implementation and CarInterface.php as interface.

CarInterface

namespace App\libs\Car;
interface CarInterface {
    public function getAll();
    public function create(array $data);
    public function delete($id);
    public function getByID($id);
    public function update($id,array $data);
}

CarEloquent

namespace App\lib\Car;

use App\lib\Car\CarInterface;
use App\Car; //car model
class CarEloquent implements CarInterface {
    protected $car;

    function __construct(Car $a) {
        $this->car = $a;
    }
    public function getAll(){
        return $this->car->all();
    }
}

Then create Car Service Provider to bind ioc controller. For create Car service provider you can also use php artisan command by laravel. php artisan make:provider CarServiceProvider

ServiceProvider

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class CarServiceProvider extends ServiceProvider {
   public function register() {
        $this->app->bind('App\lib\Car\CarInterface', 'App\lib\Car\CarEloquent');
    }

}

And final step would be add these service provider to config/app.php provider array.

'providers' => [
  'App\Providers\CatServiceProvider',
]

And finally we are ready to use our repository method in our controller.

Example Controller

namespace App\Http\Controllers;
use App\lib\Car\CarInterface as Car;
class CarController extends Controller {
    protected $carObject;
    public function __construct(Car $c) {
        $this->carObject = $c;
    }
    public function getIndex(){
        $cars = $this->carObject->getAll();
        return view('cars.index')->with('cars',$cars);
    }
}

Main purpose to achieve here call repository method to controller, however you need use them as per your requirement.

Update

CarEloqent basically help us to improve database implementation, for example in future if you want to implement same functionality for other database like redis you just add another class CarRedis and change implementation file path from server provider.

Update 1: Good Resource

http://programmingarehard.com/2014/03/12/what-to-return-from-repositories.html

[book] From Apprentice to Artisan by Taylor Otwell

Very good explanation about repository method and software design principle commonly called separation of concerns. You should read this book.

If you still have any confusion to achieve these behaviors let me know and however I will keep eye on this question to update this answer, if I find some things to change or update or as per requirement.

Share:
39,975

Related videos on Youtube

Hardist
Author by

Hardist

Updated on July 09, 2022

Comments

  • Hardist
    Hardist almost 2 years

    I used the following tutorial to get an idea about interfaces:

    http://vegibit.com/what-is-a-laravel-interface/

    But I wanted to change the directory of where I am putting my interfaces to "App/Models/Interfaces". And so I did. But now I cannot get it to work anymore. Here is my code:

    Routes.php

    App::bind('CarInterface', 'Subaru');
    
    Route::get('subaru', function()
    {
    $car = App::make('CarInterface');  
    $car->start();
    $car->gas();
    $car->brake(); 
    });
    

    Model Subaru.php

    <?php
    
    use App\Models\Interfaces\CarInterface;
    
    class Subaru implements CarInterface {
    
    ..etc
    

    Interface CarInterface

    <?php namespace App\Models\Interfaces;
    
    interface CarInterface {
    public function start();
    public function gas();
    public function brake();
    }
    

    I added this in my composer.json:

    "psr-0": {
    "Interfaces": "app/models/interfaces"
    }
    

    And I even added this in my start/global.php file:

    ClassLoader::addDirectories(array(
    
    app_path().'/models/interfaces',
    
    • Safoor Safdar
      Safoor Safdar almost 9 years
      what you trying to achieve? i think you talking about repository method right?
    • Hardist
      Hardist almost 9 years
      Just for learning purposes. And yeah repository method is what I am ultimately trying to achieve.
    • Safoor Safdar
      Safoor Safdar almost 9 years
      Cool! all right so what seem to be issue with your current implementation?
    • Hardist
      Hardist almost 9 years
      Thanks a bunch for your answer, this makes a lot more sense than the stuff I found using google. I will see if I can get this to work for myself and then be able to understand it and learn from it :)
    • Safoor Safdar
      Safoor Safdar almost 9 years
      Great to hear that. also share with us if you find any better techniques.
  • Hardist
    Hardist almost 9 years
    I've done all of the above, just to see if it worked for me, but I am getting an error: Class 'App\Providers\CarServiceProvider' not found But that might be since I am using Laravel 4, not 5 :) At least your answer makes sense and I can learn from it, which is the main reason I asked the question in the first place though.
  • Safoor Safdar
    Safoor Safdar almost 9 years
    try to use composer dump-autoload
  • Safoor Safdar
    Safoor Safdar almost 9 years
    yeah, service provide procedure different in laravel5 from laravel4.
  • Hardist
    Hardist about 8 years
    Just wanted to post an update to say that I am currently on Laravel 5 (been for a long time now) and for some reason while googling I came back to this question. I understand a lot more already and there is an error (I believe) in your controller. You use: use App\lib\Car\CarInterface - While this should be use App\lib\Car\CarEloquent. It is working all fine btw, the rest of your code :) Thanks again
  • Hardist
    Hardist about 8 years
    Never mind this above comment of mine, it is silly. Ofcourse you should be using use App\lib\Car\CarInterface. The reason it wasn't working for me because I namespaced something wrong.
  • Safoor Safdar
    Safoor Safdar about 8 years
    @RonBrouwers Nice to hear that, you understand now.
  • Gothiquo
    Gothiquo over 6 years
    Sorry for the comment, I know this post is old, but I have a question. Why should we work with interfaces and repositories instead of the simple Eloquent Model and the classic way ? Any link or tutorial please? Thank you
  • Safoor Safdar
    Safoor Safdar over 6 years
    @MoslemCherif A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection. of course copied :) and its also help write same implementation for multiple available different databases(mysql, pgsql). Just give it a try on google with "Repository Pattern" for laravel.
  • Sumit
    Sumit over 5 years
    After composer dump-autoload and php artisan optimize. It will work correctly.