CodeIgniter: использовать как базовые классы, так и расширенные классы?
В настоящее время я работаю над CI для моего сайта, и у меня возникли некоторые проблемы с расширением Controller_CI. У меня есть один контроллер, который имеет дело с действиями входа / входа, который не требует аутентификации, и другие контроллеры, которые проверяют, существует ли пользовательский сеанс перед загрузкой контента.
Для этого я создал класс MY_Controller и добавил код аутентификации в конструктор. Затем я заставил весь свой контроллер расширять MY_Controller, кроме первого, который все еще расширяет Controller_CI
Мой вопрос: это правильный путь для аутентификации? Можно ли по-прежнему использовать Controller_CI, даже если он расширен?
Я нашел другой образец:
http://philsturgeon.co.uk/blog/2010/02/CodeIgniter-Base-Classes-Keeping-it-DRY
Я думаю, что это лучше, но, тем не менее, я не понимаю, почему не использовать первое решение.
Спасибо
4 ответа
Расширение класса контроллера для этой цели будет работать, но это решение не очень гибкое. Я предпочел бы создать библиотеку, которая обрабатывает аутентификацию, и запускать ее из контроллера, когда это необходимо. Пожалуйста, прочитайте http://ellislab.com/codeigniter/user-guide/general/creating_libraries.html для получения подробной информации о создании пользовательских библиотек в CI.
Пожалуйста, помните, что вы можете расширить CI_Controller только с MY_Controller только один раз. В этом аспекте это не очень хорошая идея. Предположим, что вы хотите реализовать другую функцию (например, фрагмент кода, который делает конкретную запись в журнале) для некоторых контроллеров, но не обязательно для контроллеров, которые нуждаются в аутентификации, вы не можете сделать другой MY_Controller.
Использование библиотеки - лучшая вещь.
Я использую библиотеку flexi auth на большом CI-сайте. На каждом контроллере, который требует аутентификации, я просто добавляю следующее:
public function __construct() {
parent::__construct();
$this->load->library('flexi_auth');
if (!$this->flexi_auth->is_logged_in())
redirect('auth/login');
}
Я думаю, что комбинация того, что Фил Стерджон предлагает в этом сообщении в блоге и использование библиотеки, была бы лучшей. Так что я бы создал основной контроллер (под этим я подразумеваю контроллер, application/core
это расширяет CI_Controller
) называется MY_Controller, который будет выглядеть примерно так
class MY_Controller extends CI_Controller
{
function __construct()
{
parent::__construct();
}
//Any other functions you want
}
Тогда, судя по вашему вопросу, у вас есть контроллеры, которые подразделяются на две категории.
- Контроллеры, которым требуется войти в систему, прежде чем они что-либо делают
- Контроллеры, которым не требуется авторизованный пользователь, прежде чем что-либо делать
Поэтому я бы затем создал еще один контроллер в каталоге /application/core, который расширяет MY_Controller, но в своем конструкторе он проверяет, вошел ли пользователь в систему.
class Auth_Controller extends My_Controller
{
function __construct()
{
parent::__construct();
//Check to see if the user is logged in
$this->load->library('authentication');
if(!$this->authentication->user_logged_in())
{
redirect('/login');
}
}
//Any other functions you want
}
Теперь, когда вы создаете свой контроллер, вы можете выбрать, какой из основных контроллеров вы хотите расширить. Если это контроллер, который не требует входа в систему, вы можете расширить MY_Controller, но если он требует входа в систему, вы можете расширить Auth_Controller. Таким образом, это означает, что вам нужно всего лишь один раз выполнить проверку входа пользователя в ваш код.
Как уже говорили другие, возможно, будет хорошей идеей поместить любой код аутентификации в библиотеку, так как это лучшее место для размещения, чем в контроллере.
Резюме
Итак, подведем итог: все ваши контроллеры расширяют базовые контроллеры, а не CI_Controller, это должно сократить повторение кода.
Я также в настоящее время работаю над проектом CI и имею ту же самую проблему. Я придумал другое решение для аутентификации.
Я расширил основной контроллер, как показано ниже,
класс MY_Controller extends CI_Controller { public $data = array(); public $ saidClass; public $ namedMethod;
public function __construct()
{
parent::__construct();
$authException['authentication']['login'] = true;
$authException['authentication']['logout'] = true;
$authException['welcome']['index'] = true;
$this->load->library("router");
$this->calledClass = $this->router->fetch_class();
$this->calledMethod = $this->router->fetch_method();
if(!@$authentication[$this->calledClass][$authentication->calledMethod] && !Auth::isUserLoggedIn())
{
# IS_AJAX is a contant defined in the contants.php
# define('IS_AJAX', isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest');
if(IS_AJAX)
{
# if this is an AJAX call, it sets a value in the header ,
# which can be captured in the AJAX response
# to redirect the user to the login page.
$this->output->set_header("auth-him:1");
exit;
}
else
{
redirect("authentication/login");
}
}
}
}
Надеюсь, что приведенный выше код понятен, и это помогает.
Чтобы расширить основной контроллер более одного раза, если вам все еще нужно использовать 2 контроллера для обработки аутентификации, я воспользовался этим методом
Надеюсь, это также помогает:)