Встречайте четвертую часть цикла статей по разработке с Kohana PHP V3 (KO3). редыдущие части можно найти по метке "знакомство с kohana 3.0". В этот раз речь пойдет о работе с моделями.
Определение модели возьмем из документации Kohana 2.x:
По сути, модель – это манипулятор данными.
Первым делом мы должны определить, что будет являться данными: XML-лента, CSV, JSON, DB или что-то другое? Не стану вас мучать и скажу, что в этот раз мы поработаем с давним другом MySQL. Поэтому следующим шагом станет настройка подключения к базе данных.
Давайте откроем загрузочный файл (”application/bootstrap.php”), найдем там строку “// ‘database’ => MODPATH.’database’, // Database access” и раскомментируем ее. Весь блок теперь должен выглядеть так:
Теперь сохраните файл. Мы только что приказали фреймворку загружать модуль базы данных, но он еще не сконфигурирован. Скопируйте “database.php” из “modules/database/config/” в “application/config/”. Откройте файл “application/config/database.php” и отредактируйте его в соответствии с вашими настройками. Мой выглядит так:
Сохраните файл. Для э��ой серии статей я создал базу данных “mykohana3″, вам желательно сделать то же самое. Таблицу в базе данных мы создадим с помощью следующего SQL-кода:
Запустите его в вашем любимом MySQL-клиенте, лично я предпочитаю SQLYog. Как в конфигурации подключения к БД, так и для таблицы я выставил кодировку “utf8″. Это понадобится нам в будущем.
Давайте в “application/classes” создадим новую папку “model”. В ней создайте новый файл и поместите туда следующее:
Сохраните это как “post.php” в “application/classes/model/”. Теперь разберем код построчно.
Это базовый запрос MySQL, который выбирает до десяти записей из базы данных, который сортируются по полю ‘id’ в порядке убывания.
Это возвращает массив с результатом запроса. Метод “query” в данном примере принимает три параметра. Первый – тип запроса, у нас это “select”, поэтому мы передаем константу “Database::SELECT”. Также есть три других: “Database::INSERT”, “Database::UPDATE” и “Database::DELETE”. Метод “as_array()” возвращает массив с результатами, так что исчезает необходимость делать “while($row = mysql_fetch_array())”.
Теперь, когда у нас в модели появился метод, можно начать его использовать. Откройте “ko3.php” в “/application/classes/controller” и добавьте в класс следующий код:
Только что мы вызвали из модели метод “getLastTenPosts()” и поместили возвращаемое им значение в массив, который затем передали нашему виду. Кстати о видах: откройте новый файл и поместите туда:
Сохраните это как “posts.php” в папке “application/views/pages/”. Этот вид перебирает передаваемый контроллером массив и выводит записи из базы данных. Хотя, стоп, у нас же в базе данных еще нет статей! Исправим это следующими SQL-запросами:
Теперь, перейдя по адресу “http://localhost/mykohana3/ko3/posts”, вы должны увидеть две записи.
Давайте теперь реализуем добавление новых данных в базу. Откройте нашу модель (”application/classes/model/post.php”) и добавьте в класс следующее:
Выше находится довольно простой запрос типа INSERT, но что такое “$this->_db>escape()”? Этот метод обрамит ваши строковые переменные кавычками и очистит их от мусора. Сохраните это и вернитесь к “posts.php” из “application/views/pages”. Замените его содержимое этим:
Сохраните файл и откройте контроллер (”application/classes/controller/ko3.php”). Добавим-ка к нему новый метод:
Этот код является промежуточным звеном между “action_posts” и моделью, он служит для непосредственного сохранения записи. Давайте вернем��я к методу “action_posts” и приведем его к такому виду:
Сохраните это и перезагрузите браузер. Внизу должна появиться форма страшноватого вида. Введите что-то и нажмите «Отправить». Если вы заполнили оба поля, то ваша запись должна появиться наверху вместе с надписью “Saved”. В ином случае должно появиться сообщение об ошибке.
Прежде чем закончить ознакомление с моделями, хочу показать, как еще можно было производить добавление записи в базу данных. Существует несколько способов, но я обращу внимание только на так называемый Query Builder. MySQL-запрос в методе «addPost()» с ним выглядел бы так:
Query Builder удобен в частности тем, что позволяет переключаться между разными типами баз данных (из MySQL в Oracle, и т.п.)
Обновление записей я в модели не реализовал, так что можете рассматривать это как домашнее задание.
Определение модели возьмем из документации Kohana 2.x:
Модели — это классы, предназначенные для работы с информацией, передаваемой или запрашиваемой контроллером. Например, если у вас есть гостевая книга, то контроллер запрашивает у модели последние десять записей; модель их возвращает; контроллер передает эти данные виду. Контроллер также может с помощью модели добавить новые записи и обновить или удалить существующие.
По сути, модель – это манипулятор данными.
Первым делом мы должны определить, что будет являться данными: XML-лента, CSV, JSON, DB или что-то другое? Не стану вас мучать и скажу, что в этот раз мы поработаем с давним другом MySQL. Поэтому следующим шагом станет настройка подключения к базе данных.
Давайте откроем загрузочный файл (”application/bootstrap.php”), найдем там строку “// ‘database’ => MODPATH.’database’, // Database access” и раскомментируем ее. Весь блок теперь должен выглядеть так:
Kohana::modules(array( // 'auth' => MODPATH.'auth', // Basic authentication // 'codebench' => MODPATH.'codebench', // Benchmarking tool 'database' => MODPATH.'database', // Database access // 'image' => MODPATH.'image', // Image manipulation // 'orm' => MODPATH.'orm', // Object Relationship Mapping // 'pagination' => MODPATH.'pagination', // Paging of results // 'userguide' => MODPATH.'userguide', // User guide and API documentation ));
Теперь сохраните файл. Мы только что приказали фреймворку загружать модуль базы данных, но он еще не сконфигурирован. Скопируйте “database.php” из “modules/database/config/” в “application/config/”. Откройте файл “application/config/database.php” и отредактируйте его в соответствии с вашими настройками. Мой выглядит так:
<?php defined('SYSPATH') OR die('No direct access allowed.'); return array ( 'default' => array ( 'type' => 'mysql', 'connection' => array( /** * The following options are available for MySQL: * * string hostname * integer port * string socket * string username * string password * boolean persistent * string database */ 'hostname' => 'localhost', 'username' => 'root', 'password' => FALSE, 'persistent' => FALSE, 'database' => 'mykohana3', ), 'table_prefix' => '', 'charset' => 'utf8', 'caching' => FALSE, 'profiling' => TRUE, ), 'alternate' => array( 'type' => 'pdo', 'connection' => array( /** * The following options are available for PDO: * * string dsn * string username * string password * boolean persistent * string identifier */ 'dsn' => 'mysql:host=localhost;dbname=mykohana3', 'username' => 'root', 'password' => FALSE, 'persistent' => FALSE, ), 'table_prefix' => '', 'charset' => 'utf8', 'caching' => FALSE, 'profiling' => TRUE, ), );
Сохраните файл. Для э��ой серии статей я создал базу данных “mykohana3″, вам желательно сделать то же самое. Таблицу в базе данных мы создадим с помощью следующего SQL-кода:
CREATE TABLE `posts` ( `id` MEDIUMINT(8) UNSIGNED NOT NULL AUTO_INCREMENT, `title` VARCHAR(255) DEFAULT NULL, `post` TEXT, PRIMARY KEY (`id`) ) ENGINE=INNODB DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC;
Запустите его в вашем любимом MySQL-клиенте, лично я предпочитаю SQLYog. Как в конфигурации подключения к БД, так и для таблицы я выставил кодировку “utf8″. Это понадобится нам в будущем.
Давайте в “application/classes” создадим новую папку “model”. В ней создайте новый файл и поместите туда следующее:
<?php defined('SYSPATH') or die('No direct script access.'); class Model_Post extends Kohana_Model { /** * Get the last 10 posts * @return ARRAY */ public function getLastTenPosts() { $sql = 'SELECT *'."\n". 'FROM `posts`'."\n". 'ORDER BY `id` DESC'."\n". 'LIMIT 0, 10'; return $this->_db->query(Database::SELECT, $sql, FALSE) ->as_array(); } }
Сохраните это как “post.php” в “application/classes/model/”. Теперь разберем код построчно.
$sql = 'SELECT *'."\n". 'FROM `posts`'."\n". 'ORDER BY `id` DESC'."\n". 'LIMIT 0, 10';
Это базовый запрос MySQL, который выбирает до десяти записей из базы данных, который сортируются по полю ‘id’ в порядке убывания.
return $this->_db->query(Database::SELECT, $sql, FALSE) ->as_array();
Это возвращает массив с результатом запроса. Метод “query” в данном примере принимает три параметра. Первый – тип запроса, у нас это “select”, поэтому мы передаем константу “Database::SELECT”. Также есть три других: “Database::INSERT”, “Database::UPDATE” и “Database::DELETE”. Метод “as_array()” возвращает массив с результатами, так что исчезает необходимость делать “while($row = mysql_fetch_array())”.
Теперь, когда у нас в модели появился метод, можно начать его использовать. Откройте “ko3.php” в “/application/classes/controller” и добавьте в класс следующий код:
public function action_posts() { $posts = new Model_Post(); $ko3 = array(); $this->template->title = 'Kohana 3.0 Model Test'; $this->template->meta_keywords = 'PHP, Kohana, KO3, Framework, Model'; $this->template->meta_description = 'A test of of the KO3 framework Model'; $this->template->styles = array(); $this->template->scripts = array(); // Get the last 10 posts $ko3['posts'] = $posts->getLastTenPosts(); $this->template->content = View::factory('pages/posts', $ko3); }
Только что мы вызвали из модели метод “getLastTenPosts()” и поместили возвращаемое им значение в массив, который затем передали нашему виду. Кстати о видах: откройте новый файл и поместите туда:
<?php foreach($posts as $post):?> <h1><?php echo $post['title'];?></h1> <?php echo $post['post'];?> <hr /> <?php endforeach;?>
Сохраните это как “posts.php” в папке “application/views/pages/”. Этот вид перебирает передаваемый контроллером массив и выводит записи из базы данных. Хотя, стоп, у нас же в базе данных еще нет статей! Исправим это следующими SQL-запросами:
insert into `posts`(`id`,`title`,`post`) values (1,'Test Post','This is some sample text.'); insert into `posts`(`id`,`title`,`post`) values (2,'Another post','Some more text');
Теперь, перейдя по адресу “http://localhost/mykohana3/ko3/posts”, вы должны увидеть две записи.
Давайте теперь реализуем добавление новых данных в базу. Откройте нашу модель (”application/classes/model/post.php”) и добавьте в класс следующее:
public function addPost($title, $post) { $sql = sprintf('INSERT INTO `posts`'."\n". 'SET `title` = %s,'."\n". ' `post` = %s', $this->_db->escape($title), $this->_db->escape($post)); $this->_db->query(Database::INSERT, $sql, FALSE); }
Выше находится довольно простой запрос типа INSERT, но что такое “$this->_db>escape()”? Этот метод обрамит ваши строковые переменные кавычками и очистит их от мусора. Сохраните это и вернитесь к “posts.php” из “application/views/pages”. Замените его содержимое этим:
<?php if(!empty($msg)):?> <?php echo $msg.'<br />';?> <?php endif;?> <?php foreach($posts as $post):?> <h1><?php echo $post['title'];?></h1> <?php echo $post['post'];?> <hr /> <?php endforeach;?> <form method="POST" action="<?php echo url::base();?>ko3/posts/"> <table> <tr> <td> Title </td> <td> <input type="text" name="title" style="border: 1px solid #000000;"/> </td> </tr> <tr> <td> Post </td> <td> <textarea cols="20" rows="5" name="post"></textarea> <input type="submit" name="submit" value="Submit"/> </td> </table> </form>
Сохраните файл и откройте контроллер (”application/classes/controller/ko3.php”). Добавим-ка к нему новый метод:
private function _addPost($title, $post_content) { // Load model $post = new Model_Post(); // Check required fields if(empty($title)) { return(array('error' => 'Please enter a title.')); } elseif(empty($post_content)) { return(array('error' => 'Please enter a post.')); } // Add to DB $post->addPost($title, $post_content); return TRUE; }
Этот код является промежуточным звеном между “action_posts” и моделью, он служит для непосредственного сохранения записи. Давайте вернем��я к методу “action_posts” и приведем его к такому виду:
public function action_posts() { // Load model $posts = new Model_Post(); // Setup view stuff $ko3 = array(); $this->template->title = 'Kohana 3.0 Model Test'; $this->template->meta_keywords = 'PHP, Kohana, KO3, Framework, Model'; $this->template->meta_description = 'A test of of the KO3 framework Model'; $this->template->styles = array(); $this->template->scripts = array(); $ko3['msg'] = ""; // Handle POST if($_POST) { $ret = $this->_addPost((isset($_POST['title']) ? $_POST['title'] : ""), (isset($_POST['post']) ? $_POST['post'] : "")); if(isset($ret['error'])) { $ko3['msg'] = $ret['error']; } else { $ko3['msg'] = 'Saved.'; } } // Get the last 10 posts $ko3['posts'] = $posts->getLastTenPosts(); // Display it. $this->template->content = View::factory('pages/posts', $ko3); }
Сохраните это и перезагрузите браузер. Внизу должна появиться форма страшноватого вида. Введите что-то и нажмите «Отправить». Если вы заполнили оба поля, то ваша запись должна появиться наверху вместе с надписью “Saved”. В ином случае должно появиться сообщение об ошибке.
Прежде чем закончить ознакомление с моделями, хочу показать, как еще можно было производить добавление записи в базу данных. Существует несколько способов, но я обращу внимание только на так называемый Query Builder. MySQL-запрос в методе «addPost()» с ним выглядел бы так:
public function addPost($title, $post) { DB::insert('posts', array('title','post')) ->values(array($title, $post)) ->execute(); }
Query Builder удобен в частности тем, что позволяет переключаться между разными типами баз данных (из MySQL в Oracle, и т.п.)
Обновление записей я в модели не реализовал, так что можете рассматривать это как домашнее задание.
