Мы рады объявить о релизе новой версии Phalcon.
Прошло чуть больше двух месяцев с момента выпуска предыдущей версии, и команда разработчиков представляет один из самых больших и серьёзных релизов быстрейшего фреймворка для PHP написанного как Си-расширение.
Новая версия содержит множество новых функций, исправлений ошибок и оптимизаций. Мы также обновили сайт и готовимся к большим обновлениям документации и описания API.
Нововведения Phalcon 1.2.0:
- Динамические пути для скомпилированных шаблонов Volt
- Расширение возможностей Volt
- Ссылки для статичных и динамических путей в PhalconMvcUrl
- PhalconMvcViewSimple
- Улучшена работа с JSON
- Поддержка Many-To-Many в ORM
- Работа с виртуальными внешними ключами
- Минификация Javascript и CSS
- Запрет переменных (литералов) в PHQL
- Расширены возможности Partials
- Использование PhalconTag как сервиса
- Макросы в Volt
- BadMethodCallException вместо предупреждений
- Компонент отладки
Скачать
Новый девиз
Благодарности
Итак, что же было реализовано в Phalcon 1.2.0
1. Динамические пути для скомпилированных шаблонов Volt
Опция «compiledPath» в параметрах шаблонизатора Volt теперь принимает анонимную функцию, позволяющую выполнить необходимые действия перед записью файла кеша шаблона.
// Добавляем расширение .php к файлам шаблонов
$volt->setOptions([
'compiledPath' => function($templatePath) {
return $templatePath . '.php';
}
]);
// Создаём необходимые подкаталоги для файлов
$volt->setOptions([
'compiledPath' => function($templatePath) {
$dirName = dirname($templatePath);
if (!is_dir(CACHE_DIR . $dirName)) {
mkdir(CACHE_DIR . $dirName,0755,true);
}
return CACHE_DIR . $dirName . '/'. $templatePath . '.php';
}
]);
2. Расширение возможностей Volt
Для нашего шаблонизатора теперь можно добавлять любые требуемые расширения, менять поведение, операторы и добавлять функции и фильтры. Класс ниже, например, позволяет использовать в шаблонах любые php-функции:
class PhpFunctionExtension
{
public function compileFunction($name, $arguments)
{
if (function_exists($name)) {
return $name . '('. $arguments . ')';
}
}
}
Добавляем это расширение:
$volt->getCompiler()->addExtension(new PHPFunctionExtension());
3. Ссылки для статичных и динамических путей в PhalconMvcUrl
Теперь можно указывать разные пути для ссылок, ведущих на статичные файлы: на картинки или, например, js файлы и для ссылок на страницы. Данная возможность особенно будет актуальна при использовании CDN.
$di['url'] = function() {
$url = new PhalconMvcUrl();
// Динамичный URI без mod-rewrite
$url->setBaseUri('/index.php?_url=');
// Статичный URI для CSS/Javascript/Images
$url->setStaticUri('/static/');
return $url;
};
4. PhalconMvcViewSimple
Компонент представляет собой более лёгкую альтернативу PhalconMvcView, без поддержки иерархии шаблонов. Он будет актуален для использования в микро-приложениях и получения представлений в виде строки.
// View service
$di['view'] = function() {
$view = new PhalconMvcViewSimple();
$view->setViewsDir(APP_PATH . '/views/');
return $view;
};
Использование в микро-приложениях:
$app->map('/login', function() use ($app) {
echo $app->view->render('security/login', array(
'form' => new LoginForm(),
));
});
Компонент поддерживает разные шаблонизаторы и кеширование шаблонов.
5. Улучшена работа с JSON
Получать и отправлять данные в JSON-формате стало намного проще. Передав данные в PhalconHttpResponse, они будут автоматически отправлены в JSON-формате:
$app->post('/api/robots', function() use ($app) {
$data = $app->request->getJsonRawBody();
$robot = new Robots();
$robot->name = $data->name;
$robot->type = $data->type;
$response = new PhalconHttpResponse();
// проверка правильности сохранения
if ($robot->success() == true) {
$response->setJsonContent([
'status' => 'OK',
'id' => $robot->id
]);
} else {
// установка кода HTTP статуса
$response->setStatusCode(500, "Internal Error");
$response->setJsonContent([
'status' => 'ERROR',
'messages' => $status->getMessages()
]);
}
return $response;
});
6. Поддержка Many-To-Many в ORM
Наша ORM стала поддерживать отношение многие-ко-многим. Это позволяет установить прямые отношения между двумя моделями с использованием третей модели, промежуточной:
class Artists extends PhalconMvcModel
{
public $id;
public $name;
public function initialize()
{
$this->hasManyToMany(
'id',
'ArtistsSongs',
'artists_id', 'songs_id',
'Songs',
'id'
);
}
}
Песни исполнителей можно получить через псевдоним отношения:
$artist = Artists::findFirst();
// получим все песни исполнителя
foreach ($artist->songs as $song) {
echo $song->name;
}
С отношениями многие-ко-многим можно работать в PHQL ( это надстройка над SQL, упрощающая использование моделей и построение sql запросов ):
$phql = 'SELECT Artists.name, Songs.name FROM Artists JOIN Songs WHERE Artists.genre = "Trip-Hop"';
$result = $this->modelsManager->query($phql);
Связанные данные могут быть добавлены сразу при создании модели, все необходимые промежуточные связующие записи будут созданы также автоматически:
$songs = array()
$song = new Song();
$song->name = 'Get Lucky';
$songs[] = $song;
$song = new Song();
$song->name = 'Instant Crush';
$songs[] = $song;
$artist = new Artists();
$artist->name = 'Daft Punk';
$artist->songs = $songs; // назначаем связанные элементы
$artist->save();
7. Работа с виртуальными внешними ключами
При указании Virtual foreign keys все связанные с основной записью зависимые элементы будут так же удалены:
use PhalconMvcModel
PhalconMvcModelRelation;
class Artists extends Model
{
public $id;
public $name;
public function initialize()
{
$this->hasMany('id', 'Songs', 'artists_id', [
'foreignKey' => [
'action' => Relation::ACTION_CASCADE
]
]);
}
}
При удалении исполнителя удалятся также и все его песни:
$artist = Artists::findFirst();
$artist->delete(); // удалится со всеми песнями
8. Минификация Javascript и CSS
Мы научили компонент PhalconAssets не только гибко управлять статичными ресурсами, группировать и фильтровать их, но еще и сжимать JS/CSS (минифицировать). Для такой ответственной работы были использованы готовые решения Jsmin от Douglas Crockford и CSSMin от Ryan Day.
$manager = new PhalconAssetsManager(array(
'sourceBasePath' => './js/',
'targetBasePath' => './js/production/'
));
$manager
// собираем Javascripts в нижнюю часть страницы
->collection('jsFooter')
// название файла с результатом
->setTargetPath('final.js')
// адрес готового файла
->setTargetUri('production/final.js')
// можно использовать внешние файлы, даже без фильтрации
->addJs('code.jquery.com/jquery-1.10.0.min.js', true, false)
// локальные файлы надо пропустить через фильтр
->addJs('common-functions.js')
->addJs('page-functions.js')
// все файлы необходимо собрать в один ( final.js )
->join(true)
// использовать встроенный фильтр Jsmin
->addFilter(new PhalconAssetsFiltersJsmin())
// еще один фильтр, самописный для приложения
->addFilter(new MyAppAssetsFiltersLicenseStamper());
$manager->outputJs();
9. Запрет переменных (литералов) в PHQL
Внутри PHQL теперь нельзя использовать параметры напрямую, следующий код выдаст исключения:
$artist = Artists::findFirst("name = '$name'");
10. Расширены возможности Partials
Разработчик теперь может передавать в partials массив параметров:
<?php $this->partial('footer', ['links' => $myLinks]);
Volt так же поддерживает эту возможность:
{{ partial('footer', ['links': myLinks]) }}
{% include 'footer' with ['links': myLinks] %}
11. Использование PhalconTag как сервиса
Мы старательно уходим от использования любых статичных методов, они всё еще работаю, но использовать их не желательно. Компонент PhalconTag теперь доступен как сервис в DIFactoryDefault. Вместо:
PhalconTag is now a service in DIFactoryDefault. So instead of doing this:
Стоит использовать:
$this->tag->setDefault('name', $robot->name);
12. Макросы в Volt
Работа с макросами только начата, дальше будет больше:
{%- macro input_text(name, attributes=null) -%}
{{- '<input type="' ~ name ~ '" ' -}}
{%- for key, value in attributes -%}
{{- key ~ '="' ~ value|e '"' -}}
{%- endfor -%}
{{- '/>' -}}
{%- endmacro -%}
{{ input_text("telephone", ['placeholder': 'Type telephone']) }}
13. BadMethodCallException вместо предупреждений
До версии 1.1.0 при передаче в методы неверного числа параметров возникало предупреждение. Начиная с версии 1.2.0, в таких ситуациях будет создано исключение BadMethodCallException с возможностью проследить, где именно возникла ошибка:
<?php
$e = new PhalconEscaper();
$e->escapeCss('a {}', 1, 2, 3);
Отобразится:
Fatal error: Uncaught exception 'BadMethodCallException' with message 'Wrong number of parameters' in test.php:4
Stack trace:
#0 test.php(4): PhalconEscaper->escapeCss('a {}', 1, 2, 3)
#1 {main}
14. Компонент отладки
Компонент PhalconDebug формирует отладочный стэк, позволяя разработчику проследить в каком месте что-то пошло не так. Данные оформлены в структурированном виде. Для работы компонента необходимо удалить try/catch блоки в стартовом файле и указать в его начале:
(new PhalconDebug)->listen();
Мы подготовили небольшой скринкаст с демонстрацией работы компонента:
Есть еще несколько важных нововведений:
- Вложенные транзакции в PhalconDb, поддерживается работа с несколькими соединениями
- Поддержка адаптеров кеширования XCache/Igbinary для Cache/Annotations/ORM-MetaData
- Поддержка PHP 5.5
- Profiled Guided Optimizations
Полный список изменений доступен в CHANGELOG.
Скачать
Собрать новую версию можно на GitHub, либо скачать готовые DLL библиотеки для Windows. Доступны так же готовые сборки для некоторых linux-систем.Документация так же обновлена.
Новый девиз
Долгое время мы работали под девизом «The fastest PHP Framework», полностью ему соответствуя и поддерживая скорость работы Phalcon на максимуме. Мы оптимизировали всё, что можно и искали любые возможности по экономии расхода памяти и уменьшению накладных расходов. Но скорость — не единственный наш приоритет. От версии к версии мы старались делать Phalcon ещё более удобным и включать в него самые полезные возможности. Это позволило вырасти проекту в один из самых быстрых и функциональных продуктов в мире открытого ПО.
Двигаясь вперёд, мы решили изменить наш девиз для более точного позиционирования Phalcon. С версии 1.2.0 мы работаем под лозунгом «The best balance of speed and functionality». Наша первоочередная цель — сохранение оптимального баланса между скоростью работы фреймворка и функционалом, который он предоставляет. Мы реально хотим быть не только самым быстрым фреймворком для PHP, но и самым оптимальным по соотношению скорости и функционала.
Благодарности
Мы хотим поблагодарить всех участников сообщества, разработчиков, голосующих за новые функции и помогающих с их реализацией и проверкой. Всех, кто помогает с тестированием и улучшением документации.
Спасибо всем, кто помогает развивать Phalcon и участвует в жизни сообщества.
Спасибо вам!
Автор: boston