Upload
xopn
View
1.425
Download
0
Embed Size (px)
DESCRIPTION
An Introduction to Symfony Components and the Symfony2 Framework.
Citation preview
An Introduction to
Christian Zenker @xopn [email protected]
Symfony Components
● About 20 stand-alone packages with one specific purpose● Mostly independent from each other● Usable in almost any PHP project● Unit tested and well documented
http://symfony.com/components
● YAML is a human-readable data serialization format like XML or JSON
YAML Component
user: name: Homer Simpson # unsure about age age: 40 kids: ["Bart", "Lisa", "Maggie"] quotes: - | Operator! Give me the number for 911! - | Internet? Is that thing still around?"
http://symfony.com/doc/current/components/console/introduction.html
$yaml = file_get_contents('users.yml');
$parser = new Parser();$data = $parser->parse($yaml);$data['user']['wife'] = 'Marge';
$dumper = new Dumper();$yaml = $dumper->dump($data, 2);
file_put_contents( 'users.yml', $data);
Console Component
● Write console programs in PHP● Clean architecture● Parses arguments and options● Easily extensible● Helpers for
– progress bars– tabular data– interactive questions– colored output
me@home> php console.php demo:hello JohnHello John
me@home> php console.php demo:helloWhat's your name? JohnHello John
me@home> php sandwich.php makeWhat? Make it yourself!
me@home> php sandwich.php make --forceOk. [=======>---------] 42%
Console Component (II)
class GreetCommand extends Command { protected function configure() { $this ->setName('demo:greet') ->setDescription('Greet someone') ->addArgument( 'name', InputArgument::OPTIONAL, 'Who do you want to greet?' ) ->addOption( 'yell', null, InputOption::VALUE_NONE, 'If set, the task will yell in uppercase letters' ) ; }// ...
Console Component (III)
// ... protected function execute(InputInterface $input, OutputInterface $output) { $name = $input->getArgument('name'); if ($name) { $text = 'Hello '.$name; } else { $text = 'Hello'; }
if ($input->getOption('yell')) { $text = strtoupper($text); }
$output->writeln($text); }}
http://symfony.com/doc/current/components/console/introduction.html
Finder Component
http://symfony.com/doc/current/components/finder.htmlhttp://symfony.com/doc/current/components/filesystem.html
● Simple wrapper for PHP functions● Exceptions on error● Batch processing$finder = new Finder();
$iterator = $finder ->files() ->name('*.php') ->depth(0) ->size('>= 1K') ->in(__DIR__);
foreach ($iterator as $file) { /** @var SplFileInfo $file */ $file->getRealpath();}
● Search filesystem or Amazon S3● Uses `find` or PHP functions
$filesystem = new Filesystem();$filesystem->mkdir($dirs, 0777);$filesystem->touch($files, time() - 86400);$filesystem->remove($dir);$filesystem->chown($files, $user);$filesystem->symlink($originDir, $targetDir);$filesystem->mirror($originDir,$targetDir);
Filesystem Component
CssSelector Component
● Converts CSS selectors into Xpath ● Query XML and HTML pages● Use for simple functional tests
Goutte
echo CssSelector::toXPath('div.item > h4 > a');
descendant-or-self::div[contains(concat(' ',normalize-space(@class), ' '), ' item ')]/h4/a
https://github.com/fabpot/Gouttehttp://symfony.com/doc/current/components/css_selector.html
$client = new Client();
$crawler = $client->request( 'GET', 'http://example.com');
$link = $crawler->selectLink('Users')->link();$crawler = $client->click($link);
$users = $crawler->filter('#users > li');echo count($users) . ' online';
● CSS is better readable● Xpath is more powerful
Symfony Framework
● an HTTP framework● MVC framework? Sure, why not.● Based on Symfony Components
and well-established third-party libraries
● Backwards compatibility starting with 2.3
● Console powered● Environment aware (production,
development, testing)● Configuration via YAML, XML,
JSON, annotations● Fast and low memory footprint
ClassLoader
Config
Console
DependencyInjection
EventDispatcher
Finder
Form
HttpFoundation
HttpKernel
Intl
Routing
Security
Validator
...
SF Components
SwiftMailer
Doctrine
Monolog
Assetic
Twig
FrameworkBundle
SwiftmailerBundle
GeneratorBundle
DoctrineBundle
WebProfilerBundle
AsseticBundle SecurityBundle
...
...
GET / HTTP/1.1Host: example.comAccept: text/html
HTTP/1.1 200 OKContent-Type: text/html
<!DOCTYPE html><p>Hello World</p>Br
owse
r
GET / HTTP/1.1
HTTP/1.1 200 OK
Ap pl ica ti onindex.php
Symfony2 Kernel
Routing
Request URI
Controller::actionRequest O
bjectRespons e
Object
GET / HTTP/1.1
HTTP/1.1 200 OK
Ap pl ica ti onindex.php
Symfony2 Kernel
Routing
Request URI
Controller::actionRequest O
bjectRespons e
Object
Fire
wall
Caching
Event Handling
Controller
class MainController extends Controller { public function helloAction($name) { return $this->render( 'AcmeHelloBundle:Main:hello.html.twig', array('name' => $name) ); }}
hello: path: /hello/{name} defaults: _controller: AcmeHelloBundle:Main:hello
http://example.com/hello/world
<!DOCTYPE html><h1>Hello {{ name }}!</h1><p>Also see our <a href="{{ path('route_name') }}"> other pages </a></p><ul>{% for i in 0..10 if i %2 == 0 %} <li>{{ i }} is an even number</li>{% endfor %}</ul>
Service Container
class AntispamService { /** doctrine entity manager */ protected $em; protected $max; public function __construct($em, $max) { $this->em = $em; $this->max = $max } public function isCommentSpam($string) { $words = explode(' ', $string); $dql = 'SELECT w FROM AcmeHelloBundle:Word WHERE w.word IN (?)'; $query = $this->em->createQuery($dql); $query->setParameter(0, $words); $blackWords = $query->execute(); return count($blackWords) > $this->max; }}
Service Container (II)
services: acme_hello.antispam: class: Acme\HelloBundle\AntispamService arguments: - @doctrine.orm.entity_manager - %max_blacklist_words%
public function indexAction($comment) { $service = $this->get('acme_hello.antispam'); if($service->isCommentSpam()) { $response = new Response(); $response->setStatusCode('403'); $response->setContent('Get off my lawn'); return $response; } // ... do something ...}
Further Reading
● symfony.com– Official homepage with
documentation, etc.● fabien.potencier.org
– The fancy parts● silex.sensiolabs.org
– Microframework (the missing link between Components and Framework)
● knpbundles.com– Database with additional bundles– StofDoctrineExtensionsBundle– LiipImagineBundle– FOQElasticaBundle– DoctrineFixturesBundle
?Questions?