Удобное расширение модели CodeIgniter
Автор кода – Ерёмин Никита. Спасибо за красивое и удобное решение.
В system/application/models создаем файл base_model.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 83 84 85 86 87 88 |
<?php class Base_model extends Model { protected $table; protected static $count; //общее число записей (для пейджинации) function Base_model() { parent::Model(); // Вырезаем из имени класса модели окончание "_model" //(Например, из User_model получаем User) $model_class_name = strtolower(get_class($this)); $this->table = substr_replace($model_class_name,"", strpos($model_class_name,"_model"),6); } function get_all($limit='', $offset='', $order_by='') { $this->db->select('*'); $this->db->from($this->table); if ($order_by) $this->db->order_by($order_by); self::$count = $this->db->count_all_results('', true); $this->apply_pagination_settings($limit, $offset); return $this->db->get()->result(); } function apply_pagination_settings($limit, $offset) { if ($limit and $offset) { $this->db->limit($limit, $offset); } elseif ($limit) { $this->db->limit($limit); } return; } function count_all() { if (self::$count) { return self::$count; } return $this->db->count_all($this->table); } function find($where, $order_by='') { $this->db->select('*'); $this->db->from($this->table); $this->db->where($where); if ($order_by != '') { $this->db->order_by($order_by); } $result = $this->db->get()->result(); return $result; } function get_by_id($id) { $this->db->select('*'); $this->db->from($this->table); $this->db->where('id', $id); $res = $this->db->get()->result(); if (count($res) > 0) return $res[0]; return null; } function save($id, $data) { if ($id) { foreach($data as $key=>&$item) { if($item===''){unset($data[$key]);} } $this->db->where('id', $id); $this->db->update($this->table, $data); } else { $this->db->insert($this->table, $data); } } function delete($id) { $this->db->delete($this->table, array('id' => $id)); } } ?> |
Все остальные наши модели объявляем уже как расширения нашей base_model.
Например, создадим модель user_model. В файле user_model.php размещаем такой код:
1 2 3 4 5 6 7 8 |
<?php class User_model extends Base_model { } ?> |
Наша новая модель унаследовала весь функционал base_model. Т.е. она может выбирать данные из таблицы user, вставлять, обновлять, удалять, считать количество записей:
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 |
<?php class Main extends Controller { function index(){ $this->load->model('base_model'); $this->load->model('user_model'); //выборка всех пользователе $users = $this->user_model->get_all(); //добавление нового пользователя $data = array('username' => 'Petr', 'surname' => 'Ivanov', 'email' => 'ivanov.petr@gmail.com' ); $this->user_model->save('',$data); // допустим данный id существует в таблице user $id = 15; // обновление данных (update) для id=15 $this->user_model->save($id, $data); // удаление записи с id=15 $this->user_model->delete($id); } } ?> |
1 2 3 4 5 6 |
Для работы данного кода необходимо соблюдать два правила: 1. Все таблицы БД должны содержать поле id. (`id` int(11) NOT NULL auto_increment ) 2. Классы моделей должны называться по следующему правилу Tablename_model. |
Второе правило можно изменить под свои привычки, тогда нужно будет внести соответствующие корректировки в эти две строчки кода (в конструкторе base_model):
1 2 3 4 5 6 7 |
$model_class_name = strtolower(get_class($this)); $this->table = substr_replace($model_class_name,"", strpos($model_class_name,"_model"),6); |
Можно, вообще избавиться от ограничений по именованию классов и переписать все функции, для приема имени таблицы в качестве параметра. Но, это дело вкуса. Как по мне, то проще соблюсти несложные правила.
Константин, спасибо за замеченные ошибки!
1. $this->order_by($order_by); Подразумевалась собственная функция сортировки, но я её опустил (для упрощения), а обращался по прежнему к ней. Вообщем, сейчас исправил на $this->db->order_by($order_by);
2. $this->db->select(’*’); всегда пишу для читабельности.
3. Добавил определение protected static $count;
В методе get_all ошибка:
вместо $this->order_by($order_by);
нужно $this->db->order_by($order_by);
Кроме того не обязательно $this->db->select(‘*’);
В строке self::$count = $this->db->count_all_results(”, true);
ругается на self::$count и не отрабатывает $this->db->count_all_results(”, true); – не видит таблицу (хотя по дебагу имя таблицы из имени модели определяет точно. Если эту строчку удалить , то функция отрабатывается нормально.