То, что я делал ранее, было вводить только МОИ МОДЕЛИ, используя конструктор а также использовать Фасады для предоставленных классов Laravel то есть Session
, Auth
, Validator
и т. д., например. Это будет хорошая идея, если я ввожу каждый класс (или мой или Laravel’s) через конструирование и использовать его $this->..
синтаксис или я должен вводить свои собственные классы с помощью конструктора и использовать Фасады для чего-либо, предоставленного Laravel?
Чтобы быть более конкретным, вот как обычно выглядят мои контроллеры:
class MyController extends BaseController
{
public function __construct( User $user, Bookmark $bookmark ) {
$this->user = $user;
$this->bookmark = $bookmark
}
public function foobar ( ) {
$user_id = Input::get('bar');
...
Session::get('someInfo');
...
return Redirect::to('/');
}
...
}
Должен ли я структурировать свои методы, такие как контроллер, как следует, вместо этого?
class MyController extends BaseController
{
public function __construct( User $user, Bookmark $bookmark, Input $input, Session $session, Redirect $redirect ) {
$this->user = $user;
$this->bookmark = $bookmark
$this->input = $input;
$this->session = $session;
$this->redirect = $redirect;
}
public function foobar ( ) {
$user_id = $this->input->get('bar');
...
$this->session->get('someInfo');
...
return $this->redirect->to('/');
}
...
}
Laravel теперь поддерживает те же функциональные возможности внедрения для методов классов (не только конструкторов), которые связаны с маршрутом, таких как контроллеры и промежуточное программное обеспечение.
Вы можете предотвратить ненужные внедрения, внедрив только те методы, в которых зависимость является уникальной, возможно, оставив более общие зависимости в конструкторе:
class MyController extends BaseController
{
public function __construct( Input $input, Session $session, Redirect $redirect ) {
$this->input = $input;
$this->session = $session;
$this->redirect = $redirect;
}
public function foobar ( User $user, Bookmark $bookmark ) {
$user_id = $this->input->get('bar');
...
$this->session->get('someInfo');
...
return $this->redirect->to('/');
}
...
}
Что касается того, следует ли вам делать это таким образом, то вам решать — заставить все зависимости появляться в определениях методов мне кажется чище и проще для модульного тестирования.
Изящно и полезно вводить определенные классы, такие как Запрос. По моему мнению, они должны быть указаны в методах контроллера там, где они необходимы, поскольку они затем логически связаны с реализацией метода. Круто пока.
Я нахожу два фасада проблематичными — App и Log. Ни логически не связаны с контроллером или его действиями. App и Log не являются входными данными ни в каком контексте. Так как App и Log являются служебными классами, они также имеют отношение к сервисам и репозиториям, и становится совсем неприятно, если вы напишите их в контроллерах, а затем передадите их в качестве параметров конструктора или метода в ваши классы поддержки.
Дополнительной проблемой является то, что фасад приложения не реализует интерфейс Illuminate \ Contracts \ Auth \ Guard, который он проксирует, поэтому моя IDE загорается с предупреждениями, поскольку статический анализ невозможен.
Поэтому для согласованности и общего разделения интересов я бы, таким образом, создавал экземпляры App и Log в конструкторе или методе, в зависимости от того, насколько широко они используются в классе. Чтобы сделать мою среду IDE счастливой, я создал следующий класс, чтобы дать мне правильно типизированный экземпляр везде, где он мне нужен:
<?php namespace App\Components;
use Illuminate\Contracts\Auth\Guard;
use Psr\Log\LoggerInterface;
/**
* Get the underlying object instances of facades from the container.
*/
class AppGlobal
{
/**
* Returns the global logger instance.
*
* @return LoggerInterface
*/
public static function log()
{
return app('log');
}
/**
* Returns the global auth instance, which internally proxies a guard.
*
* @return Guard
*/
public static function auth()
{
return app('auth');
}
}
Если вам нужны свойства объекта — вставьте его как инъекцию (например, Input, Session …), в противном случае, если вы не сохраняете какие-либо данные в объекте и довольно довольны использованием класса, чем идти с фасадами (например, Log :: …, Redirect :: …).
Laravel заменил многие его фасады, например, помощниками
use Auth;
а также
Auth::user()
сейчас просто
auth()->user()
это делает вещь проще и аккуратнее (также предотвращает ошибки)
Я бы посоветовал использовать помощников, где это возможно, и, если помощников не существует, используйте фасад, потому что имитировать легче, чем внедренный экземпляр.