Upload
oleksandr-torosh
View
2.515
Download
0
Embed Size (px)
DESCRIPTION
Мой доклад на конференции "Php frameworks day 2013"
Citation preview
В мире PHP фреймворков
• ZendFramework
• Symfony
• Yii
• Laravel
• Kohana
Преимущества работы с фреймворками
• Однородная архитектура приложения
• DRY code
• Широкий набор готового
инструментария
• Высокая скорость разработки
• Возможность строить гибкие и
масштабируемые приложения
• …
Недостатки фреймворков
• Большое количество файлов
• Каждый запрос к серверу
~ 40-60 .php файлов
• Код фреймворка интерпретируется для
каждого запроса заново
• Большой аппетит на системные
ресурсы
• Относительно низкая устойчивость к
нагрузкам
Как заставить фреймворк работать быстрее?
Как заставить фреймворк работать быстрее?
• Сделать сборку в один файл
• HTTP-прокси кеш, например Varnish
• Переписать dispatcher под себя
• Написать свой MVC
• Кешировать все вдоль и поперек
• …
• Как-то работать с этим всем дальше
Нагрузочный тест Hello World
354 489 541
851 860
1059
2535
Zend Laravel Symfony Yii Kohana Codeigniter Phalcon
Requests per second
Потребление памяти
1,75
1,50 1,50
1,25 1,25
1,10
0,25
Zend Yii Symfony Laravel Kohana Codeigniter Phalcon
Megabytes per request
Phalcon PHP Framework
Особенности Phalcon
• Написан на Си
• Работает как extension для PHP
• Уже скомпилирован и не требует
интерпретации
• Находится в оперативной памяти
• Требует минимум файловых операций
• Потребляет мало ресурсов
• Очень производительный
• Не требует от разработчика знаний Си
• Бубен нам уже не нужен
Компоненты
• Routing
• Cache
• Pagination
• Annotations
• Security
• Translations
• Assets Management
• Auto-Loader
• Logging
• CLI
• ODM для Mongo
• ORM
• Шаблонизатор Volt
• DI / IOC
• Events Management
• Encryption
• HTTP Request /
Response / Cookies
• Escaping / Filtering
• Forms
• Flash Messages
Готовое приложение на Github
https://github.com/
oleksandr-torosh/phalcon-modular-app
Auto-Loader
$loader = new Phalcon\Loader();
$loader->registerNamespaces(array(
'Zend' => __DIR__ .
'/../vendor/zendframework/zendframework/library/Zend',
'Application' => __DIR__ . '/modules/Application',
'Index' => __DIR__ . '/modules/Index',
'Blog' => __DIR__ . '/modules/Blog',
));
$loader->register();
• Na++mespaces
• Prefixes (ZF1-style)
• Directories
• Classes
• Любые расширения файлов (.php, .inc, .phb … )
Dependency Injection Container
ssd
Dependency Injection Container
// Инициализация сервисов приложения
$view = new Phalcon\Mvc\View();
$view->setPartialsDir(/*some dir*/);
$di->set('view', $view);
// Переопределение сервиса, например в Module.php
$view = $di->get('view');
$view->setViewsDir(/*some dir*/);
$di->set('view', $view);
Routing
$router->add('/:module/:controller/:action/:params', array(
'module' => 1,
'controller' => 2,
'action' => 3,
'params' => 4
));
// REQUEST_URI = '/blog/admin/index/3'
// Namespace Blog\Controller\AdminController
public function editAction($id)
{
// id = '3' (string)
}
Default router
Обработка параметров в контроллере
Routing
$router->add(
"/admin/:controller/a/:action/:params", array(
"controller" => 1,
"action" => 2,
"params" => 3,
));
$router->add(
"/blog/{id:[0-9]+}/{slug:[a-z\-]+}",
"Blog\IndexController::post"
);
Предопределенные плейсхолдеры
Пользовательские плейсхолдеры и короткий синтаксис
Routing
$router->add(
"/blog/([0-9]+)/([a-z\-]+)(/([0-9]+))?",
array(
"module" => "blog",
"controller" => "index",
"action" => "archive",
"year" => 1,
"month" => 2,
"page" => 4
)
);
Регулярные выражения
Routing
$blog = new \Phalcon\Mvc\Router\Group(
array(
'module' => 'blog',
'controller' => 'index'
)
);
$blog->setPrefix('/blog');
$blog->add('/{slug:[a-z0-9_-]+}.html',
array(
'action' => 'post',
)
)->setName('blog/post');
$router->mount($blog);
Группы маршрутов
Routing
// This route only will be matched if the HTTP method is GET
$router->addGet("/products/edit/{id}", "Products::edit");
// This route only will be matched if the HTTP method is POST
$router->addPost("/products/save", "Products::save");
// This route will be matched if the HTTP method is POST or PUT
$router->add("/products/update")->via(array("POST", "PUT"));
Маршруты для определенных типов HTTP-запросов
RESTful applications friendly
Routing
/**
* @RoutePrefix("/api/products")
*/
class ProductsController
{
/**
* @Get("/edit/{id:[0-9]+}", name="edit-robot")
*/
public function editAction($id)
{
}
/**
* @Route("/save", methods={"POST", "PUT"}, name="save-robot")
*/
public function saveAction()
{
}
}
Аннотации
Cache
Backend Adapters:
• File
• Memcached
• APC
• Mongo
• XCache
Используется в:
• View
• Models
• ModelsMetadata
• Annotations
Cache
use Phalcon\Cache\Multiple,
Phalcon\Cache\Backend\Apc as ApcCache,
Phalcon\Cache\Backend\Memcache as MemcacheCache,
Phalcon\Cache\Backend\File as FileCache;
$cache = new Multiple(array(
new ApcCache($ultraFastFrontend, array(
"prefix" => 'cache',
)),
new MemcacheCache($fastFrontend, array(
"prefix" => 'cache',
"host" => "localhost",
"port" => "11211"
)),
new FileCache($slowFrontend, array(
"prefix" => 'cache',
"cacheDir" => "../app/cache/"
))
));
Многоуровневый кеш
Volt: Template Engine
• Шаблонизатор
• Написан на Си
• Ультра-быстрый
• Синтаксис похожий на Jinja (python),
Twig (php)
• Имеет высокую степень интеграции с
сервисами Phalcon
Возможности Volt
• Работа с переменными приложения
• Фильтрация данных вывода
• Логические выражения и операторы
• Математические выражения
• Работа с массивами
• Макросы
• Добавление своих функций
• Кеширование
Пример шаблона Volt
<!DOCTYPE html>
<html>
<head>
<title>{{ title }} - An example blog</title>
</head>
<body>
{% if show_navigation %}
<ul id="navigation">
{% for item in menu %}
<li><a href="{{ item.href }}">{{ item.caption }}</a></li>
{% endfor %}
</ul>
{% endif %}
<h1>{{ post.title }}</h1>
<div class="content">
{{ post.content }}
</div>
</body>
</html>
ORM
• Работа с сущностями
• Реляционные связи
• Удобные методы find,
findFirst с параметрами
выборки
• Phalcon Query Language
• Query Builder
• Валидации
• Гидрации
• Кеширование
• События/Events
• Транзакции
• Models Meta-Data
• Аннотации
• Логирование
• Профилирование
• Шардинг
Пример простого контроллера
public function indexAction()
{
$posts = Post::find(array('sort' =>
array('created_at' => 'desc'))
);
$this->view->posts = $posts;
}
public function postAction($slug)
{
$post = Post::findFirst(
array("slug = '{$slug}'",
'cache' => array(
'lifetime' => 30,
'key' => "Post::findBySlug(" . md5($slug) . ")"
))
);
$this->view->post = $post;
$this->tag->prependTitle($post->getTitle());
}
Developer Tools / Консоль
Developer Tools / Web-интерфейс
Хотелось бы упомянуть
• Развитый View Layer
• Assets Manager для минификации и
билдинга CSS, JS файлов
• ODM для MongoDb
• UNIT Testing
Higload проект Gazeta.ua
• ZendFramework 1.11
• ORM Doctrine 1.24
• MySQL
Достижение производительности
• Изменение MVC
• Varnish HTTP-proxy
• Полное кеширование страниц
• Блочное кеширование
Higload проект Gazeta.ua
Web-server
8 x Intel(R) Xeon(R)
CPU E5506 @ 2.13GHz
Total Memory 32 Gb
Middle Load avg. ~ 3.5
DB-server
8 x Intel(R) Xeon(R)
CPU E5506 @ 2.13GHz
Total Memory 16 Gb
Middle Load avg. ~ 2.1
Хиты ~ 800 000
Хосты ~ 140 000
Средний онлайн ~ 2500
Максимальный онлайн ~ 8000
Нагрузочное тестирование Gazeta.ua
# ab -n 2000 -c 10 http://gazeta.ua/
Requests per second: 67.24 [#/sec] (mean)
# ab -n 2000 -c 10 http://gazeta.ua/
Requests per second: 9.08 [#/sec] (mean)
Varnish, многоуровневое кеширование, MySQL
MySQL
Web-server CRASHED ~ 8000 онлайн
Dev-версия Gazeta.ua на Phalcon
# ab -n 2000 -c 10 http://gazeta_phalcon.local/
Requests per second: 598.74 [#/sec] (mean)
# ab -n 2000 -c 10 http:// gazeta_phalcon.local /
Requests per second: 101.92 [#/sec] (mean)
Кеширование виджетов, MongoDb
MongoDb
9,08
67,24 101,92
598,74
ZF1 ZF1+cache Phalcon Phalcon+cache
Dev-версия Gazeta.ua на Phalcon
Перспективы развития Phalcon
Проблема:
• Исходный код на Си
• Низкая скорость развития фреймворка
Решение:
• Создание новой версии Phalcon 2.0, которая
будет написана на Zephir – мощный
и простой язык понятный любому
PHP-разработчику
Zephir
class MyTest
{
public function someMethod()
{
/* Variables must be declared */
var fruits;
int i = 0, length;
/* Create PHP array */
let myArray = ["hello", 0, 100.25, false, null];
/* count the array into a 'int' variable */
let length = count(myArray);
/* Print value types */
while i < length {
echo typeof myArray[i], "\n";
let i++;
}
return fruits;
}
}
Выводы
• Phalcon даёт нам новый, свежий взгляд
на PHP фреймворки
• Phalcon – это очень быстрый и богатый
функционалом фреймворк
• На нем можно смело разрабатывать
Production приложения
• Очень большие перспективы развития
Вопросы
Александр Торош Веб-студия «WeZoom»
wezoom.com.ua
Тел: (044) 221-65-78
(096) 989-08-28
(063) 787-22-36