Home page display some information from other controllers, like news, article, etc. What is the best way of using other controller's method in one controller?
Suppose there is one controller called HomeController
,is it correct to instantiate a Controller class within home controller?
forexample, if I want to use NewsController
,instantiate it!?
The following code is just an example, I want to know that what is the best way to access a method or model in another controller?
class HomeController extends Controller
{
public function index()
{
$news_obj = new NewsController();
$news = $news_obj->getNews();
$article_obj = new ArticleController();
$articles = $article_obj->getArticles();
return view('template',['news'=>$news,'articles'=>$articles]);
}
}
I agree with @ptrTon on this, I'd suggest adopting a Repository pattern. It may be a bit of a work depending on your app size, but it's defenitely cleaner than instantiating a controller inside another controller.
Basically with this approach you don't manipulate your model directly but you use instead an object which is, in fact, an extra layer. The main advantage of this is that you can extract common operations and perform them from anywhere not inside the controller, but inside an object which the only responsability is to manage the operations on your models, further separating the responsabilities of your app components. With Laravel you can also add a custom route resolution logic which will inject these repositories in your controllers using the IoC container.
If you want to take it further, you could create the repository in a way that it behaves as the model which wraps, and extends its functionalities (PHP's magic methods are your friends). Providing a full example in a single answer can be complicated, but I'll link some intresting resources below.
Repository pattern in Laravel - example
Laravel's explicit model binding (see the "customizing resolution logic" section)
It's cleaner to not re-use controllers in other controllers. A nicer way would be to extract the logic you want to re-use from the controller into a separate service, which you can then call from both controllers instead.
Example:
class HomeController extends Controller
{
/**
* @var NewsService
*/
private $newsService;
/**
* @var ArticleService
*/
private $articleService;
public function __construct(NewsService $newsService, ArticleService $articleService)
{
$this->newsService = $newsService;
$this->articleService = $articleService;
}
public function index()
{
$news = $this->newsService->getNews();
$articles = $this->articleService->getArticles();
return view('template',['news'=>$news,'articles'=>$articles]);
}
}
class NewsController extends Controller
{
/**
* @var NewsService
*/
private $newsService;
public function __construct(NewsService $newsService)
{
$this->newsService = $newsService;
}
public function index()
{
$news = $this->newsService->getNews();
return view('template',['news'=>$news]);
}
}
class ArticleController extends Controller
{
/**
* @var ArticleService
*/
private $articleService;
public function __construct(ArticleService $articleService)
{
$this->articleService = $articleService;
}
public function index()
{
$articles = $this->articleService->getArticles();
return view('template',['articles'=>$articles]);
}
}
We can't use controller to another controller it is clear.
I think it is better to define a function inside the model to return the value. And call that function in the controller.
This will be more relevant according to MVC.
Instantiate the functions that you want to re-use in the correspondent model so you can use them in all controllers.