Урок 1: Научимся на примере
В этом первом уроке мы подробно рассмотрим создание приложения с простой формой регистрации с нуля. Мы также объясним основные аспекты поведения фреймворка. Если вас интересуют инструменты автоматической генерации кода для Phalcon, вы можете ознакомиться с нашими инструментами разработчика.
Проверка вашей установки
Мы будем исходить из того, что Phalcon у вас уже установлен. Проверьте вывод phpinfo() на наличие раздела, содержащего «Phalcon», или выполните фрагмент кода ниже:
<?php print_r(get_loaded_extensions()); ?>
Расширение Phalcon должно отображаться в выводе:
Array
(
[0] => Core
[1] => libxml
[2] => filter
[3] => SPL
[4] => standard
[5] => phalcon
[6] => pdo_mysql
)
Создание проекта
Лучший способ использовать это руководство — следовать каждой инструкции по очереди. Полный код вы можете получить здесь.
Структура файлов
Phalcon не навязывает определённой структуры файлов для разработки приложений. Ввиду его слабой связанности, вы можете реализовывать приложения, работающие на Phalcon, используя структуру файлов, наиболее удобную для вас.
Для целей этого учебника и в качестве отправной точки мы рекомендуем следующую структуру:
tutorial/
app/
controllers/
models/
views/
public/
css/
img/
js/
Обратите внимание, что вам не нужен каталог «library», связанный с Phalcon. Фреймворк доступен в памяти и готов к использованию.
Красивые URL-адреса
В этом учебнике мы будем использовать красивые (дружественные) URL-адреса. Дружественные URL-адреса лучше подходят для SEO и легче запоминаются пользователями. Phalcon поддерживает модули переписывания, предоставляемые наиболее популярными веб-серверами. Делать URL-адреса вашего приложения дружественными не является обязательным, и вы можете так же легко разрабатывать без них.
В этом примере мы будем использовать модуль переписывания для Apache. Создадим несколько правил переписывания в файле /tutorial/.htaccess:
#/tutorial/.htaccess
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^$ public/ [L]
RewriteRule (.*) public/$1 [L]
</IfModule>
Все запросы к проекту будут переписываться в каталог public/, что сделает его корневым каталогом документации. Этот шаг гарантирует, что внутренние каталоги проекта останутся скрытыми от публичного просмотра, тем самым исключая угрозы безопасности такого рода.
Вторая группа правил проверит, существует ли запрашиваемый файл, и если да, то его не нужно будет переписывать модулем веб-сервера:
#/tutorial/public/.htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?_url=/$1 [QSA,L]
</IfModule>
Bootstrap
Первый файл, который вам необходимо создать, — это файл bootstrap. Этот файл очень важен; так как он служит основой вашего приложения, предоставляя вам контроль над всеми его аспектами. В этом файле вы можете реализовать инициализацию компонентов, а также поведение приложения.
Файл tutorial/public/index.php должен выглядеть следующим образом:
try {
//Register an autoloader
$loader = new \Phalcon\Loader();
$loader->registerDirs(array(
'../app/controllers/',
'../app/models/'
))->register();
//Create a DI
$di = new Phalcon\DI\FactoryDefault();
//Setup the view component
$di->set('view', function(){
$view = new \Phalcon\Mvc\View();
$view->setViewsDir('../app/views/');
return $view;
});
//Setup a base URI so that all generated URIs include the "tutorial" folder
$di->set('url', function(){
$url = new \Phalcon\Mvc\Url();
$url->setBaseUri('/tutorial/');
return $url;
});
//Handle the request
$application = new \Phalcon\Mvc\Application($di);
echo $application->handle()->getContent();
} catch(\Phalcon\Exception $e) {
echo "PhalconException: ", $e->getMessage();
}
Автозагрузчики
Первая часть, которую мы находим в bootstrap, — регистрация автозагрузчика. Он будет использоваться для загрузки классов, таких как контроллеры и модели, в приложении. Например, мы можем зарегистрировать один или несколько каталогов контроллеров, повышая гибкость приложения. В нашем примере мы использовали компонент Phalcon\Loader.
С его помощью мы можем загружать классы, используя различные стратегии, но для этого примера мы выбрали поиск классов на основе предопределённых каталогов:
$loader = new \Phalcon\Loader();
$loader->registerDirs(
array(
'../app/controllers/',
'../app/models/'
)
)->register();
Управление зависимостями
Очень важным концептом, который необходимо понять при работе с Phalcon, является его контейнер инъекции зависимостей. Звучит сложно, но на самом деле очень просто и практично.
Контейнер сервисов — это мешок, где мы глобально храним сервисы, которые будет использовать наше приложение для работы. Каждый раз, когда фреймворк требует компонент, он будет обращаться к контейнеру, используя согласованное имя для сервиса. Поскольку Phalcon — это высокодетализированный фреймворк, Phalcon\DI действует как клей, облегчая интеграцию различных компонентов, обеспечивая их совместную работу прозрачным образом.
//Create a DI $di = new Phalcon\DI\FactoryDefault();
Phalcon\DI\FactoryDefault — это разновидность Phalcon\DI. Для упрощения, в нём зарегистрированы большинство компонентов, поставляемых с Phalcon. Таким образом, мы не должны регистрировать их по одному. Позже не возникнет проблем с заменой сервиса фабрики.
В следующей части мы регистрируем сервис «view», указав каталог, где фреймворк будет находить файлы представлений. Поскольку представления не соответствуют классам, их нельзя загружать с помощью автозагрузчика.
Сервисы можно регистрировать различными способами, но для нашего учебника мы воспользуемся анонимной функцией:
//Setup the view component
$di->set('view', function(){
$view = new \Phalcon\Mvc\View();
$view->setViewsDir('../app/views/');
return $view;
});
Далее мы регистрируем базовый URI, чтобы все URI, генерируемые Phalcon, включали папку «tutorial», которую мы настроили ранее. Это станет важным позже в этом учебнике, когда мы будем использовать класс Phalcon\Tag для генерации гиперссылки.
//Setup a base URI so that all generated URIs include the "tutorial" folder
$di->set('url', function(){
$url = new \Phalcon\Mvc\Url();
$url->setBaseUri('/tutorial/');
return $url;
});
В последней части этого файла мы находим Phalcon\Mvc\Application. Его цель — инициализировать среду запроса, маршрутизировать входящий запрос и затем передать любые обнаруженные действия; он агрегирует любые ответы и возвращает их по завершении процесса.
$application = new \Phalcon\Mvc\Application($di); echo $application->handle()->getContent();
Как видите, файл bootstrap очень короткий и нам не нужно включать дополнительные файлы. Мы создали гибкое MVC-приложение менее чем за 30 строк кода.
Создание контроллера
По умолчанию Phalcon будет искать контроллер с именем «Index». Это отправная точка, когда в запросе не указан ни контроллер, ни действие. Контроллер index (app/controllers/IndexController.php) выглядит так:
class IndexController extends \Phalcon\Mvc\Controller
{
public function indexAction()
{
echo "<h1>Hello!</h1>";
}
}
Классы контроллеров должны иметь суффикс «Controller», а действия контроллеров — суффикс «Action». Если вы откроете приложение в браузере, вы увидите примерно следующее:
Поздравляем, вы летите с Phalcon!
Вывод данных в представление
Иногда необходимо передавать данные на экран из контроллера, но это нежелательно, как утверждают многие приверженцы MVC. Всё должно передаваться в представление, которое отвечает за вывод данных на экран. Phalcon будет искать представление с таким же именем, что и последнее выполненное действие, внутри каталога с именем последнего выполненного контроллера. В нашем случае (app/views/index/index.phtml):
echo "<h1>Hello!</h1>";
Наш контроллер (app/controllers/IndexController.php) теперь имеет пустое определение действия:
class IndexController extends \Phalcon\Mvc\Controller
{
public function indexAction()
{
}
}
Вывод браузера должен остаться прежним. Статический компонент Phalcon\Mvc\View автоматически создаётся по завершении выполнения действия. Подробнее о использовании представлений здесь.
Создание формы регистрации
Теперь мы изменим файл представления index.phtml, чтобы добавить ссылку на новый контроллер с именем «signup». Цель — позволить пользователям регистрироваться в нашем приложении.
echo "<h1>Hello!</h1>";
echo Phalcon\Tag::linkTo("signup", "Sign Up Here!");
Сгенерированный HTML-код отображает анкерный тег («a») HTML, который ссылается на новый контроллер:
<h1>Hello!</h1> <a href="/tutorial/signup">Sign Up Here!</a>
Для генерации тега мы используем класс Phalcon\Tag. Это утилитарный класс, который позволяет создавать HTML-теги, учитывая соглашения фреймворка. Более подробную статью о генерации HTML можно найти здесь.
Вот контроллер Signup (app/controllers/SignupController.php):
class SignupController extends \Phalcon\Mvc\Controller
{
public function indexAction()
{
}
}
Пустое действие index предоставляет чистый путь к представлению с определением формы (app/views/signup/index.phtml):
<?php use Phalcon\Tag; ?>
<h2>Sign up using this form</h2>
<?php echo Tag::form("signup/register"); ?>
<p>
<label for="name">Name</label>
<?php echo Tag::textField("name") ?>
</p>
<p>
<label for="email">E-Mail</label>
<?php echo Tag::textField("email") ?>
</p>
<p>
<?php echo Tag::submitButton("Register") ?>
</p>
</form>
Просмотр формы в браузере покажет примерно следующее:
Phalcon\Tag также предоставляет полезные методы для создания элементов форм.
Метод Phalcon\Tag::form принимает, например, только один параметр — относительный URI контроллера/действия в приложении.
При нажатии на кнопку «Отправить» вы заметите исключение, выброшенное фреймворком, указывающее, что нам не хватает действия «register» в контроллере «signup». Файл public/index.php выбросит это исключение:
PhalconException: Действие «register» не найдено в контроллере «signup»
Реализация этого метода устранит исключение:
class SignupController extends \Phalcon\Mvc\Controller
{
public function indexAction()
{
}
public function registerAction()
{
}
}
Если вы снова нажмёте кнопку «Отправить», вы увидите пустую страницу. Введённые пользователем имя и электронная почта должны быть сохранены в базе данных. В соответствии с принципами MVC, взаимодействие с базой данных должно выполняться через модели, чтобы обеспечить чистый объектно-ориентированный код.
Создание модели
Phalcon предоставляет первый ORM для PHP, полностью написанный на языке C. Вместо увеличения сложности разработки, он её упрощает.
Прежде чем создать нашу первую модель, нам нужно создать таблицу базы данных вне Phalcon, чтобы сопоставить её. Простую таблицу для хранения зарегистрированных пользователей можно определить следующим образом:
CREATE TABLE `users` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(70) NOT NULL, `email` varchar(70) NOT NULL, PRIMARY KEY (`id`) );
Модель должна находиться в каталоге app/models (app/models/Users.php). Модель сопоставляется с таблицей «users»:
class Users extends \Phalcon\Mvc\Model
{
}
Установка подключения к базе данных
Чтобы иметь возможность использовать подключение к базе данных и впоследствии получать доступ к данным через наши модели, нам нужно указать его в процессе загрузки. Подключение к базе данных — это просто ещё один сервис нашего приложения, который может использоваться несколькими компонентами:
try {
//Register an autoloader
$loader = new \Phalcon\Loader();
$loader->registerDirs(array(
'../app/controllers/',
'../app/models/'
))->register();
//Create a DI
$di = new Phalcon\DI\FactoryDefault();
//Setup the database service
$di->set('db', function(){
return new \Phalcon\Db\Adapter\Pdo\Mysql(array(
"host" => "localhost",
"username" => "root",
"password" => "secret",
"dbname" => "test_db"
));
});
//Setup the view component
$di->set('view', function(){
$view = new \Phalcon\Mvc\View();
$view->setViewsDir('../app/views/');
return $view;
});
//Setup a base URI so that all generated URIs include the "tutorial" folder
$di->set('url', function(){
$url = new \Phalcon\Mvc\Url();
$url->setBaseUri('/tutorial/');
return $url;
});
//Handle the request
$application = new \Phalcon\Mvc\Application($di);
echo $application->handle()->getContent();
} catch(Exception $e) {
echo "PhalconException: ", $e->getMessage();
}
С правильными параметрами базы данных наши модели готовы к работе и взаимодействию с остальной частью приложения.
Хранение данных с использованием моделей
Приём данных из формы и их хранение в таблице — следующий шаг.
class SignupController extends \Phalcon\Mvc\Controller
{
public function indexAction()
{
}
public function registerAction()
{
$user = new Users();
//Store and check for errors
$success = $user->save($this->request->getPost(), array('name', 'email'));
if ($success) {
echo "Thanks for registering!";
} else {
echo "Sorry, the following problems were generated: ";
foreach ($user->getMessages() as $message) {
echo $message->getMessage(), "<br/>";
}
}
$this->view->disable();
}
}
Затем мы создаём экземпляр класса Users, который соответствует записи пользователя. Общедоступные свойства класса сопоставляются с полями записи в таблице users. Установка соответствующих значений в новой записи и вызов save() сохранит данные в базе данных для этой записи. Метод save() возвращает логическое значение, которое указывает, было ли сохранение данных успешным или нет.
ORM автоматически экранирует входные данные, предотвращая SQL-инъекции, поэтому нам нужно только передать запрос в метод save.
Дополнительная валидация автоматически выполняется для полей, определённых как не NULL (обязательные). Если мы не введём ни одного из обязательных полей в форме регистрации, наш экран будет выглядеть так:
Заключение
Это очень простой учебник, и как вы видите, легко начать создание приложения с помощью Phalcon. Тот факт, что Phalcon — это расширение вашего веб-сервера, не повлиял на простоту разработки или доступные функции. Мы приглашаем вас продолжить чтение руководства, чтобы открыть для себя дополнительные функции, предлагаемые Phalcon!
Примеры приложений
Также доступны следующие приложения, разработанные на базе Phalcon, предоставляющие более полные примеры:
- Приложение INVO: Приложение для генерации счетов. Позволяет управлять продуктами, компаниями, типами продуктов и т. д.
- Альтернативный сайт на PHP: Приложение с мультиязычной поддержкой и расширенной маршрутизацией
- Альбом O’Rama: Демонстрация музыкальных альбомов, обработка больших наборов данных с помощью PHQL и использованием Volt в качестве шаблонизатора
- Phosphorum: Простой и чистый форум
© 2011–2016 Phalcon Framework Team
Licensed under the Creative Commons Attribution License 3.0.
https://docs.phalconphp.com/en/2.0.0/reference/tutorial.html