Учебник 1: Научимся на примере
В этом первом учебнике мы покажем вам, как создать приложение с простой формой регистрации с нуля. Мы также объясним основные аспекты поведения фреймворка. Если вас интересуют инструменты автоматической генерации кода для Phalcon, вы можете ознакомиться с нашими инструментами разработчика.
Лучший способ использовать это руководство — следовать каждой инструкции по порядку. Полный код вы можете получить здесь.
Структура файлов
Phalcon не накладывает определённой структуры файлов для разработки приложений. Из-за слабой связанности вы можете реализовать приложения, работающие на Phalcon, с структурой файлов, которая вам удобнее всего.
Для целей этого учебника и в качестве отправной точки мы предлагаем очень простую структуру:
tutorial/
app/
controllers/
models/
views/
public/
css/
img/
js/
Обратите внимание, что вам не нужен каталог «library», связанный с Phalcon. Фреймворк доступен в памяти и готов к использованию.
Прежде чем продолжить, убедитесь, что вы успешно установили Phalcon и настроили либо Nginx, либо Apache, либо Cherokee.
Инициализация
Первый файл, который вам нужно создать, — файл инициализации. Этот файл очень важен, так как он служит основой вашего приложения, позволяя вам контролировать все его аспекты. В этом файле вы можете реализовать инициализацию компонентов и поведение приложения.
В конечном счёте, он отвечает за три вещи:
- Настройка автозагрузчика.
- Настройка контейнера зависимостей.
- Обработка запроса приложения.
Автозагрузчики
Первой частью в файле инициализации является регистрация автозагрузчика. Он будет использоваться для загрузки классов, таких как контроллеры и модели в приложении. Например, мы можем зарегистрировать один или несколько каталогов контроллеров, повышая гибкость приложения. В нашем примере мы использовали компонент Phalcon\Loader.
С его помощью мы можем загружать классы, используя различные стратегии, но для этого примера мы выбрали поиск классов в предопределённых каталогах:
use Phalcon\Loader;
// ...
$loader = new Loader();
$loader->registerDirs(
[
"../app/controllers/",
"../app/models/",
]
);
$loader->register();
Управление зависимостями
Очень важным понятием при работе с Phalcon является его контейнер инъекции зависимостей. Звучит сложно, но на самом деле очень просто и практично.
Контейнер сервисов — это пакет, где мы глобально храним сервисы, которые будет использовать наше приложение для работы. Каждый раз, когда фреймворк требует компонент, он обращается к контейнеру, используя согласованное имя сервиса. Поскольку Phalcon — это высокодетализированный фреймворк, Phalcon\Di выступает в роли связующего звена, облегчая интеграцию различных компонентов, обеспечивая их совместную работу прозрачным образом.
use Phalcon\Di\FactoryDefault; // ... // Create a DI $di = new FactoryDefault();
Phalcon\Di\FactoryDefault — это вариант Phalcon\Di. Для упрощения, он зарегистрировал большинство компонентов, которые поставляются с Phalcon. Таким образом, мы не должны регистрировать их по одному. Позже не возникнет проблем с заменой сервиса фабрики.
В следующей части мы регистрируем сервис «view», указав каталог, где фреймворк найдёт файлы представлений. Поскольку представления не соответствуют классам, их нельзя загружать с помощью автозагрузчика.
Сервисы можно регистрировать различными способами, но для нашего учебника мы будем использовать анонимную функцию:
use Phalcon\Mvc\View;
// ...
// Setup the view component
$di->set(
"view",
function () {
$view = new View();
$view->setViewsDir("../app/views/");
return $view;
}
);
Далее мы регистрируем базовый URI, чтобы все URI, генерируемые Phalcon, включали папку «tutorial», которую мы создали ранее. Это станет важным позже в этом учебнике, когда мы будем использовать класс Phalcon\Tag для генерации гиперссылок.
use Phalcon\Mvc\Url as UrlProvider;
// ...
// Setup a base URI so that all generated URIs include the "tutorial" folder
$di->set(
"url",
function () {
$url = new UrlProvider();
$url->setBaseUri("/tutorial/");
return $url;
}
);
Обработка запроса приложения
В последней части этого файла мы находим Phalcon\Mvc\Application. Его задача — инициализировать среду запроса, маршрутизировать входящий запрос и затем передать любые обнаруженные действия; он агрегирует любые ответы и возвращает их по завершении процесса.
use Phalcon\Mvc\Application; // ... $application = new Application($di); $response = $application->handle(); $response->send();
Объединение всего вместе
Файл tutorial/public/index.php должен выглядеть так:
use Phalcon\Loader;
use Phalcon\Mvc\View;
use Phalcon\Mvc\Application;
use Phalcon\Di\FactoryDefault;
use Phalcon\Mvc\Url as UrlProvider;
use Phalcon\Db\Adapter\Pdo\Mysql as DbAdapter;
// Register an autoloader
$loader = new Loader();
$loader->registerDirs(
[
"../app/controllers/",
"../app/models/",
]
);
$loader->register();
// Create a DI
$di = new FactoryDefault();
// Setup the view component
$di->set(
"view",
function () {
$view = new 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 UrlProvider();
$url->setBaseUri("/tutorial/");
return $url;
}
);
$application = new Application($di);
try {
// Handle the request
$response = $application->handle();
$response->send();
} catch (\Exception $e) {
echo "Exception: ", $e->getMessage();
}
Как видите, файл инициализации очень короткий и нам не нужно включать какие-либо дополнительные файлы. Мы создали гибкое MVC-приложение менее чем в 30 строках кода.
Создание контроллера
По умолчанию Phalcon будет искать контроллер под названием «Index». Это отправная точка, когда в запросе не указан контроллер или действие. Контроллер index (app/controllers/IndexController.php) выглядит следующим образом:
use Phalcon\Mvc\Controller;
class IndexController extends 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) теперь имеет пустое определение действия:
use Phalcon\Mvc\Controller;
class IndexController extends Controller
{
public function indexAction()
{
}
}
Вывод браузера должен остаться прежним. Статический компонент Phalcon\Mvc\View автоматически создаётся после завершения выполнения действия. Подробнее об использовании представлений здесь.
Проектирование формы регистрации
Теперь мы изменим файл представления index.phtml, чтобы добавить ссылку на новый контроллер под названием «signup». Цель — позволить пользователям регистрироваться в нашем приложении.
echo "<h1>Hello!</h1>";
echo PHP_EOL;
echo PHP_EOL;
echo $this->tag->linkTo(
"signup",
"Sign Up Here!"
);
Сгенерированный HTML-код отображает ссылку («a») HTML-тега, которая ссылается на новый контроллер:
<h1>Hello!</h1> <a href="/tutorial/signup">Sign Up Here!</a>
Для генерации тега мы используем класс Phalcon\Tag. Это утилитарный класс, который позволяет нам создавать HTML-теги, учитывая соглашения фреймворка. Поскольку этот класс также является зарегистрированным сервисом в DI, мы используем $this->tag для доступа к нему.
Более подробную статью о генерации HTML можно найти здесь.
Вот контроллер Signup (app/controllers/SignupController.php):
use Phalcon\Mvc\Controller;
class SignupController extends Controller
{
public function indexAction()
{
}
}
Пустое действие index предоставляет прямой доступ к представлению с определением формы (app/views/signup/index.phtml):
<h2>
Sign up using this form
</h2>
<?php echo $this->tag->form("signup/register"); ?>
<p>
<label for="name">
Name
</label>
<?php echo $this->tag->textField("name"); ?>
</p>
<p>
<label for="email">
E-Mail
</label>
<?php echo $this->tag->textField("email"); ?>
</p>
<p>
<?php echo $this->tag->submitButton("Register"); ?>
</p>
</form>
Просмотр формы в вашем браузере покажет что-то вроде этого:
Phalcon\Tag также предоставляет полезные методы для создания элементов формы.
Метод Phalcon\Tag::form() принимает только один параметр, например, относительный URI контроллера/действия в приложении.
При нажатии кнопки «Отправить» вы заметите исключение, выброшенное фреймворком, указывающее, что нам не хватает действия «register» в контроллере «signup». Наш файл public/index.php выбросит это исключение:
Исключение: Действие «register» не найдено в обработчике «signup»
Реализация этого метода устранит исключение:
use Phalcon\Mvc\Controller;
class SignupController extends 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»:
use Phalcon\Mvc\Model;
class Users extends Model
{
public $id;
public $name;
public $email;
}
Настройка подключения к базе данных
Чтобы иметь возможность использовать подключение к базе данных и затем получать доступ к данным через наши модели, нам нужно указать его в процессе инициализации. Подключение к базе данных — это всего лишь ещё один сервис, который наше приложение может использовать для различных компонентов:
use Phalcon\Db\Adapter\Pdo\Mysql as DbAdapter;
// Setup the database service
$di->set(
"db",
function () {
return new DbAdapter(
[
"host" => "localhost",
"username" => "root",
"password" => "secret",
"dbname" => "test_db",
]
);
}
);
С правильными параметрами базы данных наши модели готовы работать и взаимодействовать с остальной частью приложения.
Сохранение данных с помощью моделей
Следующий шаг — получение данных из формы и сохранение их в таблице.
use Phalcon\Mvc\Controller;
class SignupController extends Controller
{
public function indexAction()
{
}
public function registerAction()
{
$user = new Users();
// Store and check for errors
$success = $user->save(
$this->request->getPost(),
[
"name",
"email",
]
);
if ($success) {
echo "Thanks for registering!";
} else {
echo "Sorry, the following problems were generated: ";
$messages = $user->getMessages();
foreach ($messages as $message) {
echo $message->getMessage(), "<br/>";
}
}
$this->view->disable();
}
}
Затем мы создаём экземпляр класса Users, который соответствует записи User. Открытые свойства класса сопоставляются с полями записи в таблице users. Установка соответствующих значений в новой записи и вызов save() сохранит данные в базе данных для этой записи. Метод save() возвращает логическое значение, которое указывает, было ли успешным сохранение данных или нет.
ORM автоматически экранирует входные данные, предотвращая SQL-инъекции, поэтому нам нужно только передать запрос в метод %%%CODE_BLOCK_23%%.
Дополнительная проверка происходит автоматически для полей, определённых как обязательные. Если мы не введём какие-либо обязательные поля в форму регистрации, наш экран будет выглядеть так:
Заключение
Это очень простой учебник, и как вы видите, легко начать создавать приложение с использованием Phalcon. Тот факт, что Phalcon является расширением вашего веб-сервера, не повлиял на простоту разработки или доступные функции. Мы приглашаем вас продолжить чтение руководства, чтобы открыть для себя дополнительные функции, предлагаемые Phalcon!
© 2011–2017 Phalcon Framework Team
Licensed under the Creative Commons Attribution License 3.0.
https://docs.phalconphp.com/en/latest/reference/tutorial.html