В 2012 году я даже не догадывался о слово сочетании ООП, но четко понимал, написание сайтов и в недалеком будущем web-приложений, потребует уже заранее подготовленных решений, так как количество задач росло, а времени на их реализацию было недостаточно. Выбор мой пал на CodeIgniter ведь его документация меня пожалела, откинув сложные для не окрепшего новичка слова. Признаться, я до сих пор не встречал настолько же удобную и понятную документацию. С тех пор прошло сравнительно немного времени. Но я решил поделиться не многочисленными накопленными знаниями с пользователями Хабра.
На данный момент я использую CodeIgniter v2.2.0.
Роутинг:
Люди которые пользуются данным фреймворком абсолютно точно знают как работает роутинг в CI. Однако я часто задавался вопросом, а как же все таки перенаправить все запросы на один единственный контроллер.
Все просто следует добавить в конец файла /aplication/config/routes.php следующую строку:
После чего мы получим:
В таком случае все запросы, будь то http//mysite/user или http//mysite.loc/page , будут всецело перенаправлены на http//my_site/main/user и http//mysite.loc/main/page соответственно.
Отлично! Но что если нам нужно оставить перенаправления на другие контроллеры, например: user, page, admin. В этом случае я использую такую схему:
Теперь у нас есть основной контроллер и дополнительные, к которым мы так же спокойно можем обращаться. Но что если у меня есть всего лишь один контроллер отвечающий за вывод CSS, JavaScript и картинок.
Так выглядит мой конечный файл 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():
В этом случае расширяя стандартный класс 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 с помощью которого я расширю функционал библиотеки, а так же смогу добавлять новые функции для проверки входных данных.
Таким образом, мы получаем функцию $this->form_validation->error_array() которая и вернет нам массив ошибок. Например:
Спасибо за внимание! Надеюсь, был полезен.
На данный момент я использую CodeIgniter v2.2.0.
Роутинг:
Люди которые пользуются данным фреймворком абсолютно точно знают как работает роутинг в 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)
kovalevsky
06.10.2015 09:22+1Свежая статья о мертвом фреймворке. Сам на нём писал когда-то, ненавижу его, но больше ненавижу Ваши foreach и любую другую логику в конфигурационных файлах.
Radik_Wind
Одному мне кажется, что в последние время из песочницы вытаскивают только всякий шлак? Данный пост лучше убрать в черновики и ни когда, и ни кому не показывать. Автору поста посоветовал бы взглянуть на, что то другое, не такое безвозвратно устаревшее как CI к примеру Sf2, Lavarel, Yii и т.п. про CI лучше забыть как про страшный сон.
ragimovich
Вас минусуют, а ведь вы правы на 100%.
Преимуществ у него сейчас перед тем же Laravel нет никаких. Если вам нужно что-то легкое, есть куча микрофреймворков в которых не надо думать о том, как «вывести 404 ошибку» и извратиться в роутингах. Есть Yii в конце концов, если вам нужен баланс. Документацией сейчас кого-то сложно удивить.
CI сейчас можно рассматривать только в контексте супер древних сайтов, но, простите, если предыдущие несколько лет подобные сайты работали без вывода ошибки 404, может он им и не нужен?
d_shorkin
Я думаю что этот комментарий можно трактовать так: «CI сильно устарел и его не стоит применять на практике.»
И пожалуй я отчасти соглашусь. По крайне мере если ты начинающий разработчик то стоит начинать учить что то более востребованное. Сам потихоньку перехожу на Yii2. Но что делать с уже готовыми проектами? За поддержку тоже платят.
Fesor
давайте так, людям которые сейчас сидят на суппорте проектов на CI эти советы не особо помогут жить.