Laravel 4 One interface with multiple implementations at same time
interface, laravel, php
Solution
This question took for me long time to solve it. After Laravel 5.0 is out i'm posting solution that i have found using Contextual binding
Consider this example, when one controller needs one interface with multiple implementations.
<?php
// We are creating one abstract controller with one logic
abstract class AbstractSearchController
{
protected $searchService;
public function __construct(SearchServiceInterface $searchService)
{
$this->searchService = $searchService;
}
public function getResult($keyword)
{
return $this->searchService->getItems($keyword);
}
}
// In routes.php file we can point url like: http://example.com/search/posts/?keyword=my-search-keyword to use
// something like this: Route::resource('search/posts', 'PostSearchController', ['only' => ['index']]);
class PostSearchController extends AbstractSearchController
{
// No code here as this controller only is needed so that we can point Specific implementation to it
}
// In routes.php file we can point url like: http://example.com/search/members/?keyword=my-search-keyword to use
// something like this: Route::resource('search/members', 'MemberSearchController', ['only' => ['index']]);
class MemberSearchController extends AbstractSearchController
{
//
}
// Our main interface that will have multiple implementations at same time
interface SearchServiceInterface
{
public function getItems($keyword);
}
// Our first implementation of interface
class MemberSearchRepo implements SearchServiceInterface
{
public function getItems($keyword)
{
// Get members by keyword
}
}
// Our second implementation of interface
class PostSearchRepo implements SearchServiceInterface
{
public function getItems($keyword)
{
// Get posts by keyword
}
}
// When PostsSearchController needs Search Logic point IoC to give our first implementation
$this->app->when('PostSearchController')->needs('SearchServiceInterface')->give('PostSearchRepo');
// When MemberSearchController needs Search Logic point IoC to give our seconds implementation
$this->app->when('MemberSearchController')->needs('SearchServiceInterface')->give('MemberSearchRepo');
I hope this extended example will help people to understand how to implement feature that I needed for Laravel 4.x with abillities that Laravel 5 provides
Problem
Problem is that i don't know how to bind multitple implementations of one interface. Example: ``` // One interface interface SmsInterface { ... } // First implementation using SmsCoin class SmscoinAPI implements SmsInterface { ... } // Second implementation using Fortumo class FortumoAPI implements SmsInterface { ... } ``` // Two controllers: ``` class SmsCoinController { public function __construct(SmsInterface $sms) { $this->sms = $sms } } class FortumoController { public function __construct(SmsInterface $sms) { $this->sms = $sms } } ``` Question: How I can bind SmsInterface with implementation FortumoApi for FortumoController, and bind SmsInterface with implementation SmsCoinApi for SmsCoinController ? I was using ServiceProvider for registering bindings, can I do it there ? If not where should bindings put? EDIT: I can't get answer anywhere, read many laravel books, everywhere is said to use multiple implementations, but nowhere is shown how to swap/switch those implementations. If i have one interface and two implementations, how to bind and swap them in controller. Do i need to do that in that controller constructor method ? or in routes by checking controller's route or in filters.php ? or in Service provider ? and how to technically correclty write that code ?