Если вы выполнили все действия, описанные в предыдущем уроке, то теперь самое время познакомится с тем, как происходит работа с Базой Данных в Кохане. Поскольку мы сейчас создаем что-то вроде блога, то для примера создадим несколько пробных статей и выведем их на главной странице.
Таблица у нас будет пока упрощенная и состоять она будет из Идентификатора статьи, автора, даты публикации и соответственно самой статьи в виде превью (для вывода на главной странице).
CREATE TABLE IF NOT EXISTS `articles` ( `id` int(10) NOT NULL AUTO_INCREMENT COMMENT 'Идентификатор статьи', `title` varchar(250) NOT NULL COMMENT 'Название статьи', `author` varchar(100) NOT NULL COMMENT 'Автор статьи', `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Дата публикации', `content_short` text NOT NULL COMMENT 'Текст статьи', PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
Теперь заполним таблицу данными, чтобы было с чем работать:
INSERT INTO `articles` (`id`, `title`, `author`, `date`, `content_short`) VALUES (1, 'О фреймворках', 'Петя Иванов', '2012-04-01 17:20:33', 'Фреймворк - в информационных системах структура программной системы; программное обеспечение, облегчающее разработку и объединение разных компонентов большого программного проекта. В отличие от библиотек, которые объединяют набор подпрограмм близкой функциональности, фреймворк содержит в себе большое количество разных по назначению библиотек.'), (2, 'Фреймворк Yii', 'Вася Петров', '2012-04-01 17:20:33', 'Yii - это высокопроизводительный веб-фреймворк, написанный на PHP, и реализующий парадигму MVC. Yii — аббревиатура, которая расшифровывается как "Yes It Is!"'), (3, 'Фреймворк Symfony', 'Гриша Сидоров', '2012-04-01 17:23:29', 'Symfony — свободный каркас, написанный на PHP5, который использует паттерн Model-View-Controller.\r\nSymfony предлагает быструю разработку и управление веб-приложениями, позволяет легко решать рутинные задачи веб-программиста. Работает только с PHP 5. Имеет поддержку множества баз данных. Информация о реляционной базе данных в проекте должна быть связана с объектной моделью. Это можно сделать при помощи ORM инструмента. Symfony поставляется с двумя из них: Propel и Doctrine.');
Подготовительные работы закончены и пришла наконец пора создать Модель, которая будет работать с этими данными. Для этого создайте в application/classes/model файл под названием article.php со следующим содержимым:
<?php defined('SYSPATH') or die('No direct script access.'); class Model_Article extends Model { protected $_tableArticles = 'articles'; /** * Get all articles * @return array */ public function get_all() { $sql = "SELECT * FROM ". $this->_tableArticles; return DB::query(Database::SELECT, $sql) ->execute(); } }
Мы видим, что наш класс Model_Article наследует другой класс под названием Model. В начале класса мы сразу указываем, с какой таблицей будем работать, чтобы в случае изменения ее названия можно было поменять его только в одном месте. Метод get_all получает все записи из таблицы articles. Для этого внутри метода написан обычный sql-запрос, присвоен переменной и передан в метод query. Этот метод принимает следующие параметры: тип запроса в виде константы (это может быть Database::SELECT, Database::INSERT, Database::UPDATE и Database::DELETE), сам запрос, выбор вывода результата — в виде массива или объекта (по умолчанию стоит FALSE — выводить как массив) и массив с параметрами, используемыми в запросе. Ну и для выполнения запроса и получения результатов нужно в конце выполнить метод execute.
Теперь нужно изменить наш контроллер Page и обратиться в нем к свежесозданной модели. Класс контроллера будет выглядеть вот так:
<?php defined('SYSPATH') or die('No direct script access.'); class Controller_Page extends Controller_Common { // Главная страница public function action_index() { $articles = array(); $content = View::factory('/pages/show') ->bind('articles', $articles); $article = new Model_Article(); $articles = $article->get_all(); $this->template->content = $content; } } // End Page
В нем мы создаем объект класса Model_Article и вызываем его единственный метод get_all.
Можно использовать метод Фабрика и заменить эти две строки на одну (этот вариант кстати предпочтительнее):
$articles = Model::factory('Article')->get_all();
Полученный массив значений передается в блок контента посредством метода bind
А файл Вида show.php, где храниться выводимый на главной контент, станет таким:
<h3>Это главная страница</h3> <br /> <?php foreach($articles as $article): ?> <div style="padding:10px; margin-bottom:10px; border-bottom:#333 2px solid;"> <strong><?php echo $article['title']; ?></strong><br /> <i>Автор: <?php echo $article['author']; ?></i> / <i>Дата публикации: <?php echo $article['date']; ?></i><br /><br /> <p><?php echo $article['content_short']; ?></p> </div> <?php endforeach; ?>
Тут должно быть все понятно, так как это обычный перебор массива с помощью функции foreach. Все, теперь можно смотреть сайт в браузере. Получиться должно примерно следующее (кликабельно):
В следующем уроке мы немного поработаем с другими типами запросов, а также с передачей параметров в запрос. До скорых встреч.
<< Назад | Вперед >> |
Пожалуйста, зарегистрируйтесь для комментирования.
Как вы думаете, который быстрее работает, ORM или query builder?
Как я понимаю, ORM это надстройка облегчающая работу с БД, а следовательно работает более тормозно по сравнению с прямыми запросами и query builder.
вся кохановская орм построенная на query builder.
тем не менее, орм потяжелее , она каждый раз тянет список таблиц, а то это потеря скорости.
ОРМ не люблю из-за сокрости, отдаю предпочтение query builder, хотя большинство модулей юзает именно ОРМ.
какой списко таблиц?
С нетерпением жду следующий урок по БД и работе с формами.
В чем здесь ошибка?
Здесь нет ошибки.
Уже разобрался! Я в boote не раскоментил доступ к модулю базы данных!
Я вот не могу понять одной простоты в контролере, а вернее его логику:
Как на выводе получаеться переменная $articles заполнена статями, если в $articles присваеваеться результат с базы данных после
Заполнение статьями происходит посредством
$articles = $article->get_all();
А бинд — это как ссылка на результат.
Верно! Но как она ссылаеться на результат, если оно расположено выше самого формирования результата! PHP код читает же с верху в низ верно? Или так читает в процидурном коде?
Бинд используется как раз в случае, когда результат определяется ниже его передачи в вид.
Где я могу прочесть об этом Бинде? Видимо я, чтото упустил при изучении!
Плохо, что у Вас сайт не уведомляет об ответах на коментарии! ПРиходиться самому искать, что писал и смотреть! Нет ответили ли мне на вопрос!
Вкратце здесь
http://kohanaframework.su/starting/view_2
Мне комментарии приходят нормально сразу на почту.
А вообще для таких вопросов существуют форум.
Вам приходят! А нам нет!
Создаю в модели запрос
return DB::query(Database::SELECT, ‘SELECT * FROM my_category’);
В контроллер приходит вместо массива объект. Как это исправить?
Вар_дамп выдает следующее object(Database_Query)#33(7){…
А где ->execute(); ?
добавил, теперь ошибка в Виде
ErrorException [ Notice ]: Array to string conversion
APPPATH\views\widgets\w_menu.php [ 5 ]
3 foreach($categories as $cat)
4 {
5 echo ‘‘.$cat.’‘;
6 }
но вар_дамп теперь пишет чуток другое
object(Database_MySQL_Result)#36 (7)
->execute()->as_array();
теперь Модель возвращает массив в Контроллер, но вот контроллер почему те не передает его Виду
уже нашел причину. Модель передает в контроллер многомерный массив. Т.е. в Виде нужно менять код
Вар_дамп находится в контроллере
public function action_index()
{
// Получаем список категорий
$categories = Model::factory(‘category’)->categories();
var_dump($categories);
$this->template->categories = $categories;
}
Подскажите пожалуйста. При создании модели у нас есть возможность перезадать для неё имя базы данных и имя таблицы. Допустим есть модель Dealer, в ней прописываем:
protected $_db = ‘dealer’;
protected $_table_name = ‘users’;
Далее используем:
ORM::factory(‘dealer’)
->where(‘additional’,'=’, 1)
->count_all();
Можно ли перезадать в модели значение префикса таблицы? Или у нас один путь — определить в конфигурации database альтернативную базу данных и использовать её в нашей модели?
А вот интересно если class Model_Article extends Model, а class Model, насколько я понимаю extends DB, то зачем в модели использовать DB::query();? Нельзя ли там использовать $this->query();? Заранее спасибо за ответ.
Вы бы в таких случаях не спрашивали, а пробовали
Но думаю работать не будет.