Скелет для приложения в CodeIgniter



Леса - основа для строительстваПрочитав довольно большой объём материала по CodeIgniter, я заметил что основная масса полезной, казалось бы, информации проходит сквозь мою голову, абсолютно не задерживаясь. Мне явно не хватало начального представления о базовых конструктивах приложения, чтобы на них наращивать мясо дополнительного функционала.

Также изучив некоторое количество примеров начального уровня, я пришёл к выводу, что они направлены на то чтобы дать базовое представление о CodeIgniter, и слишком примитивны чтобы быть использованными в полевых условиях. И мне пришла мысль написать очередной туториал для себя.

Код который приведён ниже это не совсем туториал. Это попытка создать код для реального приложения. Поэтому код может быть слабо понятным для начинающих. Зато фрагменты отсюда, надеюсь, можно в дальнейшем использовать в боевых условиях.

В большинстве примеров в интернете описывается написание блога. На самом деле для понимания неважно, что именно реализует код. Достаточно понимать базовые принципы его работы, а они одинаковы. Поэтому для примера я выбрал ведение справочника телефонов на мини-АТС. Разумеется CodeIgnitor должен быть установлен и настроен.

Начинаем с создания БД:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
CREATE TABLE `atc_phones` (
  `in_phone` smallint(4) NOT NULL,
  `out_line` mediumint(9) NOT NULL,
  `dept` varchar(100) collate utf8_bin NOT NULL,
  `id` mediumint(9) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY  (`id`),
  UNIQUE KEY `in_phone` (`in_phone`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
 
 
INSERT INTO `atc_phones` (`in_phone`, `out_line`, `dept`) VALUES 
(234, 234, 'Отдел умников'),
(345, 345, 'Отдел очкариков'),
(456, 456456, 'Отдел охламонов');

Далее пишем модель mphones.php
Вообще-то в элементарных примерах обходятся без модели, но я посчитал этот момент принципиальным и всё-таки сделал модель. Модель отвечает за все операции с БД. У меня реализованы функции:

  • get_last_ten_entries – получить 10 последних записей
  • get_entry – получить конкретную запись
  • insert_entry – добавление записи
  • update_entry – обновить запись
  • delete_entry – обновить запись

Функции настолько просты, что не нуждаются в комментировании.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<?
class Mphones extends Model {
 
    var $id   = '';
    var $in_phone   = '';
    var $out_line = '';
    var $dept    = '';
 
    function Mphones()
    {
        // Call the Model constructor
        parent::Model();
    }
 
    function get_last_ten_entries()
    {
        $query = $this->db->get('atc_phones',10);
        return $query;
    }
    function get_entry($id)
    {
        $query = $this->db->get_where('atc_phones', array('id' => $id));
        return $query;
    }
 
    function insert_entry($data)
    {
        $this->in_phone   = intval($data['in_phone']);
        $this->out_line = intval($data['out_line']);
        $this->dept    = $data['dept'];
 
        $this->db->insert('atc_phones', $this);
    }
 
    function update_entry($data)
    {
        $this->id   = intval($data['id']);
        $this->in_phone   = intval($data['in_phone']);
        $this->out_line = intval($data['out_line']);
        $this->dept    = $data['dept'];
 
        $this->db->update('atc_phones', $this, array('id' => $data['id']));
    }
 
    function delete_entry($id)
    {        
	$this->db->delete('atc_phones', array('id' => $id));
    }
}
?>

Контроллер phones.php
Это главная составляющая отвечающая за логику приложения.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
<?php
class Phones extends Controller {
	var $rules = array(
		"in_phone"=>"required|integer",
		"out_line"=>"required|integer", 
		"dept"=>"xss_clean|trim|strip_tags|required"
		);
	var $fields = array(
		"in_phone"=>"Внутренний телефон",
		"out_line"=>"Внешняя линия", 
		"dept"=>"Подразделение/ФИО"
		);
 
	function Phones()
	{
		parent::Controller();
		$this->load->model('mphones');
		$this->load->helper('url');
		$this->load->helper('form');
		$this->load->library('validation');
		$this->validation->set_rules($this->rules);
		$this->validation->set_fields($this->fields);	
	}
 
	function index()
	{
		$data['query'] = $this->mphones->get_last_ten_entries();
		$data['header'] = 'Телефонные номера';
		$data['title'] = 'Телефонные номера';
		$this->load->view('vphones', $data);
	}
 
	function add()
	{	
		if (!$this->validation->run())  //  вызов проверки данных
		{
			$data['row'] = $_POST;; 
			$data['header'] = 'Добавить телефонные номер';
			$data['title'] = 'Добавить телефонный номер';
			$data['err']=$this->validation->error_string;
			$this->load->view('vphonesadd', $data);
			return;
		}
 
		$this->mphones->insert_entry($_POST);
		redirect('phones');
	}
	function delete($id)
	{
		$this->mphones->delete_entry(intval($id));
		redirect('phones');
	}
	function edit($id)
	{
		$query = $this->mphones->get_entry(intval($id));
		if ($query->num_rows() <= 0) {
			redirect('phones');
		}else{
			$data['err'] = ''; 
			$data['row'] = $query->row_array(); 
			$data['header'] = 'Редактировать телефонные номер';
			$data['title'] = 'Редактировать телефонный номер';
			$this->load->view('vphonesedit', $data);
		};
	}
	function save()
	{
		if (!$this->validation->run())  //  вызов проверки данных
		{
			$data['row'] = $_POST;; 
			$data['header'] = 'Редактировать телефонные номер';
			$data['title'] = 'Редактировать телефонный номер';
			$data['err']=$this->validation->error_string;
			$this->load->view('vphonesedit', $data);
			return;
		}
 
		$this->mphones->update_entry($_POST);
		redirect('phones');
	}
}
?>

Контроллер в случае вызова всех функций загружает представление phonesview соответствующее функции index() или URI phones/index или phones. Только в функции edit, при вызове которой должна открыться форма для редактирования, используется представление phoneseditview
Подробнее о соответствиях URL и функций контроллеров здесь.

В контроллере и представлениях используютя функции хелперов URL и FORMS. Для этого в конструкторе контроллера выполняется их загрузка.

В контроллере выполняется валидация введёных данных. Это нужно как для безопасности, так и для “защиты от дурака”. Для этого используется объект Validation. Отдельно заводится массив rules для правил валидации, и массив fields с описаниями для вывода в сообщениях.

В целях безопасности параметры, которые должны быть числовыми, проходят дополнительную проверку. А строковые проверяются на XSS включения, а потом ещё из них вырезаются все теги. Так что код должен быть довольно безопасным

Представление vphones.php
Это представление соответствует основной отображаемой странице. Здесь представление приведено как пример. А дальше соль/сахар по вкусу.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<html>
<head>
<title><?php echo $title;?></title>
</head>
<body>
<h1><?php echo $header;?></h1>
<table border=1>
<tr>
<td></td>
<td></td>
<td>№</td>
<td>Внутр.номер</td>
<td>Внешняя линия</td>
<td>Подразделение/ФИО</td>
</tr>
 
<?foreach ($query->result() as $row):?>
 
<tr>
<td><?=anchor('phones/delete/'.$row->id,'x','title="Удалить"')?></td>
<td><?=anchor('phones/edit/'.$row->id,'e','title="Изменить"')?></td>
<td><?=$row->id?></td>
<td><?=$row->in_phone?></td>
<td><?=$row->out_line?></td>
<td><?=$row->dept?></td>
</tr>
<? endforeach?>  
</table>
<br>
<h3>Добавить новый</h3>
<?=form_open('phones/add')?>
<table border=1>
<tr>
<td>Внутренний номер</td>
<td><?=form_input('in_phone','')?></td>
</tr>
<tr>
<td>Внешняя линия</td>
<td><?=form_input('out_line','')?></td>
</tr>
<tr>
<td>Подразделение/ФИО</td>
<td><?=form_input('dept','')?></td>
</tr>
<tr>
<td></td>
<td><?=form_submit('qwe','OK')?></td>
</tr>
 
</table>
</form>
 
</body>
</html>

Представление vphonesadd.php
Нужен для формы добавления. Кроме этого представления форма добавления имеется на главном виде, но для вывода ошибки валидации и предложения продолжить ввод потребовался отдельный вид.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<html>
<head>
<title><?php echo $title;?></title>
</head>
<body>
 
<div class="err"> <?=$err?> </div> 
 
<h1><?php echo $header;?></h1>
Редактирование номера
<? echo form_open('phones/add')?>
 
<table border=1>
<tr>
<td>Внутренний номер</td>
<td><? echo form_input('in_phone',$row['in_phone'])?></td>
</tr>
<tr>
<td>Внешняя линия</td>
<td><? echo form_input('out_line',$row['out_line'])?></td>
</tr>
<tr>
<td>Подразделение/ФИО</td>
<td><? echo form_input('dept',$row['dept'])?></td>
</tr>
<tr>
<td></td>
<td><? echo form_submit('qwe','OK')?></td>
</tr>
 
</table>
</form>
<? echo anchor('phones','Назад')?>
 
</body>
</html>

Представление vphonesedit.php
Содержит форму редактирования.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<html>
<head>
<title><?php echo $title;?></title>
</head>
<body>
 
<div class="err"> <?=$err?> </div> 
 
<h1><?php echo $header;?></h1>
Редактирование номера
<? echo form_open('phones/save')?>
<? echo form_hidden('id',$row['id'])?></td>
 
<table border=1>
<tr>
<td>Внутренний номер</td>
<td><? echo form_input('in_phone',$row['in_phone'])?></td>
</tr>
<tr>
<td>Внешняя линия</td>
<td><? echo form_input('out_line',$row['out_line'])?></td>
</tr>
<tr>
<td>Подразделение/ФИО</td>
<td><? echo form_input('dept',$row['dept'])?></td>
</tr>
<tr>
<td></td>
<td><? echo form_submit('qwe','OK')?></td>
</tr>
 
</table>
</form>
<? echo anchor('phones','Назад')?>
 
</body>
</html>

Вот собственно пока всё. А напоследок хочу сказать PHP-программистам:
- Изучайте фрейворки, так вы будете делать более качественный код за меньшее время!!
Ну а из фремворков CodeIgniter не самый плохой выбор.

Все файлы можно скачать здесь (всего скачали 724 раз)

Посты по теме:

  1. Проверка форм в CodeIgniter
  2. AJAX на CodeIgniter
  3. Кеширование в CodeIgniter
  4. Модули в Kohana и CodeIgniter
  5. CMS-визитка на CodeIgniter

Категории CodeIgniter |
автор: altesack / Среда, Апрель 29, 2009 / 15 комментов »

15 комментов

    охренительно большую работу сделал, еще бы время найти попробовать это все….

    Ну не такую уж и большую :)
    А главное не зря.

    Хорошее представление модели и работа контролера .. очень легко усвоилось
    но возник такой вопрос во вьювере vphones.php есть такая строка тоесть задействовали хелпер форм но вот как сделать что бы по клику переходил не на url index.php/phones/add а просто phones/add
    … написал и подумал.. что надо почитать про урлы …
    спасибо за статью :-)

    Стока времени думал как это сделать, а написал вам и сразу нашёл ответ )
    в общем заменил я
    form_open(’phones/add’)
    на
    form_open(base_url().’add’)
    конечно же .htaccess у меня в порядке ;-)
    всех вам благ и процветания :-)

    Vasiliy пишет:

    Стока времени думал как это сделать, а написал вам и сразу нашёл ответ )

    Надеюсь проблема ушла.

    Ну, я в общем то также работаю )
    даже админку написал – с применением аякса(ТОЛЬКО JQUERY), там прикольно вобщем ) если интересно – можешь написать на 293шесть888шесть6, покажу и поделюсь.

    Привет, не получается запустить твой скрипт на своей машине. Пишет такую ошибку:
    A PHP Error was encountered
    Severity: Notice
    Message: Undefined property: Test::$db
    Filename: controllers/test.php
    Line Number: 11

    Fatal error: Call to a member function get() on a non-object in Z:\home\localhost\www\site\system\application\controllers\test.php on line 11
    Подскажи в чем может быть проблема?

    ээ, конечно вместо Test у меня Mphones

    @ sikon: А библиотека “database” у тебя подключена?
    Попробуй в конструкторе контроллера явно прописать строчку

    $this->load->library(’database’);

    Теперь по другому ругается:
    Unable to load the requested class: database

    Спасибо, получилось таким образом:
    $this->load->database();

    @ sikon:
    Да, это я ошибся.
    А вообще это нужно прописывать в config/autoload.php
    В строчке
    $autoload['libraries'] = array(’database’, ….);

    Извиняюсь, а что нужно поменять в скриптах чтобы работало в codeigniter 2.0 ?

    CI 2.0 не смотрел, не знаю. Попробуйте поищите статьи по переходу на 2.0. Наверняка такие есть.