Repository pattern in PHP and Laravel
A repository is an interface-signed class that encapsulate all SQL queries in specific methods. The repository class is then injected into your controller methods using dependency injection. You use the class methods instead of running sql queries inside the controller logic.
In laravel, the advantage of such pattern is limited because Eloquent's Query builder is already doing all the hard -repetition- work.
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.
First, we will create a repository interface. It can be located anywhere, but in this example, we will use the following directory structure:
namespace App\Repositories\Contracts;
interface ProductRepositoryInterface
{
public function search($name);
public function getAllByUser($user_id);
public function getAllByCategory($category_id);
}
Note that each model will have its own repository interface. This example shows a repository interface for a product model and its implementation with Eloquent:
namespace App\Repositories\Eloquent;
use App\Repositories\Contracts\ProductRepositoryInterface;
use App\Models\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:
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:
'providers' => [
// ...
App\Repositories\Providers\ProductRepositoryServiceProvider::class,
// ...
],
At this point, the repository can be injected into controller classes. An example controller would look like this:
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]);
}
}
Code in copied from this article, but was corrected and improved.
I consider myself as an IT Business Artisan. Or Consultant CTO. I'm a self-taught Web Developper, coach and teacher. My main work is helping and guiding digital startups.
more about meBTC
18SY81ejLGFuJ9KMWQu5zPrDGuR5rDiauM
ETH
0x519e0eaa9bc83018bb306880548b79fc0794cd08
XMR
895bSneY4eoZjsr2hN2CAALkUrMExHEV5Pbg8TJb6ejnMLN7js1gLAXQySqbSbfzjWHQpQhQpvFtojbkdZQZmM9qCFz7BXU
2024 © My Dynamic Production SRL All rights Reserved.