dcsimg
July 21, 2017
Hot Topics:

The Repository Pattern in PHP

  • May 17, 2017
  • By Vojislav Janjic
  • Send Email »
  • More Articles »

What is the Repository Pattern?

A repository represents an architectural layer that handles communication between the application and data source. It is a widely used pattern whose main point is that the application does not have to know which data source is implemented and how it is implemented. This makes it easier to switch to another data source or implement structural changes to the existing data source.

The repository pattern introduces a repository interface, which defines how the application and the data sources should communicate. Each data source has its own class which implements the repository interface. The controller class will call the methods defined in the repository interface and will not know how and from where the data is being fetched from.

Implementation in Laravel

First, we will create a repository interface. It can be located anywhere, but in this example, we will use the following directory structure:

  • app/Repositories/Contracts: All repository interfaces will be stored here
  • app/Repositories/Eloquent: All interface Eloquent implementations can be found here
  • app/Repositories/Providers: Service providers for repositories are saved in this folder
<?php
namespace App\Repositories\Contracts;

interface ProductRepositoryInterface
{
   public function search($name);

   public function getAllByUser($user_id);

   public function getAllByCategory($category_id);
}

Note that each entity will have its own repository interface. This example shows a repository interface for a product entity and its implementation with Eloquent:

<?php
namespace App\Repositories\Eloquent;

use App\Repositories\Contracts\ProductRepositoryInterface;
use App\Entity\Product;

class ProductRepository implements ProductRepositoryInterface
{

   public function search($name)
   {
      return Product::where('title', 'LIKE', '% ' . $name . '%')
         ->get();
   }

   public function getAllByUser($user_id)
   {
      return Product::where('user_id', '=', $user_id)
         ->get();
   }

   public function getAllByCategory($category_id)
   {
      return Product::where('category_id', '=', $category_id)
         ->get();
   }
}

To be able to use these classes in the framework, we need to register the service provider:

<?php
namespace App\Repositories\Providers;
use Illuminate\Support\ServiceProvider;
class ProductRepositoryServiceProvider extends ServiceProvider
{
   public function register()
   {
      $this->app->bind(
         'App\Repositories\Contracts\ProductRepositoryInterface',
         // To change the data source, replace this class name
         // with another implementation
         'App\Repositories\Eloquent\ProductRepository'
      );
   }
}

Finally, the service provider needs to be added to the configuration file:

<?php
...
'providers' => [

   /*
    * Laravel Framework Service Providers...
    */
   Illuminate\Auth\AuthServiceProvider::class,
   Illuminate\Broadcasting\BroadcastServiceProvider::class,
   Illuminate\Bus\BusServiceProvider::class,
   Illuminate\Cache\CacheServiceProvider::class,
   Illuminate\Foundation\Providers\
      ConsoleSupportServiceProvider::class,
   Illuminate\Cookie\CookieServiceProvider::class,
   Illuminate\Database\DatabaseServiceProvider::class,
   Illuminate\Encryption\EncryptionServiceProvider::class,
   Illuminate\Filesystem\FilesystemServiceProvider::class,
   Illuminate\Foundation\Providers\FoundationServiceProvider::class,
   Illuminate\Hashing\HashServiceProvider::class,
   Illuminate\Mail\MailServiceProvider::class,
   Illuminate\Pagination\PaginationServiceProvider::class,
   Illuminate\Pipeline\PipelineServiceProvider::class,
   Illuminate\Queue\QueueServiceProvider::class,
   Illuminate\Redis\RedisServiceProvider::class,
   Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
   Illuminate\Session\SessionServiceProvider::class,
   Illuminate\Translation\TranslationServiceProvider::class,
   Illuminate\Validation\ValidationServiceProvider::class,
   Illuminate\View\ViewServiceProvider::class,

   /*
    * Application Service Providers...
    */
   App\Providers\AppServiceProvider::class,
   App\Providers\EventServiceProvider::class,
   App\Providers\RouteServiceProvider::class,

   App\Repositories\Providers\
      ProductRepositoryServiceProvider::class,
],

At this point, the repository can be injected into controller classes. An example controller would look like this:

<?php
namespace App\Http\Controllers;

use Illuminate\Routing\Controller as BaseController;
use Illuminate\Http\Request;
use App\Repositories\Contracts\ProductRepositoryInterface;
class ProductController extends BaseController
{
   protected $productRepository;

   // $productRepository will call the methods from the
   // class defined above in the service provider
   public function __construct(ProductRepositoryInterface
      $productRepository)
   {
      $this->productRepository = $productRepository;
   }

   public function search(Request $request)
   {
      $name = $request->input('name');
      $products = $this->productRepository->search($name);
      return view('home.index', ['products' => $products]);
   }
}





Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Sitemap | Contact Us

Thanks for your registration, follow us on our social networks to keep up-to-date
Rocket Fuel