Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР 151, АВГУСТ 2011 г.

Web-приложения с турбонаддувом: Фреймворк Kohana + шаблон проектирования MVC = love

Прошли те времена, когда было модно разрабатывать webприложения, состоящие из одного сценария, по уши напичканного кодом. На дворе 2011 год, и уже как-то несолидно придерживаться столь консервативных идей. Время двигаться вперед и отдавать предпочтение современным методам разработки — применению Content Management Framework. Сегодня я познакомлю тебя с одним из лучших представителей современных CMF.

Что такое фреймворк?

Content Management Framework (CMF) — набор инструментов для разработки систем управления контентом (Content Management System). В отличие от CMS, фреймворки (в большинстве случаев) не готовы к работе сразу, поскольку они представляют собой лишь отдельные кирпичики. Задача разработчика — набраться сил и сложить из этих материалов полноценное приложение. CMS — это тоже своего рода «кубики», но они готовы к работе из коробки и вполне могут функционировать без доработки кода.

Три главных плюса CMF

Если от фреймворков не было особой пользы, то никто бы не решился использовать их в своих проектах — жизнь современного разработчика и так достаточно тяжела. Из наиболее ощутимых плюсов CMF можно выделить:

  1. Оптимизированный код. Над фреймворками трудятся разработчики, уделяющие оптимизации достаточно много времени.
  2. Скажи «нет» велосипедам. Как правило, в фреймворке уже имеются готовые решения для типичных задач. Тут тебе и структура папок, и вспомогательные библиотеки, и куча всяких вкусностей. Многие вещи изначально готовы к работе и позволяют разработчику сразу приступить к разработке функционала приложения, не развлекаясь написанием кучи рутинного кода.
  3. Упрощенная командная работа. Если проект разрабатывается целой командой, то применение CMF (особенно популярного) дает ощутимый плюс при появлении в команде новенького. Ему будет проще включиться в проект, так как для этого необходимо ознакомиться с CMF, по которому наверняка написано множество статей и мануалов.

Святая троица: модель, представление, контроллер

Всех разработчиков условно можно разделить на две большие группы — «гангстеры» и «законопослушные граждане». Первые не придерживаются никаких стандартов и хорошо зарекомендовавших себя решений, а делают все наобум. Они не думают ни о каких шаблонах проектирования, а просто лепят код. В большинстве случаев такие программисты не способны заниматься большими проектами.

«Грабануть поезд» (в смысле, сорвать небольшой куш, написав простенькое приложение) — это всегда пожалуйста. Сделают быстро и без лишнего шума. А вот с крупными делами у них возникают проблемы. Для проектов, ТЗ которых содержит фразу «должен быть масштабируем», такие «специалисты» не годятся, поскольку наколбасить кучу кода в одном модуле и забыть в таких проектах не получится. Тут нужен определенный подход и максимальное разделение кода.

За годы развития языков программирования были созданы различные методики — паттерны («шаблоны») проектирования ПО. Одним из таких паттернов и является Model-View-Controller. Я бы даже сказал, что сегодня это, наверное, самый популярный шаблон.

Не буду ходить вокруг да около, а сразу перейду к сути. Если ты знаком с этим паттерном, то следующий раздел статьи можешь пропустить и перейти сразу к практике. Ну а тем, кто не в курсе, настоятельно рекомендую уделить время теории, поскольку при разработке на Kohana тебе в обязательном порядке придется придерживаться шаблона MVC.

Контроллер

Контроллер в MVC выполняет роль некоего диспетчерарегулировщика. Он не должен изменять или добавлять данные, производить расчеты и т.д. Его цель — обслуживать поступающие запросы и на каждый такой запрос соответствующим образом отвечать. Например, пользователь обращается к главной странице сайта нашего журнала — http://xakep.ru. Его запрос в первую очередь получает определенный контроллер (если рассматривать на примере шаблона MVC). После получения запроса он выполняет действие, забинденное на данный тип запроса. Причем сам контроллер ни в коем случае не должен содержать код для выборки данных и т.д. Сама выборка должна быть организована в модели.

Модель

В модели описывается вся бизнес-логика приложения. Выборки, модификация данных, расчеты — все это должно выполняться в модели, к которой и будет обращаться контроллер. Причем все сгенерированные в модели данные не должны содержать разметку. Только данные в сыром виде и ничего больше.

Представление

Последний компонент архитектуры MVC — представление. Этот элемент отвечает за вывод данных в нужном виде. Именно во вьюшках (сленговое название представления) и должна быть вся разметка. Несомненно, в них также может содержаться и программный код, отвечающий сугубо за вывод данных, полученных от контроллера. Но никакой бизнес-логики там быть не может.Перспективы и плюсы использования MVC очевидны.

Помимо решения банальной задачи вроде отделения бизнес-логики от интерфейса ты автоматически получаешь возможность комфортной командной разработки. Одни разработчики могут заниматься совершенствованием моделей, другие — готовить представления и т.д.

This is Kohana

Kohana — это бесплатный фреймворк с открытым исходным кодом. В качестве шаблона проектирования, как ты уже и догадался, в Kohana применяется паттерн — Model View Controller.

Kohana полностью объектно-ориентирована и использует в полной мере возможности последних версий интерпретатора PHP. В отличие от многих бесплатных продуктов с открытыми сорцами, Kohana распространяется под лицензией BSD, а не GPL. Это подразумевает, что ты можешь применять данный продукт совершенно бесплатно как в личных, так и в коммерческих проектах.

Ставим Kohana

Для начала прогуляйся до официального сайта и загрузи последнюю версию фреймворка. Загруженный архив закачай к себе на хост и извлеки его содержимое. Попробуй обратиться к директории своего хоста, в которую ты извлек фреймворк и… — приготовься к облому. Наверняка ты не пройдешь Environment Tests (тест окружения).

В моем случае тесты на запись в директорию хранения кэша и логов тоже завершились неудачей. Для исправления ситуации нужно всего лишь выставить права на запись для этих директорий. В общем, выставляй права и пробуй обновить страницу. В случае успеха увидишь текст: «Your environment passed all requirements. Remove or rename the install.php file now». Помимо радостного известия о готовности окружения для работы фреймворка, текст сообщения требует от тебя удаления файла install.php. Не будем брыкаться и выполним эту пустяковую просьбу. Удалив инсталляционный сценарий, попробуй обновить страницу. Если ты все сделал правильно, то браузер выплюнет девственно чистую страницу с текстом «hello, world».

Hello world на Kohana

Перед тем как перейти к рассмотрению полезного примерчика, попробуем наколбасить собственный «Hello world». Создадим новый текстовый файл и напишем в нем следующий текст:

<?php defi ned('SYSPATH') or die('No direct script access.');
class Controller_Test extends Controller {
public function action_index()
{
$this->response->body('Hello world! Hello, everyone!!!');
}
}

В этом клочке кода я описываю наш первый контроллер — класс Controller_Test, унаследованный от Controller. Обрати внимание на имя класса. В имени содержится Controller (обязательный префикс), а после него идет непосредственно название контроллера. Его мы пишем с большой буквы. В моем случае именем контроллера является Test. Контроллеры и модели должны храниться в директории App/ classes/controller и App/classes/model.

Создаем первую модель

Пробный контроллер у нас есть, теперь посмотрим, как описываются модели. Сначала рассмотрим вариант модели, которой не требуется взаимодействие с базой данных. Например, представим, что нам нужно определить модель myFirstModel:

class Model_myFirstModel extends Model
{
public function calcIt (a, b) {
return a + b;
}
}

В этой модели я объявил всего один метод — calcIt(). Он выполняет операцию сложения над переданными в качестве параметра переменными. Увы, если требуется работать с базой данных, то модель такого вида не прокатит. Все модели, предназначенные для взаимодействия с СУБД, должны наследоваться от Model_Database. Например, нам требуется написать модель, в которой предусмотрена возможность выборки данных из таблицы users. Такая модель будет выглядеть примерно так:

class Model_myFirstDBModel extends Database_Model
{
public function selectData() {
return $this -> db -> query('select userName,
pass from users');
}
}

Делаем первое представление

Ты знаешь, что представления в архитектуре MVC предназначены для отображения сгенерированного контента. Модель получает данные в сыром виде и возвращает их контроллеру, а тот, в свою очередь, должен передать их представлению. Уже во вьюшке создается красивая обертка, готовая к выводу пользователю.

Все созданные представления должны храниться в папке views, расположенной в директории твоего приложения. По умолчанию директорией приложения является Application. Создавать представления чрезвычайно просто. Ради эксперимента попробуем создать представление about. Его код будет выглядеть примерно так:

<html>
<head>
<title><?php echo $title ?></title>
</head>

Я специально не стал приводить остальную часть кода, так как там может присутствовать абсолютно любой html-код. Нас интересует только то, что расположено между тегами <title>. Там я отправляю на «печать» значение одноименной переменной. Получается, что заголовок страницы будет устанавливаться извне — из контроллера.

Теперь посмотрим на обновленный код ранее рассмотренного нами контроллера:

$about_page = View::factory('about');
$about_page -> title = 'Это страница about';
$this -> response -> body ($about_page);

В первой строке я связываю переменную about_page с представлением about. Для этого я использую конструкцию View::factory. Далее я устанавливаю переменную title и вывожу само представление.

Хостинг изображений

Я долго думал насчет примера для сегодняшней статьи. Обычно при обзоре фреймворков пишут блог или другое типичное webприложение. Признаюсь честно, сначала я так и сделал — набросал блог с простой системой авторизации пользователей, админкой и т.д. Но потом подумал (вообще-то это я тебя насильственно переубедил :) — прим. ред.), что это скучно и решил сделать что-нибудь поинтересней. В итоге придумал рассмотреть такое приложение, как хостинг изображений. Таких проектов в инете пруд пруди, и несмотря на многообразие выбора, каждый имеет свою аудиторию.

Я понимаю, что для более-менее реального личного хостинга изображений нужно несколько гигабайт места. На обычном виртуальном хостинге получить их дороговато, а раз так, то и пользы от такого хостинга будет мало. И тут я подумал, а почему бы не заюзать в качестве хранилища отдельный аккаунт известного всем Dropbox? По умолчанию каждый акк позволяет хранить 2 гигабайта стаффа, но его без особых проблем реально прокачать до восьми. А вот восемь гиг вполне хватит для использования в личных целях. Немного покумекав и в очередной раз задержав статью, я набросал небольшой проект. Я не стал сильно извращаться, а реализовал лишь:

  • Удобную загрузку изображений. На большинстве опробованных мной хостингах изображений для отправки файлов требовалось выбрать нужный файл при помощи стандартного диалога открытия файлов. Это не очень удобно, тем более, возможности HTML5 легко и просто помогают реализовать Drag&Drop-интерфейс и считать файл с компа пользователя при помощи FileAPI.
  • Передачу файлов в DropBox. Для хранения файлов я выбрал предопределенную директорию public. Все хранящиеся в ней файлы могут быть расшарены для других пользователей. Dropbox автоматически генерит к ним ссылки. Именно эта ссылка и будет использоваться для передачи клиенту. Да, конечный адресок получается длинноватым, но при желании его можно укоротить. Сервисы для укорачивания ссылок тебе в помощь.

Внутренности проекта

Увы, привести полные листинги проекта в статье я не могу, поскольку кода (особенно оформления) достаточно много. Здесь я лишь поясню основные ключевые моменты. Итак, начнем разбор с контроллеров. Для проекта мне потребовался один контроллер, одно представление и одна модель. В контроллере я объявил два методасобытия. Первое возникает, когда пользователь обращается к основной странице, а второе — в случае успешной загрузки изображения на сервер (генерируется страница со ссылкой на файл).

Первое представление — самое простое. По факту, это — страница с небольшим полем, на которое нужно перетаскивать файлы. Код страницы прост до безобразия:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Демонстрация работы CMF Kohana для ][акера</title>
<link href="style.css" rel="stylesheet" type="text/css" />
<script src="html5uploader.js"></script>
</head>
<body onload="new uploader('drop', 'status', 'uploader.php',
'list');">
<div id="box">
<div id="status">Перетащи на меня файл</div>
<div id="drop"></div>
</div>
<div id="list"></div>
</body>
</html>

В коде я определяю простенькую разметку и подключаю готовую библиотеку html5uploader. В этой JS-библиотеке уже реализовано все необходимое для создания красивой html5-страницы для передачи файлов на сервер. Для передачи файла достаточно забиндить на событие onload создание экземпляра объекта uploader. В конструктор объекта необходимо передать следующие параметры:

  1. id блока, на который пользователь будет выполнять перенос изображений;
  2. id блока для вывода статусных сообщений;
  3. путь к сценарию, выполняющий передачу файлов от клиента на сервер;
  4. id блока для вывода списка загруженных файлов.

Последний параметр можно не заполнять. Обрати внимание, к данному html-файлу я прилинковал style.css. В нем содержится описание стилей. Если ты попытаешься повторить пример, то обязательно копирни css-файл, иначе твоя страница так и останется девственно чистой.

Теперь посмотрим, как работать с Dropbox. Как всегда есть два варианта. Первый — гиковский. Думаю, ты уже догадался, что придется все писать самостоятельно. Второй проще и правильней — воспользоваться готовым модулем. Пока таких модулей не очень много. Для себя я выбрал самый простенький, который так и называется — DropboxUploader. Ссылку на его загрузку ты найдешь в конце статьи.

Модуль представляет собой класс с одним полезным методом — upload. Передача файлов в аккаунт DropBox’а выполняется следующим образом:

$uploader = new DropboxUploader('твой_логин', 'твой_пароль');
$uploader->upload('файл для загрузки', 'папка назначения');

Поскольку я решил загружать все файлы в папку public, то в качестве второго параметра мне требуется передать — /pupblic. Если необходимо загружать файлы прямо в корень аккаунта, то указывай просто слэш — '/'.

Код приемки файла на стороне сервера выглядит следующим образом:

if(count($_FILES)>0)
{
$uploader = new DropboxUploader('login', 'pass');
$uploader->upload(
$upload_folder.'/'.$_FILES['upload']['name'],
$dropbox_folder);
if(move_uploaded_fi le($_FILES['upload']['tmp_name'],
$upload_folder.'/'.$_FILES['upload']['name'] ) )
{
echo 'done';
$uploader = new DropboxUploader('login', 'pass');
$uploader->upload(
$upload_folder.'/'.$_FILES['upload']['name'],
$dropbox_folder);
}
exit();
}
...

Здесь я привел код считывания файла с использованием глобального массива $_FILES. С ним очень удобно и просто работать, но стоит помнить об одном маленьком условии — браузер клиента обязан поддерживать метод передачи файлов — sendAsBinary(). В противном случае тебе придется самостоятельно декодировать полученные данные из base64 (если они были закодированы именно этим алгоритмом). Я реализовал оба варианта. Второй ты можешь посмотреть в моем исходнике.

Заключение

Фреймворки существенно облегчают процесс разработки webприложений и прививают разработчику «культуру разработки», помогают писать более красивый и правильный код. Рассмотренная Kohana обладает весьма привлекательными возможностями и уже из коробки содержит готовые решения для типичных задач. Попробуй начать использовать Kohana в реальных проектах. Уверен, ты прочувствуешь ее мощь и гибкость и уже не захочешь возвращаться на голый php. На этом кланяюсь и желаю тебе удачи. Как обычно, все свои вопросы можешь кидать на мыло.

Что почитать

  • http://goo.gl/sRjoo — моя большая статья про CodeIgniter. Kohana берет свое начало именно с этого проекта. Несмотря на крутизну Kohana, иногда не грех воспользоваться и CodeIgniter’ом. К тому же, разработчики вроде бы опять возобновили разработку.
  • http://kohanaframework.org/ — официальный сайт проекта Kohana. Здесь ты найдешь сам фреймворк, а также всевозможную документацию и примеры использования. После прочтения статьи рекомендую сразу посетить этот ресурс.
  • http://vr-online.ru — всегда свежие статьи по программированию. В плане CMF, ресурс может похвастаться наличием статей по CodeIgniter, Drupal и т.д.
  • http://kerkness.ca/wiki/doku.php — хорошая неофициальная документация по Kohana.
Содержание
загрузка...
Журнал Хакер #151Журнал Хакер #150Журнал Хакер #149Журнал Хакер #148Журнал Хакер #147Журнал Хакер #146Журнал Хакер #145Журнал Хакер #144Журнал Хакер #143Журнал Хакер #142Журнал Хакер #141Журнал Хакер #140Журнал Хакер #139Журнал Хакер #138Журнал Хакер #137Журнал Хакер #136Журнал Хакер #135Журнал Хакер #134Журнал Хакер #133Журнал Хакер #132Журнал Хакер #131Журнал Хакер #130Журнал Хакер #129Журнал Хакер #128Журнал Хакер #127Журнал Хакер #126Журнал Хакер #125Журнал Хакер #124Журнал Хакер #123Журнал Хакер #122Журнал Хакер #121Журнал Хакер #120Журнал Хакер #119Журнал Хакер #118Журнал Хакер #117Журнал Хакер #116Журнал Хакер #115Журнал Хакер #114Журнал Хакер #113Журнал Хакер #112Журнал Хакер #111Журнал Хакер #110Журнал Хакер #109Журнал Хакер #108Журнал Хакер #107Журнал Хакер #106Журнал Хакер #105Журнал Хакер #104Журнал Хакер #103Журнал Хакер #102Журнал Хакер #101Журнал Хакер #100Журнал Хакер #099Журнал Хакер #098Журнал Хакер #097Журнал Хакер #096Журнал Хакер #095Журнал Хакер #094Журнал Хакер #093Журнал Хакер #092Журнал Хакер #091Журнал Хакер #090Журнал Хакер #089Журнал Хакер #088Журнал Хакер #087Журнал Хакер #086Журнал Хакер #085Журнал Хакер #084Журнал Хакер #083Журнал Хакер #082Журнал Хакер #081Журнал Хакер #080Журнал Хакер #079Журнал Хакер #078Журнал Хакер #077Журнал Хакер #076Журнал Хакер #075Журнал Хакер #074Журнал Хакер #073Журнал Хакер #072Журнал Хакер #071Журнал Хакер #070Журнал Хакер #069Журнал Хакер #068Журнал Хакер #067Журнал Хакер #066Журнал Хакер #065Журнал Хакер #064Журнал Хакер #063Журнал Хакер #062Журнал Хакер #061Журнал Хакер #060Журнал Хакер #059Журнал Хакер #058Журнал Хакер #057Журнал Хакер #056Журнал Хакер #055Журнал Хакер #054Журнал Хакер #053Журнал Хакер #052Журнал Хакер #051Журнал Хакер #050Журнал Хакер #049Журнал Хакер #048Журнал Хакер #047Журнал Хакер #046Журнал Хакер #045Журнал Хакер #044Журнал Хакер #043Журнал Хакер #042Журнал Хакер #041Журнал Хакер #040Журнал Хакер #039Журнал Хакер #038Журнал Хакер #037Журнал Хакер #036Журнал Хакер #035Журнал Хакер #034Журнал Хакер #033Журнал Хакер #032Журнал Хакер #031Журнал Хакер #030Журнал Хакер #029Журнал Хакер #028Журнал Хакер #027Журнал Хакер #026Журнал Хакер #025Журнал Хакер #024Журнал Хакер #023Журнал Хакер #022Журнал Хакер #021Журнал Хакер #020Журнал Хакер #019Журнал Хакер #018Журнал Хакер #017Журнал Хакер #016Журнал Хакер #015Журнал Хакер #014Журнал Хакер #013Журнал Хакер #012Журнал Хакер #011Журнал Хакер #010Журнал Хакер #009Журнал Хакер #008Журнал Хакер #007Журнал Хакер #006Журнал Хакер #005Журнал Хакер #004Журнал Хакер #003Журнал Хакер #002Журнал Хакер #001