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 контроллера для обработки аутентификации, я воспользовался этим методом

/questions/36159739/sozdanie-bazovogo-klassa-rasshiryayuschego-kodignitor-drugogo-bazovogo-klassa/36159768#36159768

Надеюсь, это также помогает:)

Другие вопросы по тегам