Pull to refresh

Знакомство с Kohana 3.0 — Часть 4

Reading time7 min
Views9.9K
Original author: http://www.dealtaker.com/blog/2010/02/01/kohana-php-3-0-ko3-tutorial-part-4/
Встречайте четвертую часть цикла статей по разработке с Kohana PHP V3 (KO3). редыдущие части можно найти по метке "знакомство с kohana 3.0". В этот раз речь пойдет о работе с моделями.

Определение модели возьмем из документации 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, и т.п.)

Обновление записей я в модели не реализовал, так что можете рассматривать это как домашнее задание.
Tags:
Hubs:
+5
Comments22

Articles