php - WebExpo

Transkript

php - WebExpo
WEBEXPO, PRAHA
24. ZÁŘÍ 2011
BARTON STUDIO s.r.o.
BARTON ADVERTISING
www.bartonstudio.cz
Pavel Campr
[email protected]
Obsah přednášky:
1 – Éra nových PHP frameworků
2 – Symfony2 – úvod
3 – Symfony2 – výběr z toho nejlepšího
www.bartonstudio.cz
30 min
Co dnes máme…
mnoho frameworků… (nejen PHP)
roste jejich využití, více zkušeností
* http://xkcd.com/927
Jak vzniklo to, co dnes máme?
Ne vždy se vědělo, čeho by měl XY framework přesně dosáhnout.
Až po dokončení se zjistilo, co se povedlo a co ne.
Není cesta zpět. Musí se dodržet zpětná kompatibilita.
Není cesta kupředu. Při zachovávání zpětné kompatibility nelze v určité chvíli pokračovat dál.
Magie = problém v reálném světě
Něco se stane, nevíme proč, nebo jak…
… __get() __set() __call()
Nejasné API
Nedostatečná dokumentace
Globální konstanty…
… define('DEBUG', true);
SCOP vs OOP
Static Class Oriented Programming
Object Oriented Programming
XY::getLogger()->error(…);
$this->get(‘logger‘)->error(…);
Éra nových PHP frameworků
• Nové koncepty, zahození starých špatných,
ponechání starých dobrých (MVC)
• Feedback od komunity vývojářů
• Standardy + „do not reinvelt the wheel“
• PHP 5.3 … a několik let tu bude s námi
• Namespaces, Anotace
• Zrušení magie – explicitní metody a
proměnné, čistý kód // na úkor funkcionality (?)
• Malé „jádro“, využití existujících komponent
• Dependency injection // singleton ne (?)
• Nástroje – Git
http://www.sxc.hu
symfony vs Symfony2
http://www.symfony-project.org
http://www.symfony.com
říjen 2005 – 1. revize (SVN)
leden 2010 – 1. revize (Git)
prosinec 2008 – verze 1.2.0
28. červenec 2011 - verze 2.0
současná stable verze 1.4.14
současná stable verze 2.0.1
LTS (long term support) do listopadu 2012
LTS – až od Symfony 2.1
PHP 5.2
PHP 5.3
+ ověřené, komunita
+ známé „best practices“
+ plugins
- provázané a závislé komponenty
bez šablonovacího systému
+ dokumentace
- končí LTS
+ komunita
- neznámé „best practices“
+ bundles
+ nezávislé komponenty
+ šablonovací systém Twig
+ zrychlení, cache, ESI
+ standardy
Symfony2: „Build your App, not your Tools!“
250 vývojářů (v den vydání 2.0), 18 měsíců vývoje
github.com: 3021 watchers (#1 in PHP, #25 overall), 773 forks (#1 in PHP, #13 overall)
Standardy:
• HTTP specifikace // RFC2616
• PHPUnit
• Namespaces
• YAML, XML
• PSR-0 autoloading
• …
výběr komponent (HttpFoundation, Routing, ClassLoader, …)
+
externí knihovny (Swiftmailer, Twig, …)
+
externí bundles (DoctrineBundle, MonologBundle, …)
+
„lepidlo“
+
konfigurace
=
full-stack framework
Instalace
„Symfony Standard 2.0.1“ distribuce
http://symfony.com/download
obsahuje plně funkční kostru web aplikace
požadavky: 5.3.2, SQLite3, APC
/deps
[symfony]
git=http://github.com/symfony/symfony.git
version=v2.0.1
[twig]
git=http://github.com/fabpot/Twig.git
version=v1.1.2
[monolog]
git=http://github.com/Seldaek/monolog.git
version=1.0.1
[doctrine-common]
git=http://github.com/doctrine/common.git
version=2.1.1
[SensioFrameworkExtraBundle]
git=http://github.com/sensio/SensioFrameworkExtraBundle.git
target=/bundles/Sensio/Bundle/FrameworkExtraBundle
[JMSSecurityExtraBundle]
git=http://github.com/schmittjoh/JMSSecurityExtraBundle.git
target=/bundles/JMS/SecurityExtraBundle
Bundle
Bundle je adresář. Obsahuje vše potřebné pro implementaci jedné funkcionality.
(logování, zabezpečení, profilování, blog, katalog produktů, admin generátor, …)
•
•
•
•
•
•
Konfigurace (routing, předvolby)
PHP soubory
Šablony
Obrázky, CSS, JS, …
Překlady
Testy
Vše je „Bundle“. Včetně jádra Symfony2.
www.symfony2bundles.org / github.com
FOSUserBundle, SonataAdmin, FOSRest, FOSRest, FOSFacebook, SensioGenerator,
SonataMedia, AvalancheImagine, WhiteOctoberAdmin, FOSComment, KnpPaginator,
JMSDebugging, WebProfilerExtra, AdmingeneratorGenerator, Forum,
JMSSecurityExtra, FOSTwitter, FOQElastica, Propel, Google, Assetic, SncRedis,
JMSI18nRouting, Xhprof, DoctrineMigrations, Facebook, WebService, Twitter,
Calendar, Doctrator, DataGrid, FirePHP, Guestbook, Imagine, DoctrineCouchDB,
EWZRecaptcha, Tinymce, ZendNavigation, Tree, …
http://www.sxc.hu
Tvoříme aplikaci. Konvertujeme
Request do Response.
GET / HTTP/1.1
Host: webexpo.cz
Accept: text/html
User-Agent: PowerPoint/1.0
<?php
$foo = $_GET['foo'];
header('Content-type: text/html');
header('Expires: Sat, 24 Sep 2011 23:59:00 GMT');
echo '"foo" is: '.$foo;
HTTP/1.1 200 OK
Date: Sat, 24 Sep 2011 10:10:28 GMT
Server: Apache/2.2.17
Content-Type: text/html
Expires: Sat, 24 Sep 2011 23:59:00 GMT
"foo" is: symfony2
… přidáme trochu Symfony2
<?php
require(…);
$request = Request::createFromGlobals();
$path = $request->getPathInfo(); // the URL being requested
if (in_array($path, array('', '/')) {
$params = $request->getParameters();
$response = new Response('"foo" is:'.$params['foo']);
} else {
$response = new Response('Page not found.', 404);
}
$response->send();
* symfony.com
Start nové Symfony2 aplikace
1)
2)
3)
4)
Vytvořit a zaregistrovat nový bundle.
$ php app/console
Nachystat URL adresy („route“), …
… ty nasměrovat na nové akce, …
… které vytvoří Response objekt (nejčastěji přes šablonu).
generate:bundle
# app/config/routing.yml
BartonStudioWebexpoBundle:
resource: "@BartonStudioWebexpoBundle/Resources/config/routing.yml"
prefix:
/
// app/AppKernel.php
public function registerBundles()
{
$bundles = array(
// ...
new BartonStudio\WebexpoBundle\BartonStudioWebexpoBundle(),
);
// ...
return $bundles;
}
Nachystání URL adres: routing (YAML konfigurace)
# src/BartonStudio/WebexpoBundle/Resources/config/routing.yml
hello:
pattern: /hello/{name}
defaults: { _controller: BartonStudioWebexpoBundle:Hello:index }
Vytvoření akce (nejjednodušší provedení)
// src/BartonStudio/WebexpoBundle/Controller/HelloController.php
namespace BartonStudio\HelloBundle\Controller;
use Symfony\Component\HttpFoundation\Response;
class HelloController
{
public function indexAction($name)
{
return new Response('<html><body>Hello '.$name.'!</body></html>');
}
}
Vytvoření akce lépe - s využitím šablony
// src/BartonStudio/WebexpoBundle/Controller/HelloController.php
namespace BartonStudio\WebexpoBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class HelloController extends Controller
{
public function indexAction($name)
{
return $this->render('BartonStudioWebexpoBundle:Hello:index.html.twig',
array('name' => $name));
}
}
Vytvoření akce pokročile
(využití anotací pro nastavení routingu, zabezpečení a zapnutí šablony)
/**
* @Route("/hello/admin/{name}", name="secured_hello_admin")
* @Secure(roles="ROLE_ADMIN")
* @Template()
*/
public function helloAdminAction($name)
{
return array('name' => $name);
}
Environments
http://localhost/app_dev.php/hello/Webexpo
http://localhost/app_staging.php/hello/Webexpo
http://localhost/app.php/hello/Webexpo
Stejný PHP kód, jiná konfigurace:
logování, profilování
využití cache
ladicí nástroje
odesílání e-mailů
routing
http://www.sxc.hu
Testování, profilování
PHPUnit 3.5.11 nebo vyšší
<?php
class HelloControllerTest extends WebTestCase
{
public function testIndex()
{
$client = static::createClient();
$crawler = $client->request('GET', '/hello/Webexpo');
// Write some assertions about the Response
$this->assertTrue(
$crawler->filter('html:contains("Hello Webexpo")')->count() > 0
);
// Check that the profiler is enabled
if ($profile = $client->getProfile()) {
// check the number of requests
$this->assertTrue($profile->getCollector('db')->getQueryCount() < 10);
// check the time spent in the framework
$this->assertTrue( $profile->getCollector('timer')->getTime() < 0.5);
}
}
}
Lze vytvořit i více klientů najednou.
Web Debug Toolbar
„Service container“
Služba (service) = PHP objekt, který je vytvořen pro konání „globálních“ úloh.
Je využíván všude, kde je nutné využít jeho funkcionalitu.
Service container = PHP objekt, který vytváří, spravuje a poskytuje jednotlivé služby
// uvnitř akce
$mailer = $this->get('mailer');
$ php app/console container:debug
[container] Public services
Name
Scope
acme.demo.listener
container
annotation_reader
container
assetic.asset_manager
container
database_connection
n/a
debug.event_dispatcher
n/a
doctrine
container
esi
container
filesystem
container
form.factory
container
http_kernel
container
kernel
container
logger
container
mailer
container
profiler
container
request
request
router
container
service_container
container
session
container
templating
container
twig
container
Class Name
Acme\DemoBundle\ControllerListener
Doctrine\Common\Annotations\FileCacheReader
Assetic\Factory\LazyAssetManager
alias for doctrine.dbal.default_connection
alias for event_dispatcher
Symfony\Bundle\DoctrineBundle\Registry
Symfony\Component\HttpKernel\HttpCache\Esi
Symfony\Component\HttpKernel\Util\Filesystem
Symfony\Component\Form\FormFactory
Symfony\Bundle\FrameworkBundle\HttpKernel
Symfony\Bridge\Monolog\Logger
Swift_Mailer
Symfony\Component\HttpKernel\Profiler\Profiler
Symfony\Bundle\FrameworkBundle\Routing\Router
Symfony\Component\HttpFoundation\Session
Symfony\Bundle\TwigBundle\TwigEngine
Twig_Environment
Vytvoření vlastní služby
# app/config/config.yml … vytvoření služby "napevno"
services:
my_mailer:
class:
BartonStudio\WebexpoBundle\Mailer
arguments:
[sendmail] # transportni vrstva
# app/config/config.yml … vytvoření služby s měnitelnými parametry
parameters:
my_mailer.class:
BartonStudio\WebexpoBundle\Mailer
my_mailer.transport: sendmail
services:
my_mailer:
class:
%my_mailer.class%
arguments:
[%my_mailer.transport%]
# src/BartonStudio/WebexpoBundle/Resources/config/services.yml
# využití jiných služeb = Referencing (Injecting) Services
parameters:
newsletter_manager.class: BartonStudio\WebexpoBundle\Newsletter\NewsletterManager
services:
newsletter_manager:
class:
%newsletter_manager.class%
arguments: [@my_mailer, @templating]
Twig – šablonovací systém
•
•
•
•
přednastavený, ale není povinný
nejen pro (x)html, ale i pro xml, php, txt, …
rychlý, rozšiřitelný, bezpečný, jednoduchý
dědičnost – základní šablona nachystá „bloky“,
ty se pak vloží do nadřazené šablony
Twig 1.2.0
http://twig.sensiolabs.org
/app/Resources/views/layout.html.twig
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>{% block title %}Welcome!{% endblock %}</title>
{% javascripts '@BartonStudioWebexpoBundle/Resources/public/js/my1.js'
'@BartonStudioWebexpoBundle/Resources/public/js/my2.js'
%}
<script type="text/javascript" src="{{ asset_url }}"></script>
{% endjavascripts %}
{% stylesheets '@BartonStudioWebexpoBundle/Resources/public/css/style1.css'
'@BartonStudioWebexpoBundle/Resources/public/css/style2.css'
%}
<link href="{{ asset_url }}" type="text/css" rel="stylesheet" />
{% endstylesheets %}
<link rel="shortcut icon" href="{{ asset('favicon.ico') }}" />
</head>
<body>
<header>WebExpo 2011 DEMO</header>
<article>
{% block body %}{% endblock %}
</article>
<sidebar>
{% block sidebar %}{% endblock %}
</sidebar>
</body>
</html>
/src/BartonStudio/WebexpoBundle/Resources/views/Default/show.html.twig
{% extends "::layout.html.twig" %}
{% block body %}
<h1>{% trans %}Topic{% endtrans %}: {{ topic }}</h1>
<p>{{ description }}</p>
{% include 'BartonStudioWebexpoBundle:Default:date.html.twig' with {'date': date} %}
<a href="{{ path('webexpo_topic_show', { 'topic': 'Symfony2' }) }}">Symfony2</a>
{% endblock %}
{% block sidebar %}
<h2>List of users</h2>
<ul>
{% for user in users %}
<li class="{{ cycle(['odd', 'even']) }}">{{ user.username }}</li>
{% else %}
<li>No users found</li>
{% endfor %}
</ul>
{% endblock %}
{% ... %} vykoná příkaz
{{ ... }} vypíše hodnotu
Assetic
Komprese CSS
a JS souborů
Komprese a
úprava
obrázků
Slučování CSS
a JS souborů
Kompilace
(LESS, SASS,
CoffeeScript,
…)
Cache busting
Optimalizované
doručení CSS,
JS, obrázků
CDN
Assetic
dev environment, HTTP požadavky prohlížeče při načtení stránky „ahoj“:
GET
GET
GET
GET
GET
http://webexpo2011demo.czlocal/app_dev.php/cs/webexpo/ahoj
http://webexpo2011demo.czlocal/app_dev.php/js/a2e2c51_my1_1.js
http://webexpo2011demo.czlocal/app_dev.php/js/a2e2c51_my2_2.js
http://webexpo2011demo.czlocal/app_dev.php/css/a498173_style1_1.css
http://webexpo2011demo.czlocal/app_dev.php/css/a498173_style2_2.css
export JS / CSS souborů do statických souborů:
$ php app/console assetic:dump
Dumping all dev assets.
Debug mode is on.
[file+]
[file+]
[file+]
[file+]
[file+]
[file+]
S:\WWW\project_webexpo2011\trunk\app/../web/js/a2e2c51.js
S:\WWW\project_webexpo2011\trunk\app/../web/js/a2e2c51_my1_1.js
S:\WWW\project_webexpo2011\trunk\app/../web/js/a2e2c51_my2_2.js
S:\WWW\project_webexpo2011\trunk\app/../web/css/a498173.css
S:\WWW\project_webexpo2011\trunk\app/../web/css/a498173_style1_1.css
S:\WWW\project_webexpo2011\trunk\app/../web/css/a498173_style2_2.css
prod environment , HTTP požadavky prohlížeče při načtení stránky „ahoj“:
GET http://webexpo2011demo.czlocal/app.php/cs/webexpo/ahoj
GET http://webexpo2011demo.czlocal/js/a2e2c51.js
GET http://webexpo2011demo.czlocal/css/a498173.css
Cache
Nejefektivnější možnost pro zrychlení aplikace:
uložit celý výstup (www stránku) do cache. Nejde vždy Typy cache:
• Browser cache – Uvnitř www prohlížeče. Pro jednoho uživatele.
• Proxy cache – poskytovatelé připojení (ISP), zvyšuje rychlost odezvy
a snižuje provoz na síti. Pro více uživatelů.
• Gateway cache (reverse proxy, surrogate cache, HTTP akcelerátor) –
podobně jako proxy cache, ale je přímo na serveru.
http://www.sitepoint.com
Cache
Symfony2 využívá pro řízení a konfiguraci cache pouze HTTP standard.
HTTP/1.1 200 OK
Date: Sat, 24 Sep 2011 10:18:41 GMT
Server: Apache/1.3.3 (Unix)
Cache-Control: max-age=3600, must-revalidate
Expires: Sat, 24 Sep 2011 11:19:41 GMT
Last-Modified: Fri, 23 Sep 2011 02:28:12 GMT
ETag: "3e86-410-3596fbbc"
Content-Length: 5040
Content-Type: text/html
Cache
HTTP Expiration / HTTP Validation
$response->setClientTtl(…);
$response->setExpires(…);
$response->setMaxAge(…);
$response->setSharedMaxAge(…);
$response->setTtl(…);
// HTTP 304 – Not Modified
$response->setETag(…);
$response->setLastModified(…);
Cache
HTTP Expiration / nastavení v akci
public function listAction()
{
// …
$response = $this->render(‘…‘);
// uloží se v cache prohlížeče
$response->setMaxAge(60);
return $response;
}
Reverse proxy = Gateway cache
Symfony2 obsahuje vestavěný „HTTP akcelerátor“
<?php
// web/app.php
require_once __DIR__.'/../app/bootstrap.php.cache';
require_once __DIR__.'/../app/AppKernel.php';
require_once __DIR__.'/../app/AppCache.php';
use Symfony\Component\HttpFoundation\Request;
$kernel = new AppKernel('prod', false);
$kernel->loadClassCache();
// caching kernel = reverse proxy = gateway cache
$kernel = new AppCache($kernel);
$kernel->handle(Request::createFromGlobals())->send();
Cache
HTTP Expiration / nastavení v akci
// gateway cache – máme teď zapnuto
public function listAction()
{
// …
$response = $this->render(‘…‘);
$response->setMaxAge(60);
// chceme pro všechny uživatele
// uložit výsledek akce do gateway cache
$response->setSharedMaxAge(60);
return $response;
}
standard ESI – Edge Side Includes
<esi:include src="http://example.com/1.html"
alt="http://bak.example.com/2.html"
onerror="continue"/>
Implementováno v Symfony2 uvnitř reverse proxy. Lze využít i jiné (Varnish).
Do cache lze díky ESI ukládat fragmenty www stránky nezávisle.
ESI - ukázka
<?php
// BartonStudio/BlogBundle/Resources/views/show.html.twig
{% extends "::layout.html.twig" %}
{% block body %}
<h1>{{ article.title }}</h1>
<p>{{ article.body }}</p>
{% endblock %}
{% block sidebar %}
<h2>Twitter</h2>
// zde bude vlozen tag <ESI> , pokud je to povoleno:
// <esi:include src="{{ path('twitter_list') }}" />
// lépe udělat takto:
{% render 'BartonStudioTwitterBundle:Twitter:list'
{'standalone': true} %}
{% endblock %}
// zobrazení článku blogu (v bloku „body“) a aktuální výpis z twitteru (v bloku „sidebar“)
Zabezpečení
XSS (Cross-site scripting), CSRF (Cross-site request forgery), SQL injection
Znepřístupnit uživateli (1) místa, kam by neměl mít přístup (2).
Lze řídit:
• přístup uživatele k akcím („editace článků“).
• nebo detailněji – ACL (access control list) pro řízení přístupu k jednotlivým
instancím objektů („kdo může editovat článek #81“)
* symfony.com
* symfony.com
Co jsme nestihli
Formuláře
Validace
Databáze
Model, ORM (Doctrine 2)
Překlady, I18n, L10n
Emaily (SwiftMailer)
…
Co jsme neměli rádi a teď se nám líbí
Příkazová řádka
Anotace
Co nám zatím chybí
Chybí větší tutorial (ala Jobeet ze symfony 1.2)
Nejasné „best practices“
Roadmap
Symfony 2.1 (LTS - Long Time Support)
• konec roku 2011
• první verze, kde všechny komponenty budou
mít stabilní API (anotace @api)
Zdroje a užitečné odkazy:
www.symfony.com – „The Book“, „The Cookbook“
symfony.com/components
github.com/kriswallsmith/assetic
twig.sensiolabs.org
silex.sensiolabs.org
Na shledanou nad vaším projektem
BARTON STUDIO s.r.o.
www.bartonstudio.cz

Podobné dokumenty

PHP Developer

PHP Developer cestě za continuous integration. Pracujeme agilně s dlouhodobou vizí stát se multichannel lídrem na EU trhu. O čem to s námi bude?  Práce na jedné z největších e-commerce platforem v Evropě  Spou...

Více

UŽIVATELSKà Nà VOD SECOND MID aktuálnÃ

UŽIVATELSKà Nà VOD SECOND MID aktuálnà kapacitní technologii, je tedy více-dotykový !!! Na LCD displeji se nacházejí velice účelné klávesy, které urychlují a zpříjemňují práci s tabletem Symfony Second MID. Tablet je vybaven samostanou ...

Více

Třída GLA.

Třída GLA. Nový model GLA. Svoboda je nakažlivá. Nový model GLA na první pohled odkrývá nekonečně mnoho možností. Čím začít? Nejlépe propracovaným a zároveň aerodynamickým designem s touhou drát se kupředu....

Více