Критические замечания к CodeIgniter фреймворку

  • написал: MpaK
  • 296
CodeIgniter bugsЭто не пост гнева, а скорее желание помочь, кто будет наступать на грабли.
Не буду много писать, текст будет интересен тем, кто уже освоил CodeIgniter и знаком со стандартными классами и принципами или только начинает на нём писать и ему предстоит столкнутся с граблями. Всё актуально для версии 1.7.2, хотя как погляжу в 2ке так же не поправили и всё прежнее.

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

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

1. Валидация форм (Form_validation) отправленных только через $_POST
Я конечно понимаю, что это суть фреймворка, что все запросы идут через _POST, но в настройках есть возможность включить например тот же _GET или даже допустим мы шлём форму через _POST но у нас только одно поле —
<input type="file name="file" />


а внутри контроллера или модели есть желание повесить callback_ валидацию на проверку валидности например этого файла, его типа, его данных, допустим это Excel

Но увы, код
$this->form_validation->set_rules('file', 'File', 'callback_file_check');

if( $this->form_validation->run() === FALSE ){
...
}

постоянно будет срабатывать в условии FALSE и валидация никогда не будет вызвана, причина простая, у разработчиков в голове не было такого варианта развития действий.

Заходим в файл класса libraries/Form_validation.php
function run($group = '')
	{
		// Do we even have any data to process?  Mm?
		if (count($_POST) == 0){
			return FALSE;
		}

Ну с этим всё, 3 варианта действия у нас.
1. Расширить CI_Form_validation своим MY_Form_validation переписав эту проверку в методе run()
2. Добавить какую-нибудь беcсмысленную input type=«hidden» переменную с каким-нибудь значением, например для CSFR защиты
3. В лоб, залезть и переписать кусочек кода :)
Проблема простая и видно, что просто не учли всех вариантов использования класса.

Номер 2 проблема.
libraries/Cart — есть такой с 1.7.1 появившийся класс для работы с корзиной интернет магазина, можно класть товары, собирать их, доставать и т.п.

Но проблема, что нельзя положить например несколько раз подряд товар одного и того же вида, например хочу класть в корзину 1 футболку, погулять, потом вернуться и положить еще одну такую же футболку, такого же размера, цвета!

Почему? Да всё просто, опять же не предусмотрели, что не во всех магазинах человек хочет указывать кол-во товара руками и т.п. Он может например просто кнопочкой «положить товар» и через ajax очень много раз класть в корзину, набирая её с горкой например.
Каждый товар имеет уникальный rowid который складывается из хэша параметров товара и если он совпадает с уже имеющимся, просто перетирает старый.

Класс libraries/Cart.php метод _insert()

// генерация ключа
if (isset($items['options']) AND count($items['options']) > 0){
    $rowid = md5($items['id'].implode('', $items['options']));
}else{
    $rowid = md5($items['id']);
}
// стираем старые данные на этом месте и сливаем новые
unset($this->_cart_contents[$rowid]);
// Create a new index with our new row 
$this->_cart_contents[$rowid]['rowid'] = $rowid;

// And add the new items to the cart array
foreach ($items as $key => $val){
   $this->_cart_contents[$rowid][$key] = $val;
}

согласитесь, не очень удобно, в магазинах ложить товар поштучно

Как варианты решения 2: расширить опять же класс и 2ой это нагло переписать, смотрите сами. Я изменил вот так вставку
// is it second put?
if( isset($this->_cart_contents[$rowid]) ){
	$this->_cart_contents[$rowid]['qty'] += $items['qty'];
}else{
	unset($this->_cart_contents[$rowid]);
	// Create a new index with our new row ID
	$this->_cart_contents[$rowid]['rowid'] = $rowid;

	// And add the new items to the cart array
	foreach ($items as $key => $val){
		$this->_cart_contents[$rowid][$key] = $val;
	}
}


Недочет 3, который тоже очень портит жизнь особенно если у вас много внутренних вызовов внутри контроллера своих же методов с заполнением различных шаблонов и Views.

В чем проблема, простенький пример набрасываю: контроллер Article два метода

public function show($id){
    $data = array( 'title' => 'hello' );
    $this->template['show'] = $this->load->view( 'article/show', $data, TRUE );
    $tags = array( 'tag1', 'tag2', 'tag3' );
    $this->template['tags'] = $this->load->view( 'article/tags', $tags, TRUE );
    $this->load->view( 'layouts/inside', $this->template ); // **
}


Ну так вот в чем суть, что последний вызов шаблона будет знать о кучке других переменных например ему помимо $show, $tags будут еще доступны $title и массив $tags. Знаете ли мне кажется это не совсем удобно и правильно. Если еще в MVC это не так сильно будет мешать, а вот в применении HMVC то будет страшновато смотреть что там накопилось за время работы.
На заметку, память поедается методом vars и _ci_load обратите внимание в классе libraries/Loader, решений так же 2, переписать и расширить.
Я просто переписал в методе _ci_load
if (is_array($_ci_vars)){
    $this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars);
}

на строку вида
if (is_array($_ci_vars)){
    $this->_ci_cached_vars = $_ci_vars;
}

Не оптимально, но приемлимо получилось.

А вообще CodeIgniter, конечно был в своё время очень хорошим фреймворком, брал своей простотой, обилием библиотек, хорошей документацией и отличным сообществом, но в последнее какой-то период «застоя». Версия 2 топчется на месте, коммунити разваливается, да и вообще в мире выросло уже много не плохих альтернатив, я лично уже в предвкушении FuelPHP фреймворка от команды, что работала над CodeIgniter и PyroCMS.

0 комментариев

Автор топика запретил добавлять комментарии