Pull to refresh

Пара полезностей для CodeIgniter

Reading time 4 min
Views 18K
В 2012 году я даже не догадывался о слово сочетании ООП, но четко понимал, написание сайтов и в недалеком будущем web-приложений, потребует уже заранее подготовленных решений, так как количество задач росло, а времени на их реализацию было недостаточно. Выбор мой пал на CodeIgniter ведь его документация меня пожалела, откинув сложные для не окрепшего новичка слова. Признаться, я до сих пор не встречал настолько же удобную и понятную документацию. С тех пор прошло сравнительно немного времени. Но я решил поделиться не многочисленными накопленными знаниями с пользователями Хабра.

На данный момент я использую CodeIgniter v2.2.0.

image

Роутинг:

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

Все просто следует добавить в конец файла /aplication/config/routes.php следующую строку:

$route['(:any)'] = $route['default_controller']."/$1";

После чего мы получим:

$route['default_controller'] = "main";
$route['404_override'] = '';
$route['(:any)'] = $route['default_controller']."/$1";

В таком случае все запросы, будь то http//mysite/user или http//mysite.loc/page , будут всецело перенаправлены на http//my_site/main/user и http//mysite.loc/main/page соответственно.

Отлично! Но что если нам нужно оставить перенаправления на другие контроллеры, например: user, page, admin. В этом случае я использую такую схему:

<?php
// Открытые для доступа контроллеры.
$controllers = array(
    "user",
    "admin",
    "page"
);

foreach($controllers as $controller){
    $route[$controller] = $controller;
    $route[$controller.'/(:any)'] = $controller.'/$1';
}

$route['default_controller'] = "main";
$route['404_override'] = '';
$route['(:any)'] = $route['default_controller']."/$1";

Теперь у нас есть основной контроллер и дополнительные, к которым мы так же спокойно можем обращаться. Но что если у меня есть всего лишь один контроллер отвечающий за вывод CSS, JavaScript и картинок.

<?php
// Содержание системного контроллера
$systems_redirect = array(
    'css',
    'js',
    'image'
);

$route['('.implode('|',$systems_redirect).')'] = 'systems/$1';
$route['('.implode('|',$systems_redirect).')/(:any)'] = 'systems/$1/$2';

// Открытые для доступа контроллеры.
$controllers = array(
    "user",
    "admin",
    "page"
);

foreach($controllers as $controller){
    $route[$controller] = $controller;
    $route[$controller.'/(:any)'] = $controller.'/$1';
}

$route['default_controller'] = "main";
$route['404_override'] = '';
$route['(:any)'] = $route['default_controller']."/$1";

Так выглядит мой конечный файл routes.php.

Вывод ошибки 404:

Некоторое время назад я задался вопросом. Как перенаправить 404 ошибку на контроллер для того что бы и там вывести некоторые данные, ведь как мы знаем CodeIgniter выводит только небольшую заранее заготовленную html страничку без возможности загрузить в нее какую то информацию с базы данных. Или поработать с библиотеками.

Казалось бы, решение до боли простое. В ранее упомянутом файле routes.php изменить значение переменной $route['404_override'] = ''; на имя заранее приготовленного контроллера, например my404.php. Но пользуясь такой реализацией я вдруг наткнулся на одну очень неприятную вещь.

Дело в том что если вам потребуется из постороннего контроллера вызвать функцию show_404() вы получите старую заранее приготовленную html страничку /aplication/errors/error_404.php которая вряд ли вас обрадует.

Наилучшим решением этой проблемы я посчитал расширить стандартный класс CI_Exceptions с помощью автоматически подгружаемого файла /aplication/core/MY_Exceptions.php заменит стандартную функцию show_404():

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class MY_Exceptions extends CI_Exceptions {

    public function show_404()
    {
        $CI =& get_instance();
        $CI->output->set_status_header('404');
        $CI->output->set_output("error_404");
    }
}

В этом случае расширяя стандартный класс CI_Exceptions, мы получаем доступ к функции get_instance(); которая в свою очередь дает нам возможность полноценно использовать все классы модели хэлперы и т.д.

Получение ошибок из библиотеки CI_Form_validation:

Представим, что мы передаем форму с помощью ajax и ждем возврат в формате json. При этом проверяя данные с помощью CI_Form_validation. И вроде все хорошо библиотека работает исправно но вернуть ошибки в массив для преобразования в json не представляется возможным так как единственная функция для возврата ошибок $this->form_validation->error_string() возвращает строку со всеми ошибками из которой в последствии уже не получить ошибки для каждого переданного значения. Конечно есть еще функция $this->form_validation->error() но для ее использования нужен будет совершенно не нужный цикл. И вот решение. Создать файл /aplication/libraries/MY_Form_validation.php с помощью которого я расширю функционал библиотеки, а так же смогу добавлять новые функции для проверки входных данных.

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class MY_Form_validation extends CI_Form_validation
{
    function __construct($config = array())
    {
        parent::__construct($config);
    }

    function error_array()
    {
        if (count($this->_error_array) === 0)
            return FALSE;
        else
            return $this->_error_array;
    }
}

Таким образом, мы получаем функцию $this->form_validation->error_array() которая и вернет нам массив ошибок. Например:

$errors = array(
    "username" => "Имя пользователя слишком короткое",
    "email"    => "Этот адрес уже зарегистрирован"
);

Спасибо за внимание! Надеюсь, был полезен.
Tags:
Hubs:
-1
Comments 8
Comments Comments 8

Articles