Контроллеры
Контроллеры — это сердце вашего приложения, поскольку они определяют, как должны обрабатываться запросы HTTP.
- Что такое контроллер?
- Попробуем: Hello World!
- Методы
- Передача сегментов URI в ваши методы
- Определение контроллера по умолчанию
- Перенаправление вызовов методов
- Приватные методы
- Организация контроллеров в подкаталоги
- Включенные свойства
- Валидация данных
- Итого!
Что такое контроллер?
Контроллер — это просто файл класса, который назван таким образом, что его можно связать с URI.
Рассмотрим такой URI:
example.com/index.php/helloworld/
В приведенном выше примере CodeIgniter попытается найти контроллер под названием Helloworld.php и загрузить его.
Когда имя контроллера соответствует первому сегменту URI, он будет загружен.
Попробуем: Hello World!
Давайте создадим простой контроллер, чтобы вы могли увидеть его в действии. Используя ваш текстовый редактор, создайте файл Helloworld.php и поместите в него следующий код. Вы заметите, что контроллер Helloworld расширяет BaseController. Вы также можете расширить CodeIgniter\Controller, если вам не нужны функции BaseController.
BaseController предоставляет удобное место для загрузки компонентов и выполнения функций, необходимых для всех ваших контроллеров. Вы можете расширить этот класс в любом новом контроллере.
По соображениям безопасности убедитесь, что вы объявляете любые новые утилитарные методы как защищенные или приватные:
<?php
namespace App\Controllers;
class Helloworld extends BaseController
{
public function index()
{
echo 'Hello World!';
}
}
Затем сохраните файл в директорию /app/Controllers/.
Важно
Файл должен называться ‘Helloworld.php’, с заглавной буквой ‘H’.
Теперь посетите ваш сайт, используя URL, подобный этому:
example.com/index.php/helloworld
Если вы все сделали правильно, вы увидите:
Hello World!
Важно
Имена классов контроллеров ДОЛЖНЫ начинаться с заглавной буквы, и ТОЛЬКО первый символ может быть заглавным.
Это допустимо:
<?php
namespace App\Controllers;
class Helloworld extends BaseController
{
}
Это не допустимо:
<?php
namespace App\Controllers;
class helloworld extends BaseController
{
}
Это не допустимо:
<?php
namespace App\Controllers;
class HelloWorld extends BaseController
{
}
Кроме того, всегда убедитесь, что ваш контроллер расширяет родительский класс контроллера, чтобы он мог унаследовать все его методы.
Примечание
Система попытается сопоставить URI с контроллерами, сопоставляя каждый сегмент с папками/файлами в APPPATH/Controllers, когда соответствие не было найдено по определенным маршрутам. Вот почему ваши папки/файлы ДОЛЖНЫ начинаться с заглавной буквы, а остальные ДОЛЖНЫ быть строчными. Если вам нужна другая система именования, вам нужно вручную определить ее, используя функцию маршрутизации URI.
Вот пример, основанный на PSR-4: автозагрузчике:
\<NamespaceName>(\<SubNamespaceNames>)*\<ClassName>
$routes->get('helloworld', 'App\Controllers\HelloWorld::index');
Методы
В приведенном выше примере имя метода index(). Метод «index» всегда загружается по умолчанию, если второй сегмент URI пуст. Другой способ показать ваше сообщение «Hello World» — это:
example.com/index.php/helloworld/index/
Второй сегмент URI определяет, какой метод в контроллере вызывается.
Давайте попробуем. Добавьте новый метод в свой контроллер:
<?php
namespace App\Controllers;
class Helloworld extends BaseController
{
public function index()
{
echo 'Hello World!';
}
public function comment()
{
echo 'I am not flat!';
}
}
Теперь загрузите следующий URL, чтобы увидеть метод комментария:
example.com/index.php/helloworld/comment/
Вы должны увидеть ваше новое сообщение.
Передача сегментов URI в ваши методы
Если ваш URI содержит более двух сегментов, они будут переданы вашему методу в качестве параметров.
Например, предположим, что у вас есть URI, подобный этому:
example.com/index.php/products/shoes/sandals/123
Ваш метод получит сегменты URI 3 и 4 («sandals» и «123»):
<?php
namespace App\Controllers;
class Products extends BaseController
{
public function shoes($sandals, $id)
{
echo $sandals;
echo $id;
}
}
Важно
Если вы используете функцию маршрутизации URI, сегменты, передаваемые вашему методу, будут перенаправленными.
Определение контроллера по умолчанию
CodeIgniter можно настроить на загрузку контроллера по умолчанию, когда URI отсутствует, как это произойдет, когда будет запрошен только URL вашего сайта. Попробуем с контроллером Helloworld.
Чтобы указать контроллер по умолчанию, откройте файл app/Config/Routes.php и установите эту переменную:
$routes->setDefaultController('Helloworld');
Где ‘Helloworld’ — имя класса контроллера, который вы хотите использовать.
Несколько строк ниже в Routes.php в разделе «Определения маршрутов» закомментируйте строку:
$routes->get('/', 'Home::index');
Если вы теперь перейдете на свой сайт без указания сегментов URI, вы увидите сообщение «Hello World».
Примечание
Строка $routes->get('/', 'Home::index'); — это оптимизация, которую вы захотите использовать в приложении «реального мира». Но для демонстрационных целей мы не хотим использовать эту функцию. $routes->get() описана в маршрутизации URI
Для получения дополнительной информации см. раздел «Параметры конфигурации маршрутов» в документации по маршрутизации URI.
Перенаправление вызовов методов
Как отмечалось выше, второй сегмент URI обычно определяет, какой метод в контроллере вызывается. CodeIgniter позволяет вам изменить это поведение с помощью метода _remap().
public function _remap()
{
// Some code here...
}
Важно
Если ваш контроллер содержит метод _remap(), он ВСЕГДА будет вызываться независимо от того, что содержит ваш URI. Он переопределяет стандартное поведение, в котором URI определяет, какой метод вызывается, позволяя вам определить свои собственные правила маршрутизации методов.
Вызванный метод (обычно второй сегмент URI) будет передан в качестве параметра методу _remap():
public function _remap($method)
{
if ($method === 'some_method') {
return $this->$method();
} else {
return $this->default_method();
}
}
Любые дополнительные сегменты после имени метода передаются в _remap() . Эти параметры можно передать методу для эмуляции стандартного поведения CodeIgniter.
Пример:
public function _remap($method, ...$params)
{
$method = 'process_'.$method;
if (method_exists($this, $method)) {
return $this->$method(...$params);
}
throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
}
Приватные методы
В некоторых случаях вам может потребоваться скрыть определенные методы от общего доступа. Для этого просто объявите метод как приватный или защищенный. Это предотвратит его обработку запросом URL. Например, если вы определите метод для контроллера Helloworld:
protected function utility()
{
// some code
}
то попытка доступа к нему с помощью следующего URL не сработает:
example.com/index.php/helloworld/utility/
Организация контроллеров в подкаталоги
Если вы разрабатываете крупное приложение, вам может потребоваться иерархически организовать или структурировать ваши контроллеры в подкаталоги. CodeIgniter позволяет это сделать.
Просто создайте подкаталоги в основном каталоге app/Controllers/ и поместите в них классы контроллеров.
Важно
Имена папок ДОЛЖНЫ начинаться с заглавной буквы, и ТОЛЬКО первый символ может быть заглавным.
Примечание
При использовании этой функции первый сегмент вашего URI должен указать папку. Например, предположим, что у вас есть контроллер, расположенный здесь:
app/Controllers/Products/Shoes.php
Для вызова указанного контроллера ваш URI будет выглядеть примерно так:
example.com/index.php/products/shoes/show/123
Каждый из ваших подкаталогов может содержать контроллер по умолчанию, который будет вызываться, если URL содержит ТОЛЬКО подкаталог. Просто поместите в него контроллер, соответствующий имени вашего ‘default_controller’, указанного в файле app/Config/Routes.php.
CodeIgniter также позволяет вам перенаправлять свои URI с помощью функции маршрутизации URI.
Включенные свойства
Каждый создаваемый вами контроллер должен расширять класс CodeIgniter\Controller. Этот класс предоставляет несколько функций, доступных для всех ваших контроллеров.
Объект запроса
Основной объект запроса приложения всегда доступен как свойство класса, $this->request.
Объект ответа
Основной объект ответа приложения всегда доступен как свойство класса, $this->response.
Объект логгера
Экземпляр класса логгера доступен как свойство класса, $this->logger.
forceHTTPS
Внутри всех контроллеров доступен удобный метод для принудительного доступа к методу через HTTPS:
if (! $this->request->isSecure()) {
$this->forceHTTPS();
}
По умолчанию, и в современных браузерах, поддерживающих заголовок HTTP Strict Transport Security, этот вызов должен заставить браузер преобразовать не-HTTPS вызовы в HTTPS вызовы на один год. Вы можете изменить это, передав продолжительность (в секундах) в качестве первого параметра:
if (! $this->request->isSecure()) {
$this->forceHTTPS(31536000); // one year
}
Примечание
Некоторые постоянные значения, основанные на времени всегда доступны для вашего использования, включая YEAR, MONTH и многое другое.
Вспомогательные функции
Вы можете определить массив файлов вспомогательных функций как свойство класса. При загрузке контроллера эти файлы вспомогательных функций будут автоматически загружаться в память, так что вы можете использовать их методы в любом месте внутри контроллера:
namespace App\Controllers;
class MyController extends BaseController
{
protected $helpers = ['url', 'form'];
}
Валидация данных
Для упрощения проверки данных контроллер также предоставляет удобный метод validate(). Метод принимает массив правил в первом параметре и, по желанию, во втором параметре массив пользовательских сообщений об ошибках для отображения, если элементы не валидны. Внутренне он использует экземпляр $this->request контроллера для получения данных, подлежащих валидации. Подробную информацию о формате массивов правил и сообщений, а также о доступных правилах, можно найти в документации библиотеки валидации:
public function updateUser(int $userID)
{
if (! $this->validate([
'email' => "required|is_unique[users.email,id,{$userID}]",
'name' => 'required|alpha_numeric_spaces'
])) {
return view('users/update', [
'errors' => $this->validator->getErrors()
]);
}
// do something here if successful...
}
Если вам проще хранить правила в файле конфигурации, вы можете заменить массив $rules именем группы, как определено в Config\Validation.php:
public function updateUser(int $userID)
{
if (! $this->validate('userRules')) {
return view('users/update', [
'errors' => $this->validator->getErrors()
]);
}
// do something here if successful...
}
Примечание
Валидацию также можно обрабатывать автоматически в модели, но иногда проще сделать это в контроллере. Решение за вами.
Вот и всё!
Это, вкратце, всё, что нужно знать о контроллерах.
© 2014–2020 British Columbia Institute of Technology
Licensed under the MIT License.
https://codeigniter.com/user_guide/incoming/controllers.html