В цьому посібнику ми створимо програму з простою реєстраційною формою, розкриваючи основні аспекти дизайну Phalcon.
Цей посібник охоплює реалізацію простого MVC додатку, показуючи, як швидко і легко це можна зробити за допомогою Phalcon. Після розробки ви можете скористатися цим додатком і розширити його для задоволення ваших потреб. Код в цьому посібнику також може використовуватися як майданчик для вивчення інших понять та ідей Phalcon. <iframe width="560" height="315" src="https://www.youtube.com/embed/75W-emM4wNQ" frameborder="0" allowfullscreen></iframe>
Якщо ви хочете просто почати роботу, ви можете пропустити це і створити проект Phalcon автоматично за допомогою наших інструментів розробника.
Найкращий спосіб використовувати цей посібник - вникнути в основи та спробувати насолодитись процесом. Ви можете отримати повний код тут. Якщо ви зіткнулися з труднощами або маєте запитання, будь ласка звертайтеся до нас у Discord чи напишіть нам на нашому форумі.
Однією з головних особливостей Phalcon є слабка зв’язаність. Через це ви можете використати будь-яку структуру каталогів, яка вам зручна. У цьому посібнику ми будемо використовувати стандартну структуру каталогів, що зазвичай використовується в MVC застосунках.
.
└── tutorial
├── app
│ ├── controllers
│ │ ├── IndexController.php
│ │ └── SignupController.php
│ ├── models
│ │ └── Users.php
│ └── views
└── public
├── css
├── img
├── index.php
└── js
ПРИМІТКА: Оскільки весь код, який пропонує Phalcon, зібрано у розширенні (яке ви завантажили на вашому веб-сервері), ви не побачите папку
vendor
, яка містить код Phalcon. Все, що вам потрібно, знаходиться в пам’яті. Якщо Ви ще не встановили розширення, перейдіть на сторінку установка і завершіть встановлення перед тим, як продовжувати виконувати вказівки цього посібника.
Якщо це все абсолютно нове для вас, рекомендується також встановити Phalcon Devtools. DevTools доповнює вбудований веб-сервер PHP, що дозволяє вам запустити ваш продукт майже миттєво. Якщо ви виберете цю опцію, то вам знадобиться файл .htrouter.php
в кореневому каталозі вашого проекту з наступним змістом:
<?php
$uri = urldecode(
parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)
);
if ($uri !== '/' && file_exists(__DIR__ . '/public' . $uri)) {
return false;
}
$_GET['_url'] = $_SERVER['REQUEST_URI'];
require_once __DIR__ . '/public/index.php';
У випадку цього посібника цей файл повинен знаходитися в каталозі tutorial
.
Ви також можете використовувати nginX, apache, cherokee або інші веб-сервери. Ви можете відвідати сторінку налаштування веб-сервера для отримання інструкцій.
Перший файл, який потрібно створити - це файл bootstrap. Цей файл працює як вхідна точка і базова конфігурація для вашого продукту. У цьому файлі можна реалізувати ініціалізацію компонентів, а також визначити поведінку програми.
Цей файл виконує три завдання:
Ми збираємося використовувати Phalcon\Loader як PSR-4 сумісний завантажувач файлів. Загальні речі, які слід додати до автозавантажувача, це ваші контролери і моделі. Ви також можете зареєструвати каталоги, які будуть проскановані для пошуку файлів, необхідних вашій програмі.
Для початку, давайте зареєструємо каталоги контролерів
нашої програми і моделей
, за допомогою Phalcon\Loader:
public/index.php
<?php
use Phalcon\Loader;
define('BASE_PATH', dirname(__DIR__));
define('APP_PATH', BASE_PATH . '/app');
// ...
$loader = new Loader();
$loader->registerDirs(
[
APP_PATH . '/controllers/',
APP_PATH . '/models/',
]
);
$loader->register();
Оскільки Phalcon є слабко зв’язаним, сервіси реєструються в менеджері залежностей фреймворка, тому вони можуть бути автоматично вставлені в компоненти і послуги, загорнуті в IoC контейнер. Часто ви стикатиметесь з терміном DI, який означає впровадження залежностей (Dependency Injection). Впровадження залежностей та Інверсія контролю (IoC) можуть звучати складно, але Phalcon гарантує, що їх використання є простим, практичним та ефективним. Контейнер IoC Phalcon містить такі концепції:
Кожен раз, коли фреймворк потребує компонента або послугу, він буде звертатися до контейнера використовуючи певне ім’я сервісу. Таким чином, ми маємо простий спосіб отримання об’єктів, необхідних для нашої програми, таких як логер, з’єднання бази даних і тощо.
ПРИМІТКА: Якщо вас цікавлять деталі, то ознайомтесь із статтею Мартіна Фавлера. Також ми маємо чудовий посібник, що охоплює багато випадків використання.
Phalcon\Di\FactoryDefault є варіантом Phalcon\Di. Щоб спростити роботу, він автоматично зареєструє більшість компонентів, що необхідні для продукту та стандартно поставляється з Phalcon. Хоч і рекомендується налаштовувати служби вручну, ви можете використовувати Phalcon\Di\FactoryDefault спочатку та пізніше налаштувати його відповідно до ваших потреб.
Сервіси можуть бути зареєстровані кількома способами, але для нашого посібника, ми будемо використовувати анонімну функцію:
public/index.php
<?php
use Phalcon\Di\FactoryDefault;
// Create a DI
$container = new FactoryDefault();
Тепер нам потрібно зареєструвати службу view, встановивши каталог, де фреймворк знайде файли подання. Оскільки представлення не належать до класів, вони не можуть бути автоматично завантажені нашим автозавантажувачем.
public/index.php
<?php
use Phalcon\Mvc\View;
// ...
$container->set(
'view',
function () {
$view = new View();
$view->setViewsDir(APP_PATH . '/views/');
return $view;
}
);
Тепер нам потрібно зареєструвати базову URI, яка надасть можливість створення всіх URL-адрес за допомогою Phalcon. Цей компонент буде гарантувати, що якщо ви запускатимете програму через верхній каталог або підкаталог, всі ваші URI будуть правильними. Для цього навчального посібника наш базовий шлях є /
. Це матиме значення пізніше у цьому посібнику, коли ми використовуватимемо клас Phalcon\Tag
для генерування гіперпосилань.
public/index.php
<?php
use Phalcon\Url;
// ...
$container->set(
'url',
function () {
$url = new Url();
$url->setBaseUri('/');
return $url;
}
);
Для того, щоб обробляти будь-які запити, використовуєтьс об’єкт Phalcon\Mvc\Application, який виконує всі самі важкі завдання. Цей компонент прийме запит користувача, визначить шляхи, скоординує дії контролера та виведе візуальне подання результатів обробки запиту.
public/index.php
<?php
use Phalcon\Mvc\Application;
// ...
$application = new Application($container);
$response = $application->handle(
$_SERVER["REQUEST_URI"]
);
$response->send();
Файл tutorial/public/index.php
повинен виглядати так:
public/index.php
<?php
use Phalcon\Di\FactoryDefault;
use Phalcon\Loader;
use Phalcon\Mvc\View;
use Phalcon\Mvc\Application;
use Phalcon\Url;
// Визначимо деякі константи абсолютних шляхів, щоб забезпечити визначення розташування ресурсів
define('BASE_PATH', dirname(__DIR__));
define('APP_PATH', BASE_PATH . '/app');
// Реєструємо автозавантажувач
$loader = new Loader();
$loader->registerDirs(
[
APP_PATH . '/controllers/',
APP_PATH . '/models/',
]
);
$loader->register();
$container = new FactoryDefault();
$container->set(
'view',
function () {
$view = new View();
$view->setViewsDir(APP_PATH . '/views/');
return $view;
}
);
$container->set(
'url',
function () {
$url = new Url();
$url->setBaseUri('/');
return $url;
}
);
$application = new Application($container);
try {
// Опрацьовуємо запити
$response = $application->handle(
$_SERVER["REQUEST_URI"]
);
$response->send();
} catch (\Exception $e) {
echo 'Exception: ', $e->getMessage();
}
Як ви бачите, файл bootstrap дуже короткий і нам не потрібно включати до нього будь-які додаткові файли. Ви маєте змогу створити гнучкий MVC додаток менш ніж за 30 рядків коду.
За замовчуванням Phalcon буде шукати контролер з назвою IndexController
. Це початкова точка, коли в запиті не було додано жодного контролера чи дії (наприклад, https://localhost/
). IndexController
та його IndexAction
повинен бути схожим на такий приклад:
app/controllers/IndexController.php
<?php
use Phalcon\Mvc\Controller;
class IndexController extends Controller
{
public function indexAction()
{
return '<h1>Привіт!</h1>';
}
}
Класи контролера повинні містити суфікс Controller
, а дії контролера повинні мати суфікс Action
. Для отримання додаткової інформації ви можете прочитати наш документ про контролери. Якщо ви спробуєте отримати досту до вашого продукта через браузер, то побачите щось на зразок цього:
Вітаємо, ви літаєте із Phalcon!
Виведення результату на екран безпосередньо з контролера часом потрібне, але не бажане, і це підтвердять більшість пуристів MVC спільноти. Всі результати мають передаватись компоненту view, який відповідальний за виведення інформації на екран. Phalcon шукатиме view з такою ж назвою, як і остання виконана дія, в папці з ім’ям контролера, якому така дія належить.
Таким чином, у нашому випадку якщо URL-адреса:
http://localhost/
буде викликано IndexController
і indexAction
, який буде шукати подання:
/views/index/index.phtml
Якщо такий файл існує, його буде зчитано і виведено результат на екран. Наш view в такому разі матиме вміст:
app/views/index/index.phtml
<?php echo "<h1>Привіт!</h1>";
і оскільки ми перемістили echo
з нашої дії контролера у подання, то дія буде порожньою:
app/controllers/IndexController.php
<?php
use Phalcon\Mvc\Controller;
class IndexController extends Controller
{
public function indexAction()
{
}
}
Виведена браузером інформація не зміниться. Компонент Phalcon\Mvc\View
автоматично створюється по завершенню виконання дії. Інформацію про подання у Phalcon ви можете почитати тут.
Тепер ми змінимо файл подання index.phtml
, щоб додати посилання на новий контролер з назвою signup. Мета - дозволити користувачам зареєструватися у нашому додатку.
app/views/index/index.phtml
<?php
echo "<h1>Привіт!</h1>";
echo PHP_EOL;
echo PHP_EOL;
echo $this->tag->linkTo(
'signup',
'Зареєструватись тут!'
);
Згенерований HTML код показує посилання (`<a></code), що веде до нового контролера:</p>
tag->textField("name"); ?>
tag->textField("email"); ?>
tag->submitButton("Зареєструватися"); ?>
app/views/index/index.phtml` (зчитано)
```html
Привіт!
Зареєструватись тут!
```
Для створення посилання для тегу ``, ми використовуємо компонент [Phalcon\Tag](tag). Це допоміжний інструмент, який пропонує простий спосіб побудови HTML-тегів з урахуванням правил фреймворку. Цей клас також є сервісом, зареєстрованим у Dependency Injector, тому ми можемо використовувати `$this->tag` для доступу до його функціональності.
> **ПРИМІТКА**: `Phalcon\Tag` вже зареєстрований у контейнері DI, оскільки ми використали `Phalcon\Di\FactoryDefault`. Якщо ви вирішили реєструвати усі сервіси самостійно, то потрібно зареєструвати у цьому контейнері кожен такий сервіс, щоб зробити його доступним у вашому продукті.
{: .alert .alert-info }
Компонент [Phalcon\Tag](tag) також використовує раніше зареєстрований [Phalcon\Uri](uri) компонент для правильного створення URI. Більш детальну статтю стосовно генерування HTML [можна знайти тут](tag).

А контролер реєстрації - (`app/controllers/SignupController.php`):
`app/controllers/SignupController.php`
```php
Зареєструйтесь, використовуючи цю форму
tag->form("signup/register"); ?>
"
. implode('
', $user->getMessages());
}
// передача повідомлення поданню
$this->view->message = $message;
}
}
```
На початку `registerAction` ми створили порожній об'єкт користувача, використовуючи клас користувачів `Users`, який ми створили раніше. Ми будемо використовувати цей клас для керування записами користувача. Як було зазначено вище, публічні властивості класу ведуть до полів таблиці `users` у нашій базі даних. Вставлення відповідних значень до нового запису і виклик `save()` збереже дані цього запису у базі даних. Метод `save()` повертає значення `boolean`, яке сигналізує про успіх чи невдачу операції збереження.
ORM автоматично обріже записи, аби уникнути SQL ін'єкцій, тому нам потрібно лише передати запит методу `save()`.
Додаткова перевірка відбувається автоматично в усіх полях, що визначені як не null (обов’язкові). Якщо ми не заповнимо жодного з обов'язкових полів у реєстраційній формі, наш екран виглядатиме схоже на це:

## Список зареєстрованих користувачів
Тепер нам потрібно буде відобразити всіх зареєстрованих користувачів у нашій базі даних
Перше, що ми зробимо в `indexAction` контролера `IndexController` - це показати результат пошуку всіх користувачів, що робиться просто шляхом виклику статичного методу `find()` в нашій моделі (`Users::find()`).
`indexAction` буде змінено так:
`app/controllers/IndexController.php`
```php
view->users = Users::find();
}
}
```
> **ПРИМІТКА**: Ми присвоюємо результат операції `find` магічній властивості об'єкта `view`. Це вставляє у цю змінну присвоєні їй дані та робить їх доступними у нашому поданні
{: .alert .alert-info }
У нашому файлі подання `views/index/index.phtml` ми можемо використовувати змінну `$users` так:
Ураховуючи все вищезазначене, наше подання виглядатиме приблизно так:
`views/index/index.phtml`
```html
Привіт!";
echo $this->tag->linkTo(["signup", "Зареєструватися!", 'class' => 'btn btn-primary']);
if ($users->count() > 0) {
?>
N п/п
Ім'я
Email
Кількість користувачів: count(); ?>
id; ?>
name; ?>
email; ?>