Напомню для запамятовавших Model в парадигме MVC отвечает за работу с источником данных, обычно это MySQL и прочие реляционные БД, хотя сейчас набирают популярность NoSQL БД. Сейчас не об этом в этой заметке покажу, как работать с Model в CodeIgniter т.к. это доставило наибольшие сложности при работе с этим Фреймворком. Начнем с того что у нас есть выбор как исполнять запросы к БД в CodeIgniter первое мы можем пользоваться привычными нам запросами sql вызывая функцию query(‘some query’); Лучше изучать что либо на примере, лучше один раз увидеть чем сто раз услышать. Стоит упомянуть о конвенции, класс модели должен начинаться с большой буквы, имя файла должно соответствовать имени класса в нижнем регистре.
class Blogmodel extends CI_Model { public _construct() { parent::__construct(); } public function get_last_entries() { $query = $this->db->query('SELECT *FROM posts LIMIT 10'); return $query; } public function get_last_post() { $query = $this->db->query('SELECT *FROM posts LIMIT 1'); return $query; } public function update_record($title,$post) { $sql = "INSERT INTO posts(title, post) VALUES (".$this->db->escape($title).", ".$this->db->escape($post).")"; $this->db->query($sql); echo $this->db->affected_rows(); } } //... public function SomeFunctionWhereWeUseOurModel() { $this->load->model('Blogmodel'); $result=$this->Blogmodel->get_last_entries(); foreach($result->result() as $row) echo $row->title.'<br/>'; foreach($row->result_array() as $row) echo $row['title'].'<br/>'; $result=$this->Blogmodel->get_last_post(); $title=$result->row(); echo "our last post ".$title->title; $title=$result->row_array(); echo "our last post ".$title['title']; }
Если мы переопределяем конструктор, то не забываем в самом начале вызвать базовый. В функции get_last_entries мы получаем последние 10-ть постов, заметьте, что можно получить результаты двумя способами как объект либо как ассоциативный массив. В функции get_last_post мы получаем лишь единственную запись, не используя механизм foreach так же можем получить как объект, так и ассоциативный массив. В функции update_record мы вставляем запись в БД используя функции для экранирования, что бы предотвратить sql инъекцию в CodeIgniter существует несколько функций экранирования. Вот перечень из них
- $this->db_escape()
- $this->db->escape_str()
- $this->db->escape_like_str()
$this->db->escape() Эта функция определяет тип данных, так что она экранирует только строки. Она также автоматически добавляет одинарные кавычки вокруг данных, поэтому вы не должны делать этого. $this->db->escape_str() Эта функция экранирует данные, переданные ей, в независимости от их типа. В большинстве случаев вы будете использовать функцию выше, а не эту. Используйте эту функцию вот так. $this->db->escape_like_str() Этот метод может быть использован, когда строки могут быть использованы в условиях LIKE, так что подстановки (‘%’, ‘_’) в строках будут также экранированы. Так же есть возможность использование параметризованных запросов их преимущество состоит в том, что данные автоматически экранируются. Пример
$sql = "SELECT * FROM some_table WHERE id = ? AND status = ? AND author = ?"; $this->db->query($sql, array(3, 'live', 'Rick'));
Вспомогательными функциями для работы с результатами запросов относятся следующие.
$query = $this->db->query('SELECT * FROM my_table'); echo $query->num_rows(); $query = $this->db->query('SELECT * FROM my_table'); echo $query->num_fields(); $query = $this->db->query('SELECT title FROM my_table'); foreach ($query->result() as $row) { echo $row->title; } $query->free_result(); // Объект результата $query больше не будет доступен
Тут мы разобрали классические sql запросы, перейдем теперь к Active Record, этот паттерн позволяет абстрагироваться от конкретной реализации БД и выполнять запросы в едином стиле. Используя Active Record мы уже получаем экранированные, защищенные запросы. Я остановлюсь на основных из них более подробную информацию можно узнать из страницы документации, на которую я дам ссылку ниже.
1. Выборка данных.
$query = $this->db->get('mytable'); //Делает: SELECT * FROM mytable $query = $this->db->get('mytable', 10, 20); // Делает: SELECT * FROM mytable LIMIT 20, 10 (в MySQL. Другие базы данных могут иметь несколько другой синтаксис) //Второй и третий параметры позволяют указывать лимит и смещение $query = $this->db->get('mytable'); foreach ($query->result() as $row) { echo $row->title; } $query = $this->db->get_where('mytable', array('id' => $id), $limit, $offset); //Эквивалент SELECT *FROM mytable WHERE id=id $this->db->select('title, content, date'); $query = $this->db->get('mytable'); // Производит: SELECT title, content, date FROM mytable
Замечу что результат, который возвращают эти функции такой же, как при применении классических sql запросов, функции для работы с которыми приведены были выше. Опишем подробнее действия функций.
- $this->db->get(); получает все записи из указанной таблицы
- $this->db->get_where(); получает все записи из указанной таблицы с заданным условием 3-им и 4-м параметром идет лимит и смещение эти параметры не обязательны. Условие задается в виде ассоциативного массива, где ключ условия, а значение это проверяемая величина, т.е. $cond['balance <']=150;$query = $this->db->get_where(‘mytable’, $cond, $limit, $offset);
- $this->db->select(); получает все записи указанных полей
2. Вставка данных
$data = array( 'title' => 'My title' , 'name' => 'My Name' , 'date' => 'My date' ); $this->db->insert('mytable', $data); // Производит: INSERT INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date') class Myclass { var $title = 'My Title'; var $content = 'My Content'; var $date = 'My Date'; } $object = new Myclass; $this->db->insert('mytable', $object); // Производит: INSERT INTO mytable (title, content, date) VALUES ('My Title', 'My Content', 'My Date')
Как видите для вставки данных может, использован как массив, так и объект, функции очевидны, так что комментировать думаю, будет уже излишне.
3.Обновление данных
$data = array( 'title' => $title, 'name' => $name, 'date' => $date ); $this->db->where('id', $id); $this->db->update('mytable', $data); class Myclass { var $title = 'My Title'; var $content = 'My Content'; var $date = 'My Date'; } $object = new Myclass; $this->db->where('id', $id); $this->db->update('mytable', $object); // Делает: // UPDATE mytable // SET title = '{$title}', name = '{$name}', date = '{$date}' // WHERE id = $id $this->db->update('mytable', $data, "id = 4"); $this->db->update('mytable', $data, array('id' => $id));
Как видим ситуация такая же как со вставкой данных мы можем использовать как объект так и массив как удобно, перед запросом обновления была использована функций where которая задает параметр условия, что бы избежать вызова двух функций
условие можно упаковать в третий параметр либо строкой либо в виде ассоциативного массива.
4. Удаление данных
$this->db->delete('mytable', array('id' => $id)); // Производит: // DELETE FROM mytable // WHERE id = $id
Здесь думаю, комментарии излишни.
Это краткий обзор возможностей Model в CodeIgniter более подробную информацию можно получить в документации тут. Целью этой заметки было компактное изложение, думаю человек, досконально изучивший документацию, врятли найдет тут что-то
новое, ну а человек кому нужен результат сразу это будет самое то.
вместо “_construct()” надо “__construct()” (два символа подчеркивания вместо одного)
Спасибо исправил