Может войдёшь?
Черновики Написать статью Профиль

Контроллеры

перевод документация 5.х

  1. 1. Введение
  2. 2. Простейшие контроллеры
  3. 3. Посредник контроллера
  4. 4. RESTful-контроллеры ресурсов
  5. 5. Неявные контроллеры
  6. 6. Внедрение зависимостей и контроллеры
  7. 7. Кэширование маршрутов
Этот перевод актуален для англоязычной документации на (ветка 5.1) и (ветка 5.0). Опечатка? Выдели и нажми Ctrl+Enter.

Введение

Вместо того, чтобы определять всю логику обработки запросов в одном файле routes.php, вы можете организовать её с помощью классов контроллеров. Контроллеры могут группировать связанную с обработкой HTTP-запросов логику в отдельный класс. Контроллеры хранятся в папке app/Http/Controllers.

Простейшие контроллеры

Вот пример простейшего класса контроллера. Все контроллеры в Laravel должны наследовать базовый класс контроллера, встроенный в создаваемое приложение Laravel:

PHP
<?php

namespace App\Http\Controllers;

use 
App\User;
use 
App\Http\Controllers\Controller;

class 
UserController extends Controller
{
  
/**
   * Показать профиль данного пользователя.
   *
   * @param  int  $id
   * @return Response
   */
  
public function showProfile($id)
  {
    return 
view('user.profile', ['user' => User::findOrFail($id)]);
  }
}

Мы можем зарегистрировать маршрут для его действия (action) вот так:

PHP
Route::get('user/{id}''UserController@showProfile');

Теперь при соответствии запроса указанному URI маршрута будет выполняться метод PHPshowProfile() класса UserController. Само собой параметры маршрута также будут переданы в метод.

Контроллеры и пространства имён

Важно помнить, что при определении маршрута контроллера нам не надо указывать полное пространство имён контроллера, а только ту часть имени класса, которая следует за «корнем» пространства имён — App\Http\Controllers. По умолчанию RouteServiceProvider загрузит файл routes.php вместе с группой маршрутизации, содержащей корневое пространство имён контроллера.

Если вы решите разместить свои контроллеры, используя пространства имён PHP, в поддиректориях App\Http\Controllers, то просто используйте конкретное имя класса относительно корня пространства имён App\Http\Controllers. Тогда, если полный путь к вашему классу будет App\Http\Controllers\Photos\AdminController, то вы зарегистрируете маршрут вот так:

PHP
Route::get('foo''Photos\AdminController@method');

Имена маршрутов контроллеров

Подобно маршрутам замыканий, вы можете указать имена для маршрутов контроллеров:

PHP
Route::get('foo', ['uses' => 'FooController@method''as' => 'name']);

URL-адреса для действий контроллера

Также вы можете использовать вспомогательную функцию PHProute(), чтобы сгенерировать URL маршрута названного контроллера:

PHP
$url route('name');

Также вы можете использовать вспомогательный метод PHPaction(), чтобы сгенерировать URL, используя имена классов и методов контроллера. И снова, нам надо указать только ту часть имени контроллера, которая идёт после базового пространства имён App\Http\Controllers:

PHP
$url action('FooController@method');
+ 5.0

добавлено в 5.0 ()

Для получения URL для действия контроллера используйте метод PHPaction():

PHP
$url action('App\Http\Controllers\FooController@method');

Если вы хотите получить URL для действия контроллера, используя только часть имени класса относительно пространства имён контроллера, зарегистрируйте корневое пространство имён контроллера с помощью генератора URL:

PHP
URL::setRootControllerNamespace('App\Http\Controllers');

$url action('FooController@method');

Получить имя действия, которое выполняется в данном запросе, можно методом PHPcurrentRouteAction() фасада Route:

PHP
$action Route::currentRouteAction();

Посредник контроллера

Посредник может быть указан для маршрутов контроллера вот так:

PHP
Route::get('profile', [
  
'middleware' => 'auth',
  
'uses' => 'UserController@showProfile'
]);

Но удобнее указать посредника в конструкторе вашего контроллера. Используя метод PHPmiddleware() в конструкторе контроллера, вы легко можете назначить посредника для контроллера. Вы можете даже ограничить использование посредника, назначив его только для определённых методов класса контроллера:

PHP
class UserController extends Controller
{
  
/**
   * Создание нового экземпляра UserController.
   */
  
public function __construct()
  {
    
$this->middleware('auth');

    
$this->middleware('log', ['only' => ['fooAction''barAction']]);

    
$this->middleware('subscribed', ['except' => ['fooAction''barAction']]);
  }
}

RESTful-контроллеры ресурсов

Контроллеры ресурсов упрощают построение RESTful-контроллеров, работающих с ресурсами. Например, вы можете создать контроллер, обрабатывающий HTTP-запросы, связанные с фотографиями, хранимые вашим приложением. Вы можете быстро создать такой контроллер с помощью Artisan-команды shmake:controller:

shphp artisan make:controller PhotoController

Эта команда сгенерирует файл контроллера app/Http/Controllers/PhotoController.php. Контроллер будет содержать метод для каждой доступной операции с ресурсами.

Теперь мы можем зарегистрировать маршрут контроллера ресурса:

PHP
Route::resource('photo''PhotoController');

Этот единственный вызов создаёт множество маршрутов для обработки различных RESTful-действий для ресурса photo. Сам сгенерированный контроллер уже имеет методы-заглушки для каждого из этих действий с комментариями о том, какие URI и типы запросов они обрабатывают.

Действия, обрабатываемые контроллером ресурсов

Тип Путь Действие Имя маршрута
GET /photo index photo.index
GET /photo/create create photo.create
POST /photo store photo.store
GET /photo/{photo} show photo.show
GET /photo/{photo}/edit edit photo.edit
PUT/PATCH /photo/{photo} update photo.update
DELETE /photo/{photo} destroy photo.destroy

Частичные маршруты ресурсов

При объявлении маршрута вы можете указать подмножество всех возможных действий, которые должны обрабатываться по маршруту:

PHP
Route::resource('photo''PhotoController',
            [
'only' => ['index''show']]);

Route::resource('photo''PhotoController',
            [
'except' => ['create''store''update''destroy']]);

Именование маршрутов ресурсов

По умолчанию все действия контроллера ресурсов имеют имена маршрутов, но вы можете переопределить эти имена, передав массив names вместе с остальными параметрами:

PHP
Route::resource('photo''PhotoController',
            [
'names' => ['create' => 'photo.build']]);

Вложенные ресурсы

Иногда необходимо определить маршруты для «вложенных» ресурсов. Например, фото-ресурс может иметь множество «комментариев», которые могут быть прикреплены к фотографии. Используйте «точечную» нотацию в объявлении маршрута для контроллеров «вложенных» ресурсов:

PHP
Route::resource('photos.comments''PhotoCommentController');

Этот маршрут зарегистрирует «вложенный» ресурс, к которому можно обратиться по такому URL: photos/{photos}/comments/{comments}.

PHP
<?php

namespace App\Http\Controllers;

use 
App\Http\Controllers\Controller;

class 
PhotoCommentController extends Controller
{
  
/**
   * Показать определённый комментарий к фото.
   *
   * @param  int  $photoId
   * @param  int  $commentId
   * @return Response
   */
  
public function show($photoId$commentId)
  {
    
//
  
}
}

Добавление дополнительных маршрутов в контроллеры ресурсов

Когда вам необходимо добавить дополнительные маршруты в контроллер ресурсов, не входящие в маршруты ресурсов по умолчанию, их надо определить до вызова PHPRoute::resource, иначе определенные методом PHPresource() маршруты могут нечаянно «победить» ваши дополнительные маршруты:

PHP
Route::get('photos/popular''PhotoController@method');

Route::resource('photos''PhotoController');

Неявные контроллеры

Laravel позволяет вам легко создавать единый маршрут для обработки всех действий в классе контроллера. Для начала зарегистрируйте маршрут методом PHPRoute::controller(). Этот метод принимает два аргумента. Первый — обрабатываемый контроллером базовый URI, а второй — имя класса контроллера:

PHP
Route::controller('users''UserController');

После регистрации просто добавьте методы в контроллер, назвав их по имени URI с большой буквы и с префиксом в виде типа HTTP-запроса (HTTP verb), который они обрабатывают:

PHP
<?php

namespace App\Http\Controllers;

class 
UserController extends Controller
{
  
/**
   * Отклик на запрос GET /users
   */
  
public function getIndex()
  {
    
//
  
}

  
/**
   * Отклик на запрос GET /users/show/1
   */
  
public function getShow($id)
  {
    
//
  
}

  
/**
   * Отклик на запрос GET /users/admin-profile
   */
  
public function getAdminProfile()
  {
    
//
  
}

  
/**
   * Отклик на запрос POST /users/profile
   */
  
public function postProfile()
  {
    
//
  
}
}

Как видите, в этом примере методы index обрабатывают корневой URI контроллера — в нашем случае это users.

+ 5.0

добавлено в 5.0 ()

Если имя действия вашего контроллера состоит из нескольких слов вы можете обратиться к нему по URI, используя синтаксис с дефисами (-). Например, следующее действие в нашем классе UserController будет доступно по адресу users/admin-profile:

PHP
public function getAdminProfile() {}

Назначение имён маршрутов

Если вы хотите назвать некоторые маршруты в контроллере, вы можете передать массив имён в качестве третьего аргумента в метод PHPcontroller():

PHP
Route::controller('users''UserController', [
  
'getShow' => 'user.show',
]);

Внедрение зависимостей и контроллеры

Внедрение в конструктор

Сервис-контейнер в Laravel используется для работы всех контроллеров Laravel. В результате вы можете указывать типы любых зависимостей, которые могут потребоваться вашему контроллеру в его конструкторе. Зависимости будут автоматически получены и внедрены в экземпляр контроллера:

PHP
<?php

namespace App\Http\Controllers;

use 
Illuminate\Routing\Controller;
use 
App\Repositories\UserRepository;

class 
UserController extends Controller
{
  
/**
   * Экземпляр репозитория пользователя.
   */
  
protected $users;

  
/**
   * Создание нового экземпляра контроллера.
   *
   * @param  UserRepository  $users
   * @return void
   */
  
public function __construct(UserRepository $users)
  {
    
$this->users $users;
  }
}

Разумеется, вы можете также указать тип любого контракта Laravel. Если контейнер может с ним работать, значит вы можете указывать его тип.

Внедрение в метод

Кроме внедрения в конструктор, вы также можете указывать типы зависимостей в методах вашего контроллера. Например, давайте укажем тип экземпляра Illuminate\Http\Request в одном из наших методов:

PHP
<?php

namespace App\Http\Controllers;

use 
Illuminate\Http\Request;
use 
Illuminate\Routing\Controller;

class 
UserController extends Controller
{
  
/**
   * Сохранить нового пользователя.
   *
   * @param  Request  $request
   * @return Response
   */
  
public function store(Request $request)
  {
    
$name $request->input('name');

    
//
  
}
}

Если метод вашего контроллера также ожидает данных из параметра маршрута, просто перечислите аргументы маршрута после остальных зависимостей. Например, если ваш маршрут определён так:

PHP
Route::put('user/{id}''UserController@update');

Вы по-прежнему можете указать тип Illuminate\Http\Request и обращаться к id параметра вашего маршрута, определив метод контроллера вот так:

PHP
<?php

namespace App\Http\Controllers;

use 
Illuminate\Http\Request;
use 
Illuminate\Routing\Controller;

class 
UserController extends Controller
{
  
/**
   * Обновить указанного пользователя.
   *
   * @param  Request  $request
   * @param  int  $id
   * @return Response
   */
  
public function update(Request $request$id)
  {
    
//
  
}
}
+ 5.0

добавлено в 5.0 ()

Внедрение в метод полностью совместимо с привязкой к модели. Контейнер автоматически определит, какие из аргументов привязаны к модели, а какие аргументы должны быть внедрены.

Кэширование маршрутов

Кэширование маршрутов не работает с маршрутами на основе замыканий. Чтобы использовать кэширование маршрутов, необходимо перевести все маршруты замыканий на использование классов контроллера.

Если ваше приложение единолично использует маршруты контроллера, то вы можете воспользоваться преимуществом кэширования маршрутов в Laravel. Использование кэша маршрутов радикально уменьшит время, требуемое для регистрации всех маршрутов вашего приложения. В некоторых случаях регистрация ваших маршрутов может стать быстрее в 100 раз! Для создания кэша маршрутов просто выполните Artisan-команду shroute:cache:

shphp artisan route:cache

Вот и всё! Теперь вместо файла app/Http/routes.php будет использоваться кэшированный файл маршрутов. Помните, после добавления новых маршрутов, вам необходимо заново сгенерировать свежий кэш маршрутов. Поэтому можно выполнить команду shroute:cache уже при развёртывании вашего проекта.

Для удаления кэшированного файла маршрутов без создания нового используйте команду shroute:clear:

shphp artisan route:clear

Комментарии (4)

marcuzy

Для генерации контроллера с методами-заглушками к команде php artisan make:controller PhotoController нужно добавить параметр --resource

Ololosha

А как удалить контроллер? artisan --help не помог

zZz

Клавиша DELETE

Zaklinatel

Контроллер — это просто файл, содержащий ваш класс контроллера (наследуемый от абстракции контроллера фреймворка, скорее всего). Чтобы удалить контроллер, надо просто удалить класс (файл). Найти его можно в app/Http/Controllers/

Артисан для этого не нужен. Он просто помогает создавать шаблоны этих классов, чтобы вам меньше было писать кода. Удалить вы можете и сами.

Написать комментарий

Разметка: ? ?

Авторизуйся, чтобы прокомментировать.