В 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"    => "Этот адрес уже зарегистрирован"
);

Спасибо за внимание! Надеюсь, был полезен.

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


  1. Radik_Wind
    05.10.2015 14:17
    +7

    Одному мне кажется, что в последние время из песочницы вытаскивают только всякий шлак? Данный пост лучше убрать в черновики и ни когда, и ни кому не показывать. Автору поста посоветовал бы взглянуть на, что то другое, не такое безвозвратно устаревшее как CI к примеру Sf2, Lavarel, Yii и т.п. про CI лучше забыть как про страшный сон.


    1. ragimovich
      05.10.2015 15:15
      +1

      Вас минусуют, а ведь вы правы на 100%.

      Преимуществ у него сейчас перед тем же Laravel нет никаких. Если вам нужно что-то легкое, есть куча микрофреймворков в которых не надо думать о том, как «вывести 404 ошибку» и извратиться в роутингах. Есть Yii в конце концов, если вам нужен баланс. Документацией сейчас кого-то сложно удивить.

      CI сейчас можно рассматривать только в контексте супер древних сайтов, но, простите, если предыдущие несколько лет подобные сайты работали без вывода ошибки 404, может он им и не нужен?


    1. d_shorkin
      05.10.2015 15:16

      Я думаю что этот комментарий можно трактовать так: «CI сильно устарел и его не стоит применять на практике.»

      И пожалуй я отчасти соглашусь. По крайне мере если ты начинающий разработчик то стоит начинать учить что то более востребованное. Сам потихоньку перехожу на Yii2. Но что делать с уже готовыми проектами? За поддержку тоже платят.


      1. Fesor
        05.10.2015 20:10
        +1

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


  1. kovalevsky
    06.10.2015 09:22
    +1

    Свежая статья о мертвом фреймворке. Сам на нём писал когда-то, ненавижу его, но больше ненавижу Ваши foreach и любую другую логику в конфигурационных файлах.


  1. adombrovsky
    06.10.2015 21:50

    Это фреймворк все еще жив?


    1. Fesor
      06.10.2015 23:12

      Жив, но жизнь назвать это тяжело…


  1. IbrahimKZ
    07.10.2015 08:01
    +1

    Вы опоздали примерно на 4-5 лет с этой статьей