Этот урок, состоящий из двух частей, познакомит вас с фреймворком
Введение
Fuel — новый PHP фреймворк, построенный специально для PHP 5.3, он использует проверенную архитектуру MVC для логического разделения кода и объединяет лучшие идеи существующих фреймворков, совершенствуя их и добавляя собственные нововведения. После девяти месяцев тяжелой разработки состоялся релиз первой версии, и у фреймворка за короткое время появилось множество последователей. Эта статья быстро научит вас создавать сайты с помощью Fuel – но для начала немного поговорим об этой архитектуре.
Понимание MVC
Архитектура MVC (eng. Model-View-Controller — Модель-Представление-Контроллер) используется многими существующими фреймворками, такими как CodeIgniter, Zend Framework, Symphony и Ruby on Rails. Если вы знакомы хотя бы с одним из них, считайте, что начало положено!
Для тех, кто плохо знаком с этой архитектурой: MVC — метод разделения кода в зависимости от того, какую роль он играет в приложении. В программе он начинается с Контроллера, загружаемого Fuel. Затем выполняется метод, который извлекает данные, используя Модель. Как только это сделано, Контроллер может решить, какое Представление загрузить. Представления содержат вывод, который увидят ваши пользователи, ответы AJAX или сообщения об ошибках.
Более подробно об MVC с точки зрения Fuel можно прочитать в
Сейчас мы объясним всё самое простое, чтобы не запутать новичков. Если всё это для вас очевидно, вы можете пропустить эту часть и перейти к более интересным моментам.
Шаг 1: Установка
Установка так же проста, как загрузка ZIP-архива с сайта. Вы также можете использовать онлайн-установку, если вы используете *nix систему, вроде Linux, Mac OS X и т.д., которая требует, чтобы был запущен Git. Установка через Git очень проста, если вы разрабатываете свои приложения:
1 |
$ curl get.fuelphp.com/oil | sh |
Установим ограниченную версию Oil — это утилиты командной строки, которые вы можете использовать при работе с приложениями Fuel. Эта версия может быть использована для создания приложений:
1 |
$ oil create blog |
Создаем в текущем каталоге папку blog
для нашего проекта, которая будет содержать основную структуру фреймворка. Если вы сталкиваетесь с какими-либо проблемами, просмотрите более
Если вы выполнили эту команду в корневом каталоге своего локального сервера, при переходе по адресу http://localhost/test/public
вы должны увидеть страницу приветствия.
Структура файлов
Каталог вашего приложения должен содержать три основных директории:
- fuel/ – Здесь будет весь ваш PHP код.
- public/ – То, что должно быть доступно непосредственно в браузере, например JS, CSS, картинки и т.д.
- oil – Исполняемая программа, которая является полной версией oil, установленной ранее, может выполнять такие консольные задачи, как генерация кода или интерактивная отладка в пределах вашего приложения. Она необязательна, вы можете удалить её, если вам не нравится работать с командной строкой.
В каталоге fuel/
у нас несколько важных папок:
- app/ – Здесь располагается весь PHP код, определяемый программой, включая Модели, Представления и Контроллеры.
- core/ – Здесь находится сам Fuel. Если вы используете Git, это будет субмодулем, который можно легко обновить.
- packages/ – Fuel выделяет определённую логику в пакеты, чтобы не раздувать ядро. По умолчанию в Fuel входят три пакета: oil, auth и ORM. Эти пакеты не будут загружены без специального запроса, поэтому об этом мы поговорим позже.
Далее наиболее важна папка app/
:
- config/ – Здесь расположены файлы конфигурации для различных классов и основной файл
config.php
. - classes/ – Здесь идут все Контроллеры, Модели, вспомогательные классы, библиотеки бизнес-логики и т.д. Если нужно написать класс, который будет использован в коде, он, вероятно, будет помещён сюда. Все названия должны быть в нижнем регистре.
- classes/controller/ – Здесь располагаются Контроллеры.
- classes/model/ – Место расположения ваших моделей, хотя в сущности они являются обыкновенными классами.
- views/ – Сюда можно поместить свои файлы представлений. Файлы можно размещать как в этом каталоге, так и в его подкаталогах. Ограничений имён нет.
Прежде чем перейти к теории, давайте напишем небольшой код.
Шаг 2: Hello World
Давайте удалим контроллер fuel/app/classes/controller/welcome.php
и создадим свой собственный, под названием hello.php
.
В этот файл добавьте следующий код:
1 2 3 4 5 6 7 |
class Controller_Hello extends Controller { public function action_index() { echo "Hello World!"; } } |
Теперь если вы перейдёте к http://localhost/test/public/index.php/hello
, вы должны увидеть “Hello World!” в своём браузере. Префикс action
говорит нам, что это маршрутизируемый, а не открытый метод, т.е. вы можете использовать имена методов, типа “list,” не запутывая PHP.
Если мы хотим, чтобы этот контроллер приветствия стал нашим “root” контроллером, вместо welcome.php
, как сейчас, нам просто нужно открыть fuel/app/config/routes.php
и изменить маршрут _root_
вот так:
1 2 3 |
return array( '_root_' => 'hello', // The default route ); |
Ваше первое представление
Создайте файл fuel/app/views/hello.php
и добавьте в него:
1 2 |
<h1>Hello!</h1> <p>Hey <?php echo $name ?>, how's it going?</p> |
Затем немного измените свой контроллер:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
class Controller_Hello extends Controller { public function action_index() { echo "Hello World!"; } public function action_buddy($name = 'buddy') { $this->response->body = View::factory('hello', array( 'name' => $name, ); } } |
Сейчас, если вы загрузите http://localhost/test/public/index.php/hello/buddy
или http://localhost/test/public/index.php/hello/buddy/John
, вы увидите переменную $name
переданную представлению от метода. Фактически extract()
выполняется в представлении.
Шаг 3: Базовая конфигурация
Как видите, Fuel может работать с базовыми Контроллерами/Представлениями из коробки, но если нам нужно что-то большее, придётся произвести некоторые изменения базовой конфигурации. Для начала откройте fuel/app/config/config.php
и внесите небольшие правки:
1 2 3 4 5 6 |
/** * index_file - The name of the main bootstrap file. * * Set this to false or remove if you using mod_rewrite. */ 'index_file' => 'index.php', |
Если у вас установлен mod_rewrite
, вы можете установить в качестве значения пустую строку, это позволит нам удалить index.php
из нашего URL. В public/
есть .htaccess файл, который будет это поддерживать.
Далее нам нужно настроить конфигурацию базы данных, для данного урока мы использовали MySQL. Создайте свою базу данных со своим настольным GUI, phpMyAdmin и т.п.:
1 |
mysql> create database blog_example; |
Откройте fuel/app/config/db.php
и установите массив Fuel::DEVELOPMENT
следующим образом:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
Fuel::DEVELOPMENT => array( 'type' => 'mysql', 'connection' => array( 'hostname' => 'localhost', 'database' => 'blog_example', 'username' => 'yourmyseluser', 'password' => 'yourmysqlpassword', 'persistent' => false, ), 'table_prefix' => '', 'charset' => 'utf8', 'caching' => false, 'profiling' => false, ), |
Затем активируем пакеты ORM
и auth
, раскомментировав следующие строки:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
/** * These packages are loaded on Fuel's startup. You can specify them in * the following manner: * * array('auth'); // This will assume the packages are in <code>PKGPATH</code> * * // Use this format to specify the path to the package explicitly * array( * array('auth' => PKGPATH.'auth/') * ); */ 'packages' => array( 'orm', 'auth', ), |
Этот шаг нужен только если вы будете использовать эти пакеты – как в нашем случае.
Дополнительно: Использование виртуального хоста
Последний шаг установки — создание виртуального хоста. Вам не обязательно это делать, но так вы можете использовать реальный URL и удалить из URL /public/
. Если вы используете Apache, вам потребуется вот этот код:
1 2 3 4 5 6 7 8 9 |
<VirtualHost 127.0.0.1> DocumentRoot /home/phil/Sites/blog/public ServerName local.blog <Directory /home/phil/Sites/blog> Options All AllowOverride All </Directory> </VirtualHost> |
Если бы это был живой, рабочий сайт, мы бы добавили ServerName вроде “myawesomeblog.com” вместо “local.blog”, но это только для демо. Как только вы добавите “127.0.0.1 local.blog” в свой файл
/etc/hosts
, хост должен заработать. Это необязательно, поэтому данный шаг можно пропустить.
Шаг 4: Начало разработки
С пониманием того, как работают Контроллеры, Представления и Конфигурации, вы могли бы окунуться в документацию и довольно быстро начать разработку, но сначала лучше познакомиться со Скаффолдингом.
Скаффолдинг (eng. Scaffolding) — это не новое понятие, наиболее известное по фреймворку Ruby on Rails. По существу, это очень простой способ сгенерировать код на основе нескольких спецификаций через командную строку. Т.е. если вам нужно добавить, отредактировать или удалить объект, который вы называете, и для которого предоставляете поля, это делается через oil и подкоманду oil generate scaffold
Так, если мы хотим создать блог, нам нужно написать только $ oil g scaffold post title:string summary:varchar[250] body:text
. Oil будет очень подробно описывать, что она делает и предоставит нам список всех созданных файлов:
1 2 3 4 5 6 7 8 9 |
Creating model: /home/phil/Sites/blog/fuel/app/classes/model/post.php Creating migration: /home/phil/Sites/blog/fuel/app/migrations/001_create_posts.php Creating controller: /home/phil/Sites/blog/fuel/app/classes/controller/posts.php Creating view: /home/phil/Sites/blogfuel/app/views/posts/index.php Creating view: /home/phil/Sites/blog/fuel/app/views/posts/view.php Creating view: /home/phil/Sites/blog/fuel/app/views/posts/create.php Creating view: /home/phil/Sites/blog/fuel/app/views/posts/edit.php Creating view: /home/phil/Sites/blog/fuel/app/views/posts/_form.php Creating view: /home/phil/Sites/blog/fuel/app/views/template.php |
Примечание: Модели, сгенерированные посредством скаффолдинга, используют пакет ORM, поэтому убедитесь, что он активирован, как показано выше.
Здесь вы видите модель под названием post
, миграцию (об этом мы будем говорить ниже), контроллер posts
и группу представлений. Все поля сгенерированы на основе предоставленных параметров, т.е. fieldname:fieldtype[optional-length]
. Для title
, мы использовали параметр :string
который, пока вы используете MySQL, будет псевдонимом :varchar[255]
, но поддерживается любой тип БД.
С этой командой мы должны выполнить свои миграции. Миграция — это серия изменений, которая должна быть произведена в базе данных. Это полезно, когда множество разработчиков работают над проектом, поскольку каждый разработчик может добавить миграцию, и вам нужно будет выполнить только одну команду, чтобы убедиться, что ваша локальная копия актуальна. Больше не будет ошибок типа “missing field’ или “table does not exist” после установки последней разработанной копии!
Чтобы выполнить эту миграцию, просто введите:
1 2 |
$ oil refine migrate Migrated to latest version: 1. |
Теперь вы можете посмотреть, что сделала Oil, перейдя к </code>
<img src="https://2web-master.ru/wp-content/uploads/2012/04/scaffolding.png" alt="" title="scaffolding" />
Если вы хотите создать контроллеры, модели и миграции отдельно, а не всё вместе, как здесь, вы можете это сделать также легко с помощью <code>oil g controller, oil g migrate
, oil g model
и т.д.
Шаблоны
Вы возможно обратили внимание, что в шаге выше Oil создала файл:
1 |
Creating view: /home/phil/Sites/blog/fuel/app/views/template.php |
Он будет создаваться, когда вы впервые выполняете команду скаффолдинга, поскольку все представления обёрнуты в шаблон с шапкой, футером и боковой панелью. Всё, что вам нужно сделать, чтобы изменить стандартный дизайн, это отредактировать этот шаблон, включить свои файлы CSS, добавить логотип и ввести любые метаданные, которые вам нужны.
Когда вы создаёте новые контроллеры вручную, вы можете расширить Controller_Template
вместо обычного Controller
, чтобы Представления, загружаемые в контроллере оборачивались в этот шаблон.
Если вы хотите использовать другой шаблон для контроллера, просто измените значение свойства $template
.
1 2 3 |
class Users extends Controller_Template { public $template = 'alternative'; } |
В этом случае будет использоваться файл представления fuel/app/views/alternative.php
вместо обычного fuel/app/views/template.php
.
Работа с формами
Один из самых важных аспектов любого приложения — это представление форм. Так информация передаётся программе от пользователя; это может быть вход, комментарий, управление корзиной и т.д. Всё это обычно делается на HTML, но Fuel предоставляет нам несколько полезных методов, чтобы сделать этот процесс намного проще. Они дополнительны, так, если вы фанат HTML, вы можете работать вручную, но если вы хотите ускорить свою работу, читайте:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<?php echo Form::open(); ?> <p> <?php echo Form::label('Title', 'title'); ?> <?php echo Form::input('title', Input::post('title', isset($post) ? $post->title : '')); ?> </p> <p> <?php echo Form::label('Summary', 'summary'); ?> <?php echo Form::input('summary', Input::post('summary', isset($post) ? $post->summary : '')); ?> </p> <p> <?php echo Form::label('Body', 'body'); ?> <?php echo Form::textarea('body', Input::post('body', isset($post) ? $post->body : ''), array('cols' => 60, 'rows' => 8)); ?> </p> <div class="actions"> <?php echo Form::submit(); ?> </div> <?php echo Form::close(); ?> |
Это очень простая форма, которая будет работать как с create
, так и с edit
. Для каждого поля, она может найти соответствие в POST
и будет использовать его; в противном случае, она будет искать переменную $post
и вводить значение (хорошо для редактирования).
Реальная выгода подобного решения заключается не в более чистом синтаксисе, как можно было подумать, а в том, что это позволяет фреймворку программно оборачивать вашу форму. Это означает, что Fuel может автоматически внедрить атрибуты во все формы, чтобы удостовериться, что данные отправляются в правильной кодировке и предотвратить CSRF
(eng. Cross-Site Request Forgery — Межсайтовая Подделка Запроса).
Проверка форм
Проверка — простой способ гарантировать, что определённая информация была предоставлена в форме правильным образом. Она может проводиться на основе определённых шаблонов, типов данных или условий и поможет улучшить целостность данных.
По умолчанию проверка не используется скаффолдингом, потому что трудно предположить, с какими именно данными будет работать разработчик. По этой причине валидация — дополнительная возможность, но её легко добавить в ваши контроллеры вручную.
Давайте посмотрим, как метод Create Post
может выглядеть в нашем блоге:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
public function action_create($id = null) { if (Input::method() == 'POST') { $val = Validation::factory(); // Добавляем поле для заголовка, даём ему метку "Title" и делаем его обязательным $val->add('title', 'Title') ->add_rule('required'); // Теперь добавляем другое поле для краткого описания и указываем, что оно должно содержать не менее 10 и не более 250 символов $val->add('summary', 'Summary') ->add_rule('required') ->add_rule('min_length', 10) ->add_rule('max_length', 250); $val->add('body', 'Article body') ->add_rule('required'); if ($val->run()) { // Создаём пост на основе ввода (массива) $post = Model_Post::factory($val->validated()); // Проверяем и сохраняем его if ($post->save()) { Session::set_flash('notice', 'Added post #' . $post->id . '.'); } else { Session::set_flash('notice', 'Could not save post.'); } Response::redirect('posts'); } else { $this->template->set('error', $val->errors()); } } $this->template->title = "Posts"; $this->template->content = View::factory('posts/create'); } |
Здесь мы говорим классу Validation
(который автоматически загружен, как и все классы), о каких полях мы заботимся. Затем мы назначаем правила и даём им метки, чтобы люди могли их читать. Если значение $val->run()
true
, мы создаём новый экземпляр класса Model_Post
, используя factory, и отправляем $val->validated()
, где содержится массив всех подтверждённых данных. Так мы можем просто сохранить экземпляр класса, который использует ORM, чтобы сделать всю работу.
Если хотя бы одно из правил проверки возвратит false
, то $val->run()
прекратиться и мы получим массив ошибок в $val->errors()
, который мы возвратим пользователю.
Используя свои знания проверки и создания форм, вы можете начинать создавать любые приложения основанные на Контроллерах, какие захотите.
Работа с задачами
Задачи похожи на контроллеры, но к ним нельзя обратиться через URL или какой-либо маршрут. Вместо этого, они выполняются через подкоманду oil refine
. Задачи в основном применяются для создания интерактивных сценариев командного процессора, имеющих доступ к вашей кодовой странице, или в качестве задачи cron.
Некоторые фреймворки предлагают вам использовать wget
, curl
или что-то подобное, чтобы запустить контроллер, выполняющий задачи cron, но это потенциально может вызвать проблемы безопасности или последовательности и привести к нежелательным результатам. Если использовать данный способ, задачи полностью защищены от внешнего воздействия.
Для примера, посмотрите на предоставленную задачу robots
в fuel/app/tasks/robots.php
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
class Robots { public static function run($speech = null) { if ( ! isset($speech)) { $speech = 'KILL ALL HUMANS!'; } $eye = \Cli::color("*", 'red'); return \Cli::color(" \"{$speech}\" _____ / /_____\\", 'blue')."\n" .\Cli::color(" ____[\\", 'blue').$eye.\Cli::color('---', 'blue').$eye.\Cli::color('/]____', 'blue')."\n" .\Cli::color(" /\\ #\\ \\_____/ /# /\\ / \\# \\_.---._/ #/ \\ / /|\\ | | /|\\ \\ /___/ | | | | | | \\___\\ | | | | |---| | | | | |__| \\_| |_#_| |_/ |__| //\\\\ <\\ _//^\\\\_ /> //\\\\ \\||/ |\\//// \\\\\\\\/| \\||/ | | | | |---| |---| |---| |---| | | | | |___| |___| / \\ / \\ |_____| |_____| |HHHHH| |HHHHH|", 'blue'); } } |
Чтобы выполнить эту остроумную задачу, просто введите oil r robots
или oil r robots 'Kill all Mice'
, чтобы заставить робота сказать что-то ещё.
Подведём итоги
Если вы следовали каждому шагу, описанному здесь, вы установили Fuel, узнали, где располагаются важные файлы, сконфигурировали базовую установку для работы Apache с mod_rewrite
(другие серверы работают также хорошо), и создали простые контроллеры и представления, использующие формы и проверки. Если использовать для генерации кода скаффолдинг, у вас должно быть много кода, на котором можно учиться!
Сейчас у вас достаточно знаний, чтобы поиграть с этим фреймворком и создать несложные приложения, – т.е. до Второй части этой серии, где мы рассмотрим процесс создания и расширения Базовых Контроллеров для разделения внутреннего/внешнего интерфейса. Также мы рассмотрим продвинутый ORM, драйверы аутентификации и загрузки файлов.
Интересно было прочитать.
Ничего личного, но мне все равно Zend больше нравиться. = )
Добрый день. Спасибо за статью! Вы бы не могли рассказать как вылаживать fuelphp на реальный хостинг?
Хорошая статья, но... Собственно, ГДЕ ВТОРАЯ ЧАСТЬ?!
Определять правила валидации в контроллере??? Спасибо, не надо. Валидация данных — это модель и только модель.