[Doc] Use Markdown syntax highlighting

This commit is contained in:
Laurent Ghirardotti 2014-09-26 12:51:50 +02:00 committed by Fabien Potencier
parent c3feed6df2
commit 638ce847b3
21 changed files with 626 additions and 527 deletions

View File

@ -40,7 +40,7 @@
Before:
```
```yaml
framework:
session:
default_locale: fr
@ -48,7 +48,7 @@
After:
```
```yaml
framework:
default_locale: fr
```
@ -74,10 +74,10 @@
##### Simulate old behavior
You can simulate that the locale for the user is still stored in the session by
registering a listener that looks like the following if the parameter which
registering a listener that looks like the following if the parameter which
handles the locale value in the request is `_locale`:
```
```php
namespace XXX;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
@ -138,7 +138,7 @@
Before:
```
```php
class User implements UserInterface
{
// ...
@ -149,7 +149,7 @@
After:
```
```php
class User implements UserInterface, EquatableInterface
{
// ...
@ -165,13 +165,13 @@
Before:
``` yaml
```yaml
security:
factories:
- "%kernel.root_dir%/../src/Acme/DemoBundle/Resources/config/security_factories.yml"
```
``` yaml
```yaml
# src/Acme/DemoBundle/Resources/config/security_factories.yml
services:
security.authentication.factory.custom:
@ -182,7 +182,7 @@
After:
```
```php
namespace Acme\DemoBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
@ -212,7 +212,7 @@
Before:
``` yaml
```yaml
security:
providers:
my_chain_provider:
@ -225,7 +225,7 @@
After:
``` yaml
```yaml
security:
providers:
my_chain_provider:
@ -245,14 +245,14 @@
Before:
```
```php
use Symfony\Bundle\SecurityBundle\Validator\Constraint\UserPassword;
use Symfony\Bundle\SecurityBundle\Validator\Constraint as SecurityAssert;
```
After:
```
```php
use Symfony\Component\Security\Core\Validator\Constraint\UserPassword;
use Symfony\Component\Security\Core\Validator\Constraint as SecurityAssert;
```
@ -270,7 +270,7 @@
Before:
```
```php
use Symfony\Component\Form\FormBuilder;
public function buildForm(FormBuilder $builder, array $options)
@ -278,7 +278,7 @@
After:
```
```php
use Symfony\Component\Form\FormBuilderInterface;
public function buildForm(FormBuilderInterface $builder, array $options)
@ -301,7 +301,7 @@
Before:
```
```php
public function getParent(array $options)
{
return 'field';
@ -310,7 +310,7 @@
After:
```
```php
public function getParent()
{
return 'form';
@ -333,7 +333,7 @@
Before:
```
```php
public function getParent(array $options)
{
return $options['expanded'] ? 'form' : 'field';
@ -342,7 +342,7 @@
After:
```
```php
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\OptionsResolver\Options;
@ -374,7 +374,7 @@
Form mapped to an instance of `Person`:
```
```php
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
public function setDefaultOptions(OptionsResolverInterface $resolver)
@ -399,7 +399,7 @@
Before:
```
```php
$builder->add('name', 'text', array(
'property_path' => 'address.street',
));
@ -407,7 +407,7 @@
After (if the address object is an array):
```
```php
$builder->add('name', 'text', array(
'property_path' => 'address[street]',
));
@ -427,7 +427,7 @@
underscores wherever you specify a value for the field's "prototype_name"
option.
```
```php
$builder->add('tags', 'collection', array('prototype_name' => '__proto__'));
// results in the name "__proto__" in the template
@ -455,7 +455,7 @@
Before:
```
```jinja
{% block url_widget %}
{% spaceless %}
{% set type = type|default('url') %}
@ -466,7 +466,7 @@
After:
```
```jinja
{% block url_widget %}
{% spaceless %}
{% set type = type|default('url') %}
@ -482,7 +482,7 @@
Before:
```
```jinja
{% block form_errors %}
{% spaceless %}
... form code ...
@ -498,7 +498,7 @@
After:
```
```jinja
{% block form_errors %}
{% spaceless %}
{% if compound %}
@ -526,13 +526,13 @@
* In the choice field type's template, the `_form_is_choice_selected` method
used to identify a selected choice has been replaced with the `selectedchoice`
filter. Similarly, the `_form_is_choice_group` method used to check if a
choice is grouped has been removed and can be checked with the `iterable`
filter. Similarly, the `_form_is_choice_group` method used to check if a
choice is grouped has been removed and can be checked with the `iterable`
test.
Before:
```
```jinja
{% for choice, label in choices %}
{% if _form_is_choice_group(label) %}
<optgroup label="{{ choice|trans }}">
@ -550,7 +550,7 @@
After:
```
```jinja
{% for label, choice in choices %}
{% if choice is iterable %}
<optgroup label="{{ label|trans({}, translation_domain) }}">
@ -571,7 +571,7 @@
accommodate those cases when the `label` option has not been explicitly
set.
```
```jinja
{% block form_label %}
{% if label is empty %}
{% set label = name|humanize %}
@ -588,7 +588,7 @@
Before:
```
```jinja
{% block _author_tags_0_label %}
{# ... #}
{% endblock %}
@ -600,7 +600,7 @@
After:
```
```jinja
{% block _author_tags_entry_label %}
{# ... #}
{% endblock %}
@ -612,13 +612,13 @@
Before:
```
```php
<?php echo $view['form']->renderBlock('widget_attributes') ?>
```
After:
```
```php
<?php echo $view['form']->block($form, 'widget_attributes') ?>
```
@ -631,13 +631,13 @@
Before:
```
```php
$form = $factory->createNamed('text', 'firstName');
```
After:
```
```php
$form = $factory->createNamed('firstName', 'text');
```
@ -648,7 +648,7 @@
Before:
```
```php
class MyChoiceList extends ArrayChoiceList
{
protected function load()
@ -664,7 +664,7 @@
After:
```
```php
class MyChoiceList extends SimpleChoiceList
{
public function __construct()
@ -680,7 +680,7 @@
accessed for the first time -- you can extend `LazyChoiceList` instead
and load the choices by overriding `loadChoiceList()`.
```
```php
class MyChoiceList extends LazyChoiceList
{
protected function loadChoiceList()
@ -705,13 +705,13 @@
Before:
```
```jinja
{{ form_label(form.name, 'Your Name', { 'attr': {'class': 'foo'} }) }}
```
After:
```
```jinja
{{ form_label(form.name, 'Your Name', { 'label_attr': {'class': 'foo'} }) }}
```
@ -751,7 +751,7 @@
Before:
```
```php
public function getDefaultOptions(array $options)
{
return array(
@ -769,7 +769,7 @@
After:
```
```php
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
@ -786,7 +786,7 @@
Before:
```
```php
public function getDefaultOptions(array $options)
{
$defaultOptions = array();
@ -801,7 +801,7 @@
After:
```
```php
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
@ -832,13 +832,13 @@
Before:
```
```php
$builder->appendClientTransformer(new MyTransformer());
```
After:
```
```php
$builder->addViewTransformer(new MyTransformer());
```
@ -857,7 +857,7 @@
Before:
```
```php
$builder->addListener(FormEvents::BIND_CLIENT_DATA, function (FilterDataEvent $event) {
// ...
});
@ -865,7 +865,7 @@
After:
```
```php
$builder->addListener(FormEvents::PRE_BIND, function (FormEvent $event) {
// ...
});
@ -886,7 +886,7 @@
Before:
```
```php
public function guessMinLength($class, $property)
{
if (/* condition */) {
@ -897,7 +897,7 @@
After:
```
```php
public function guessPattern($class, $property)
{
if (/* condition */) {
@ -914,7 +914,7 @@
Before:
```
```php
$builder->add('termsAccepted', 'checkbox', array(
'property_path' => false,
));
@ -922,7 +922,7 @@
After:
```
```php
$builder->add('termsAccepted', 'checkbox', array(
'mapped' => false,
));
@ -944,13 +944,13 @@
Before:
```
```php
$form->getErrorBubbling()
```
After:
```
```php
$form->getConfig()->getErrorBubbling();
```
@ -962,13 +962,13 @@
Before:
```
```php
if ($form->hasChildren()) {
```
After:
```
```php
if (count($form) > 0) {
```
@ -976,13 +976,13 @@
Before:
```
```php
$form->bindRequest($request);
```
After:
```
```php
$form->bind($request);
```
@ -992,7 +992,7 @@
Before:
```
```php
$builder->add('name', 'text', array(
'validation_constraint' => new NotBlank(),
));
@ -1000,7 +1000,7 @@
After:
```
```php
$builder->add('name', 'text', array(
'constraints' => new NotBlank(),
));
@ -1008,7 +1008,7 @@
Unlike previously, you can also pass a list of constraints now:
```
```php
$builder->add('name', 'text', array(
'constraints' => array(
new NotBlank(),
@ -1021,7 +1021,7 @@
to the validated group! So if you validate a form in group "Custom"
and previously did:
```
```php
$builder->add('name', 'text', array(
'validation_constraint' => new NotBlank(),
));
@ -1029,7 +1029,7 @@
Then you need to add the constraint to the group "Custom" now:
```
```php
$builder->add('name', 'text', array(
'constraints' => new NotBlank(array('groups' => 'Custom')),
));
@ -1041,7 +1041,7 @@
Before:
```
```php
$builder->add('scheduledFor', 'date', array(
'data_timezone' => 'UTC',
'user_timezone' => 'America/New_York',
@ -1050,7 +1050,7 @@
After:
```
```php
$builder->add('scheduledFor', 'date', array(
'model_timezone' => 'UTC',
'view_timezone' => 'America/New_York',
@ -1063,13 +1063,13 @@
Before:
```
```php
$this->get('form.factory')->addType(new MyFormType());
```
After:
```
```php
$registry = $this->get('form.registry');
$registry->addType($registry->resolveType(new MyFormType()));
@ -1098,14 +1098,14 @@
Before:
```
```php
$view->set('help', 'A text longer than six characters');
$view->set('error_class', 'max_length_error');
```
After:
```
```php
$view->vars = array_replace($view->vars, array(
'help' => 'A text longer than six characters',
'error_class' => 'max_length_error',
@ -1114,25 +1114,25 @@
Before:
```
```php
echo $view->get('error_class');
```
After:
```
```php
echo $view->vars['error_class'];
```
Before:
```
```php
if ($view->hasChildren()) { ...
```
After:
```
```php
if (count($view->children)) { ...
```
@ -1147,7 +1147,7 @@
Before:
```
```php
public function isValid($value, Constraint $constraint)
{
// ...
@ -1163,7 +1163,7 @@
After:
```
```php
public function isValid($value, Constraint $constraint)
{
// ...
@ -1185,7 +1185,7 @@
Before:
```
```php
public function isPropertyValid(ExecutionContext $context)
{
// ...
@ -1197,7 +1197,7 @@
After:
```
```php
public function isPropertyValid(ExecutionContext $context)
{
// ...
@ -1216,7 +1216,7 @@
Before:
```
```php
public function isValid($value, Constraint $constraint)
{
// ...
@ -1232,7 +1232,7 @@
After:
```
```php
public function validate($value, Constraint $constraint)
{
// ...
@ -1259,14 +1259,14 @@
Before:
```
```php
/** @Assert\Valid */
private $recursiveCollection;
```
After:
```
```php
/** @Assert\Valid(deep = true) */
private $recursiveCollection;
```
@ -1276,28 +1276,28 @@
Before:
```
```php
/** @Assert\Size(min = 2, max = 16) */
private $numberOfCpus;
```
After:
```
```php
/** @Assert\Range(min = 2, max = 16) */
private $numberOfCpus;
```
Before:
```
```php
/** @Assert\Min(2) */
private $numberOfCpus;
```
After:
```
```php
/** @Assert\Range(min = 2) */
private $numberOfCpus;
```
@ -1307,14 +1307,14 @@
Before:
```
```php
/** @Assert\MinLength(8) */
private $password;
```
After:
```
```php
/** @Assert\Length(min = 8) */
private $password;
```
@ -1325,14 +1325,14 @@
Before:
```
```php
$validator = ValidatorFactory::buildDefault(array('path/to/mapping.xml'))
->getValidator();
```
After:
```
```php
$validator = Validation::createValidatorBuilder()
->addXmlMapping('path/to/mapping.xml')
->getValidator();
@ -1349,7 +1349,7 @@
Before:
```
```jinja
{% if app.session.hasFlash('notice') %}
<div class="flash-notice">
{{ app.session.getFlash('notice') }}
@ -1358,7 +1358,7 @@
```
After:
```
```jinja
{% for flashMessage in app.session.flashbag.get('notice') %}
<div class="flash-notice">
{{ flashMessage }}
@ -1368,7 +1368,7 @@
You can process all flash messages in a single loop with:
```
```jinja
{% for type, flashMessages in app.session.flashbag.all() %}
{% for flashMessage in flashMessages %}
<div class="flash-{{ type }}">
@ -1391,7 +1391,7 @@
* The `item` element is now converted to an array when deserializing XML.
``` xml
```xml
<?xml version="1.0"?>
<response>
<item><title><![CDATA[title1]]></title></item><item><title><![CDATA[title2]]></title></item>
@ -1433,7 +1433,7 @@
Before:
```
```yaml
framework:
session:
lifetime: 3600
@ -1445,7 +1445,7 @@
After:
```
```yaml
framework:
session:
cookie_lifetime: 3600
@ -1457,7 +1457,7 @@
Added `handler_id`, defaults to `session.handler.native_file`.
```
```yaml
framework:
session:
storage_id: session.storage.native
@ -1466,7 +1466,7 @@ Added `handler_id`, defaults to `session.handler.native_file`.
To use mock session storage use the following. `handler_id` is irrelevant in this context.
```
```yaml
framework:
session:
storage_id: session.storage.mock_file

View File

@ -7,13 +7,13 @@
Before:
```
```jinja
{% render 'BlogBundle:Post:list' with { 'limit': 2 }, { 'alt': 'BlogBundle:Post:error' } %}
```
After:
```
```jinja
{% render controller('BlogBundle:Post:list', { 'limit': 2 }), { 'alt': 'BlogBundle:Post:error' } %}
{# Or: #}
{{ render(controller('BlogBundle:Post:list', { 'limit': 2 }), { 'alt': 'BlogBundle:Post:error'}) }}
@ -29,7 +29,7 @@
Before:
```
```jinja
{% render 'BlogBundle:Post:list' with { 'limit': 2 }, {'standalone': true} %}
{% render 'BlogBundle:Post:list' with { 'limit': 2 }, {'standalone': false} %}
{% render 'BlogBundle:Post:list' with { 'limit': 2 }, {'standalone': 'js'} %}
@ -37,7 +37,7 @@
After:
```
```jinja
{{ render(controller('BlogBundle:Post:list', { 'limit': 2 }), { 'strategy': 'esi'}) }}
{{ render(controller('BlogBundle:Post:list', { 'limit': 2 }), { 'strategy': 'inline'}) }}
{{ render(controller('BlogBundle:Post:list', { 'limit': 2 }), { 'strategy': 'hinclude'}) }}
@ -65,7 +65,7 @@
You should now use the `AcceptHeader` class which give you fluent methods to
parse request accept-* headers. Some examples:
```
```php
$accept = AcceptHeader::fromString($request->headers->get('Accept'));
if ($accept->has('text/html') {
$item = $accept->get('html');
@ -95,7 +95,7 @@
Before:
```
```jinja
{{
error.messagePluralization is null
? error.messageTemplate|trans(error.messageParameters, 'validators')
@ -105,7 +105,7 @@
After:
```
```jinja
{{ error.message }}
```
@ -117,7 +117,7 @@
Before:
```
```php
use Symfony\Component\Form\Extensions\Core\DataMapper\PropertyPathMapper;
class CustomMapper extends PropertyPathMapper
@ -133,7 +133,7 @@
After:
```
```php
use Symfony\Component\Form\Extensions\Core\DataMapper\PropertyPathMapper;
class CustomMapper extends PropertyPathMapper
@ -163,7 +163,7 @@
Before:
```
```php
use Symfony\Component\Form\Util\PropertyPath;
use Symfony\Component\Form\Util\PropertyPathBuilder;
use Symfony\Component\Form\Util\PropertyPathInterface;
@ -176,7 +176,7 @@
After:
```
```php
use Symfony\Component\PropertyAccess\PropertyPath;
use Symfony\Component\PropertyAccess\PropertyPathBuilder;
use Symfony\Component\PropertyAccess\PropertyPathInterface;
@ -192,7 +192,7 @@
Before:
```
```php
use Symfony\Component\Form\Util\FormUtil;
$singular = FormUtil::singularify($plural);
@ -200,7 +200,7 @@
After:
```
```php
use Symfony\Component\PropertyAccess\StringUtil;
$singular = StringUtil::singularify($plural);
@ -211,7 +211,7 @@
Before:
```
```php
use Symfony\Component\Form\Util\PropertyPath;
$propertyPath = new PropertyPath('some.path');
@ -222,7 +222,7 @@
After (alternative 1):
```
```php
use Symfony\Component\PropertyAccess\PropertyAccess;
$propertyAccessor = PropertyAccess::getPropertyAccessor();
@ -233,7 +233,7 @@
After (alternative 2):
```
```php
use Symfony\Component\PropertyAccess\PropertyAccess;
use Symfony\Component\PropertyAccess\PropertyPath;
@ -253,7 +253,7 @@
Before:
```
```php
$rootCollection = new RouteCollection();
$subCollection = new RouteCollection();
$rootCollection->addCollection($subCollection);
@ -262,7 +262,7 @@
After:
```
```php
$rootCollection = new RouteCollection();
$subCollection = new RouteCollection();
$subCollection->add('foo', new Route('/foo'));
@ -272,7 +272,7 @@
Also one must call `addCollection` from the bottom to the top hierarchy.
So the correct sequence is the following (and not the reverse):
```
```php
$childCollection->addCollection($grandchildCollection);
$rootCollection->addCollection($childCollection);
```
@ -298,7 +298,7 @@
use-case instead.
Before: `$parentCollection->addCollection($collection, '/prefix', array(...), array(...))`
After:
```
```php
$collection->addPrefix('/prefix', array(...), array(...));
$parentCollection->addCollection($collection);
```
@ -312,7 +312,7 @@
Before:
```
```php
use Symfony\Component\Validator\ExecutionContext;
public function validateCustomLogic(ExecutionContext $context)
@ -320,7 +320,7 @@
After:
```
```php
use Symfony\Component\Validator\ExecutionContextInterface;
public function validateCustomLogic(ExecutionContextInterface $context)
@ -331,7 +331,7 @@
Before:
```
```php
use Symfony\Component\Validator\ConstraintValidatorInterface;
use Symfony\Component\Validator\ExecutionContext;
@ -346,7 +346,7 @@
After:
```
```php
use Symfony\Component\Validator\ConstraintValidatorInterface;
use Symfony\Component\Validator\ExecutionContextInterface;
@ -391,7 +391,7 @@
Before:
```
```php
use Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface;
class MyMetadataFactory implements ClassMetadataFactoryInterface
@ -405,7 +405,7 @@
After:
```
```php
use Symfony\Component\Validator\MetadataFactoryInterface;
use Symfony\Component\Validator\Exception\NoSuchMetadataException;
@ -432,14 +432,14 @@
Before:
```
```php
$metadataFactory = $validator->getMetadataFactory();
$metadata = $metadataFactory->getClassMetadata('Vendor\MyClass');
```
After:
```
```php
$metadataFactory = $validator->getMetadataFactory();
$metadata = $metadataFactory->getMetadataFor('Vendor\MyClass');
```
@ -451,7 +451,7 @@
Before:
```
```php
use Symfony\Component\Validator\ExecutionContext;
public function validateCustomLogic(ExecutionContext $context)
@ -471,7 +471,7 @@
After:
```
```php
use Symfony\Component\Validator\ExecutionContextInterface;
public function validateCustomLogic(ExecutionContextInterface $context)
@ -488,7 +488,7 @@
Before:
```
```php
use Symfony\Component\Validator\ExecutionContext;
public function validateCustomLogic(ExecutionContext $context)
@ -501,7 +501,7 @@
After:
```
```php
use Symfony\Component\Validator\ExecutionContextInterface;
public function validateCustomLogic(ExecutionContextInterface $context)
@ -519,7 +519,7 @@
Before:
```
```php
use Symfony\Component\Validator\ExecutionContext;
public function validateCustomLogic(ExecutionContext $context)
@ -534,7 +534,7 @@
After:
```
```php
use Symfony\Component\Validator\ExecutionContextInterface;
public function validateCustomLogic(ExecutionContextInterface $context)
@ -553,20 +553,20 @@
Before:
```
```php
<?php echo $view['actions']->render('BlogBundle:Post:list', array('limit' => 2), array('alt' => 'BlogBundle:Post:error')) ?>
```
After:
```
```php
<?php echo $view['actions']->render($view['router']->generate('post_list', array('limit' => 2)), array('alt' => 'BlogBundle:Post:error')) ?>
```
where `post_list` is the route name for the `BlogBundle:Post:list`
controller, or if you don't want to create a route:
```
```php
<?php echo $view['actions']->render(new ControllerReference('BlogBundle:Post:list', array('limit' => 2)), array('alt' => 'BlogBundle:Post:error')) ?>
```
@ -577,7 +577,7 @@
Before:
```
```yaml
# app/config/config.yml
framework:
trust_proxy_headers: false
@ -585,7 +585,7 @@
After:
```
```yaml
# app/config/config.yml
framework:
trusted_proxies: ['127.0.0.1', '10.0.0.1'] # a list of proxy IPs you trust
@ -598,13 +598,13 @@
Before:
```
```php
use Symfony\Component\Security\Core\Validator\Constraint\UserPassword;
```
After: (note the `s` at the end of `Constraint`)
```
```php
use Symfony\Component\Security\Core\Validator\Constraints\UserPassword;
```
@ -612,7 +612,7 @@
``service`` option that allows to specify a custom validator service name in
order to validate the current logged-in user's password.
```
```php
use Symfony\Component\Security\Core\Validator\Constraints\UserPassword;
$constraint = new UserPassword(array(
@ -628,14 +628,14 @@
Before:
```
```php
use Symfony\Component\Security\Core\Validator\Constraint\UserPassword;
use Symfony\Component\Security\Core\Validator\Constraint\UserPasswordValidator;
```
After:
```
```php
use Symfony\Component\Security\Core\Validator\Constraints\UserPassword;
use Symfony\Component\Security\Core\Validator\Constraints\UserPasswordValidator;
```

View File

@ -41,7 +41,7 @@ Form
Before:
```
```php
use Symfony\Component\Form\DataMapperInterface;
class MyDataMapper
@ -60,7 +60,7 @@ Form
After:
```
```php
use Symfony\Component\Form\DataMapperInterface;
class MyDataMapper
@ -84,7 +84,7 @@ Form
Before:
```
```php
use Symfony\Component\Form\Util\VirtualFormAwareIterator;
public function mapFormsToData(array $forms, $data)
@ -101,7 +101,7 @@ Form
After:
```
```php
public function mapFormsToData($forms, $data)
{
foreach ($forms as $form) {
@ -121,7 +121,7 @@ Form
Before:
```
```php
$form = $factory->create('form');
$form->add($factory->createNamed('field', 'text'));
```
@ -135,7 +135,7 @@ Form
After (Alternative 1):
```
```php
$form = $factory->create('form');
$form->add($factory->createNamed('field', 'text', array(), array(
'auto_initialize' => false,
@ -147,7 +147,7 @@ Form
After (Alternative 2):
```
```php
$builder = $factory->createBuilder('form');
$builder->add($factory->createBuilder('field', 'text'));
$form = $builder->getForm();
@ -157,14 +157,14 @@ Form
After (Alternative 3):
```
```php
$form = $factory->create('form');
$form->add('field', 'text');
```
After (Alternative 4):
```
```php
$builder = $factory->createBuilder('form');
$builder->add('field', 'text');
$form = $builder->getForm();
@ -180,7 +180,7 @@ Form
Before:
```
```php
$builder->add('field', 'text', array(
'data' => $defaultData ?: null,
));
@ -188,7 +188,7 @@ Form
After:
```
```php
$options = array();
if ($defaultData) {
$options['data'] = $defaultData;
@ -203,7 +203,7 @@ PropertyAccess
even if a non-public match was found. This means that the property "author"
in the following class will now correctly be found:
```
```php
class Article
{
public $author;
@ -224,7 +224,7 @@ PropertyAccess
Before:
```
```php
use Symfony\Component\PropertyAccess\Exception\PropertyAccessDeniedException;
use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException;
@ -239,7 +239,7 @@ PropertyAccess
After:
```
```php
use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException;
try {
@ -257,7 +257,7 @@ DomCrawler
Before:
```
```php
$data = $crawler->each(function ($node, $i) {
return $node->nodeValue;
});
@ -265,7 +265,7 @@ DomCrawler
After:
```
```php
$data = $crawler->each(function ($crawler, $i) {
return $crawler->text();
});
@ -280,13 +280,13 @@ Console
Before:
```
```php
if (OutputInterface::VERBOSITY_VERBOSE === $output->getVerbosity()) { ... }
```
After:
```
```php
if (OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) { ... }
```

View File

@ -25,13 +25,13 @@ UPGRADE FROM 2.x to 3.0
Before:
```
```php
$form->bind(array(...));
```
After:
```
```php
$form->submit(array(...));
```
@ -42,7 +42,7 @@ UPGRADE FROM 2.x to 3.0
Before:
```
```php
if ('POST' === $request->getMethod()) {
$form->bind($request);
@ -54,7 +54,7 @@ UPGRADE FROM 2.x to 3.0
After:
```
```php
$form->handleRequest($request);
if ($form->isValid()) {
@ -65,7 +65,7 @@ UPGRADE FROM 2.x to 3.0
If you want to test whether the form was submitted separately, you can use
the method `isSubmitted()`:
```
```php
$form->handleRequest($request);
if ($form->isSubmitted()) {
@ -82,7 +82,7 @@ UPGRADE FROM 2.x to 3.0
Before:
```
```php
$builder->addEventListener(FormEvents::PRE_BIND, function (FormEvent $event) {
// ...
});
@ -90,7 +90,7 @@ UPGRADE FROM 2.x to 3.0
After:
```
```php
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
// ...
});
@ -100,7 +100,7 @@ UPGRADE FROM 2.x to 3.0
Before:
```
```php
$builder->add('address', 'form', array(
'virtual' => true,
));
@ -108,7 +108,7 @@ UPGRADE FROM 2.x to 3.0
After:
```
```php
$builder->add('address', 'form', array(
'inherit_data' => true,
));
@ -118,7 +118,7 @@ UPGRADE FROM 2.x to 3.0
Before:
```
```php
use Symfony\Component\Form\Util\VirtualFormAwareIterator;
$iterator = new VirtualFormAwareIterator($forms);
@ -126,17 +126,17 @@ UPGRADE FROM 2.x to 3.0
After:
```
```php
use Symfony\Component\Form\Util\InheritDataAwareIterator;
$iterator = new InheritDataAwareIterator($forms);
```
* The `TypeTestCase` class was moved from the `Symfony\Component\Form\Tests\Extension\Core\Type` namespace to the `Symfony\Component\Form\Test` namespace.
Before:
```
```php
use Symfony\Component\Form\Tests\Extension\Core\Type\TypeTestCase
class MyTypeTest extends TypeTestCase
@ -147,7 +147,7 @@ UPGRADE FROM 2.x to 3.0
After:
```
```php
use Symfony\Component\Form\Test\TypeTestCase;
class MyTypeTest extends TypeTestCase
@ -166,7 +166,7 @@ UPGRADE FROM 2.x to 3.0
Before:
```
```php
<form method="post" action="http://example.com" <?php echo $view['form']->enctype($form) ?>>
...
</form>
@ -174,7 +174,7 @@ UPGRADE FROM 2.x to 3.0
After:
```
```php
<?php echo $view['form']->start($form) ?>
...
<?php echo $view['form']->end($form) ?>
@ -186,7 +186,7 @@ UPGRADE FROM 2.x to 3.0
Alternative 1:
```
```php
$form = $this->createForm('my_form', $formData, array(
'method' => 'PUT',
'action' => $this->generateUrl('target_route'),
@ -195,7 +195,7 @@ UPGRADE FROM 2.x to 3.0
Alternative 2:
```
```php
$form = $this->createFormBuilder($formData)
// ...
->setMethod('PUT')
@ -205,7 +205,7 @@ UPGRADE FROM 2.x to 3.0
It is also possible to override the method and the action in the template:
```
```php
<?php echo $view['form']->start($form, array('method' => 'GET', 'action' => 'http://example.com')) ?>
...
<?php echo $view['form']->end($form) ?>
@ -245,7 +245,7 @@ UPGRADE FROM 2.x to 3.0
* The Locale component was removed and replaced by the Intl component.
Instead of the methods in `Symfony\Component\Locale\Locale`, you should use
these equivalent methods in `Symfony\Component\Intl\Intl` now:
* `Locale::getDisplayCountries()` -> `Intl::getRegionBundle()->getCountryNames()`
* `Locale::getCountries()` -> `array_keys(Intl::getRegionBundle()->getCountryNames())`
* `Locale::getDisplayLanguages()` -> `Intl::getLanguageBundle()->getLanguageNames()`
@ -259,7 +259,7 @@ UPGRADE FROM 2.x to 3.0
Before:
```
```php
use Symfony\Component\PropertyAccess\PropertyAccess;
$accessor = PropertyAccess::getPropertyAccessor();
@ -267,7 +267,7 @@ UPGRADE FROM 2.x to 3.0
After:
```
```php
use Symfony\Component\PropertyAccess\PropertyAccess;
$accessor = PropertyAccess::createPropertyAccessor();
@ -282,17 +282,21 @@ UPGRADE FROM 2.x to 3.0
Before:
```
```yaml
article_edit:
pattern: /article/{id}
requirements: { '_method': 'POST|PUT', '_scheme': 'https', 'id': '\d+' }
```
```xml
<route id="article_edit" pattern="/article/{id}">
<requirement key="_method">POST|PUT</requirement>
<requirement key="_scheme">https</requirement>
<requirement key="id">\d+</requirement>
</route>
```
```php
$route = new Route();
$route->setPattern('/article/{id}');
$route->setRequirement('_method', 'POST|PUT');
@ -301,17 +305,21 @@ UPGRADE FROM 2.x to 3.0
After:
```
```yaml
article_edit:
path: /article/{id}
methods: [POST, PUT]
schemes: https
requirements: { 'id': '\d+' }
```
```xml
<route id="article_edit" path="/article/{id}" methods="POST PUT" schemes="https">
<requirement key="id">\d+</requirement>
</route>
```
```php
$route = new Route();
$route->setPath('/article/{id}');
$route->setMethods(array('POST', 'PUT'));
@ -332,7 +340,7 @@ UPGRADE FROM 2.x to 3.0
Before:
```
```php
<form method="post" action="http://example.com" {{ form_enctype(form) }}>
...
</form>
@ -340,7 +348,7 @@ UPGRADE FROM 2.x to 3.0
After:
```
```jinja
{{ form_start(form) }}
...
{{ form_end(form) }}
@ -352,7 +360,7 @@ UPGRADE FROM 2.x to 3.0
Alternative 1:
```
```php
$form = $this->createForm('my_form', $formData, array(
'method' => 'PUT',
'action' => $this->generateUrl('target_route'),
@ -361,7 +369,7 @@ UPGRADE FROM 2.x to 3.0
Alternative 2:
```
```php
$form = $this->createFormBuilder($formData)
// ...
->setMethod('PUT')
@ -371,7 +379,7 @@ UPGRADE FROM 2.x to 3.0
It is also possible to override the method and the action in the template:
```
```jinja
{{ form_start(form, {'method': 'GET', 'action': 'http://example.com'}) }}
...
{{ form_end(form) }}
@ -385,7 +393,7 @@ UPGRADE FROM 2.x to 3.0
Before:
```
```php
use Symfony\Component\Validator\Constraints as Assert;
/**
@ -399,7 +407,7 @@ UPGRADE FROM 2.x to 3.0
After:
```
```php
use Symfony\Component\Validator\Constraints as Assert;
/**
@ -417,12 +425,12 @@ UPGRADE FROM 2.x to 3.0
Before:
```
```php
Yaml::parse($fileName);
```
After:
```
```php
Yaml::parse(file_get_contents($fileName));
```

View File

@ -9,51 +9,63 @@ standard or the PEAR naming convention.
First, register the autoloader:
require_once __DIR__.'/src/Symfony/Component/ClassLoader/UniversalClassLoader.php';
```php
require_once __DIR__.'/src/Symfony/Component/ClassLoader/UniversalClassLoader.php';
use Symfony\Component\ClassLoader\UniversalClassLoader;
use Symfony\Component\ClassLoader\UniversalClassLoader;
$loader = new UniversalClassLoader();
$loader->register();
$loader = new UniversalClassLoader();
$loader->register();
```
Then, register some namespaces with the `registerNamespace()` method:
$loader->registerNamespace('Symfony', __DIR__.'/src');
$loader->registerNamespace('Monolog', __DIR__.'/vendor/monolog/src');
```php
$loader->registerNamespace('Symfony', __DIR__.'/src');
$loader->registerNamespace('Monolog', __DIR__.'/vendor/monolog/src');
```
The `registerNamespace()` method takes a namespace prefix and a path where to
look for the classes as arguments.
You can also register a sub-namespaces:
$loader->registerNamespace('Doctrine\\Common', __DIR__.'/vendor/doctrine-common/lib');
```php
$loader->registerNamespace('Doctrine\\Common', __DIR__.'/vendor/doctrine-common/lib');
```
The order of registration is significant and the first registered namespace
takes precedence over later registered one.
You can also register more than one path for a given namespace:
$loader->registerNamespace('Symfony', array(__DIR__.'/src', __DIR__.'/symfony/src'));
```php
$loader->registerNamespace('Symfony', array(__DIR__.'/src', __DIR__.'/symfony/src'));
```
Alternatively, you can use the `registerNamespaces()` method to register more
than one namespace at once:
$loader->registerNamespaces(array(
'Symfony' => array(__DIR__.'/src', __DIR__.'/symfony/src'),
'Doctrine\\Common' => __DIR__.'/vendor/doctrine-common/lib',
'Doctrine' => __DIR__.'/vendor/doctrine/lib',
'Monolog' => __DIR__.'/vendor/monolog/src',
));
```php
$loader->registerNamespaces(array(
'Symfony' => array(__DIR__.'/src', __DIR__.'/symfony/src'),
'Doctrine\\Common' => __DIR__.'/vendor/doctrine-common/lib',
'Doctrine' => __DIR__.'/vendor/doctrine/lib',
'Monolog' => __DIR__.'/vendor/monolog/src',
));
```
For better performance, you can use the APC based version of the universal
class loader:
require_once __DIR__.'/src/Symfony/Component/ClassLoader/UniversalClassLoader.php';
require_once __DIR__.'/src/Symfony/Component/ClassLoader/ApcUniversalClassLoader.php';
```php
require_once __DIR__.'/src/Symfony/Component/ClassLoader/UniversalClassLoader.php';
require_once __DIR__.'/src/Symfony/Component/ClassLoader/ApcUniversalClassLoader.php';
use Symfony\Component\ClassLoader\ApcUniversalClassLoader;
use Symfony\Component\ClassLoader\ApcUniversalClassLoader;
$loader = new ApcUniversalClassLoader('apc.prefix.');
$loader = new ApcUniversalClassLoader('apc.prefix.');
```
Furthermore, the component provides tools to aggregate classes into a single
file, which is especially useful to improve performance on servers that do not

View File

@ -5,10 +5,12 @@ Console eases the creation of beautiful and testable command line interfaces.
The Application object manages the CLI application:
use Symfony\Component\Console\Application;
```php
use Symfony\Component\Console\Application;
$console = new Application();
$console->run();
$console = new Application();
$console->run();
```
The ``run()`` method parses the arguments and options passed on the command
line and executes the right command.
@ -16,23 +18,25 @@ line and executes the right command.
Registering a new command can easily be done via the ``register()`` method,
which returns a ``Command`` instance:
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
```php
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
$console
->register('ls')
->setDefinition(array(
new InputArgument('dir', InputArgument::REQUIRED, 'Directory name'),
))
->setDescription('Displays the files in the given directory')
->setCode(function (InputInterface $input, OutputInterface $output) {
$dir = $input->getArgument('dir');
$console
->register('ls')
->setDefinition(array(
new InputArgument('dir', InputArgument::REQUIRED, 'Directory name'),
))
->setDescription('Displays the files in the given directory')
->setCode(function (InputInterface $input, OutputInterface $output) {
$dir = $input->getArgument('dir');
$output->writeln(sprintf('Dir listing for <info>%s</info>', $dir));
})
;
$output->writeln(sprintf('Dir listing for <info>%s</info>', $dir));
})
;
```
You can also register new commands via classes.

View File

@ -6,9 +6,11 @@ CssSelector converts CSS selectors to XPath expressions.
The component only goal is to convert CSS selectors to their XPath
equivalents:
use Symfony\Component\CssSelector\CssSelector;
```php
use Symfony\Component\CssSelector\CssSelector;
print CssSelector::toXPath('div.item > h4 > a');
print CssSelector::toXPath('div.item > h4 > a');
```
HTML and XML are different
--------------------------
@ -18,11 +20,13 @@ default. If you need to use this component with `XML` documents, you have to
disable this `HTML` extension. That's because, `HTML` tag & attribute names
are always lower-cased, but case-sensitive in `XML`:
// disable `HTML` extension:
CssSelector::disableHtmlExtension();
```php
// disable `HTML` extension:
CssSelector::disableHtmlExtension();
// re-enable `HTML` extension:
CssSelector::enableHtmlExtension();
// re-enable `HTML` extension:
CssSelector::enableHtmlExtension();
```
When the `HTML` extension is enabled, tag names are lower-cased, attribute
names are lower-cased, the following extra pseudo-classes are supported:

View File

@ -6,23 +6,27 @@ Debug provides tools to make debugging easier.
Enabling all debug tools is as easy as calling the `enable()` method on the
main `Debug` class:
use Symfony\Component\Debug\Debug;
```php
use Symfony\Component\Debug\Debug;
Debug::enable();
Debug::enable();
```
You can also use the tools individually:
use Symfony\Component\Debug\ErrorHandler;
use Symfony\Component\Debug\ExceptionHandler;
```php
use Symfony\Component\Debug\ErrorHandler;
use Symfony\Component\Debug\ExceptionHandler;
error_reporting(-1);
error_reporting(-1);
ErrorHandler::register($errorReportingLevel);
if ('cli' !== php_sapi_name()) {
ExceptionHandler::register();
} elseif (!ini_get('log_errors') || ini_get('error_log')) {
ini_set('display_errors', 1);
}
ErrorHandler::register($errorReportingLevel);
if ('cli' !== php_sapi_name()) {
ExceptionHandler::register();
} elseif (!ini_get('log_errors') || ini_get('error_log')) {
ini_set('display_errors', 1);
}
```
Note that the `Debug::enable()` call also registers the debug class loader
from the Symfony ClassLoader component when available.

View File

@ -6,45 +6,51 @@ Injection Container.
Here is a simple example that shows how to register services and parameters:
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
```php
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
$sc = new ContainerBuilder();
$sc
->register('foo', '%foo.class%')
->addArgument(new Reference('bar'))
;
$sc->setParameter('foo.class', 'Foo');
$sc = new ContainerBuilder();
$sc
->register('foo', '%foo.class%')
->addArgument(new Reference('bar'))
;
$sc->setParameter('foo.class', 'Foo');
$sc->get('foo');
$sc->get('foo');
```
Method Calls (Setter Injection):
$sc = new ContainerBuilder();
```php
$sc = new ContainerBuilder();
$sc
->register('bar', '%bar.class%')
->addMethodCall('setFoo', array(new Reference('foo')))
;
$sc->setParameter('bar.class', 'Bar');
$sc
->register('bar', '%bar.class%')
->addMethodCall('setFoo', array(new Reference('foo')))
;
$sc->setParameter('bar.class', 'Bar');
$sc->get('bar');
$sc->get('bar');
```
Factory Class:
If your service is retrieved by calling a static method:
$sc = new ContainerBuilder();
```php
$sc = new ContainerBuilder();
$sc
->register('bar', '%bar.class%')
->setFactoryClass('%bar.class%')
->setFactoryMethod('getInstance')
->addArgument('Aarrg!!!')
;
$sc->setParameter('bar.class', 'Bar');
$sc
->register('bar', '%bar.class%')
->setFactoryClass('%bar.class%')
->setFactoryMethod('getInstance')
->addArgument('Aarrg!!!')
;
$sc->setParameter('bar.class', 'Bar');
$sc->get('bar');
$sc->get('bar');
```
File Include:
@ -52,16 +58,18 @@ For some services, especially those that are difficult or impossible to
autoload, you may need the container to include a file before
instantiating your class.
$sc = new ContainerBuilder();
```php
$sc = new ContainerBuilder();
$sc
->register('bar', '%bar.class%')
->setFile('/path/to/file')
->addArgument('Aarrg!!!')
;
$sc->setParameter('bar.class', 'Bar');
$sc
->register('bar', '%bar.class%')
->setFile('/path/to/file')
->addArgument('Aarrg!!!')
;
$sc->setParameter('bar.class', 'Bar');
$sc->get('bar');
$sc->get('bar');
```
Resources
---------

View File

@ -5,22 +5,26 @@ DomCrawler eases DOM navigation for HTML and XML documents.
If you are familiar with jQuery, DomCrawler is a PHP equivalent:
use Symfony\Component\DomCrawler\Crawler;
```php
use Symfony\Component\DomCrawler\Crawler;
$crawler = new Crawler();
$crawler->addContent('<html><body><p>Hello World!</p></body></html>');
$crawler = new Crawler();
$crawler->addContent('<html><body><p>Hello World!</p></body></html>');
print $crawler->filterXPath('descendant-or-self::body/p')->text();
print $crawler->filterXPath('descendant-or-self::body/p')->text();
```
If you are also using the CssSelector component, you can use CSS Selectors
instead of XPath expressions:
use Symfony\Component\DomCrawler\Crawler;
```php
use Symfony\Component\DomCrawler\Crawler;
$crawler = new Crawler();
$crawler->addContent('<html><body><p>Hello World!</p></body></html>');
$crawler = new Crawler();
$crawler->addContent('<html><body><p>Hello World!</p></body></html>');
print $crawler->filter('body > p')->text();
print $crawler->filter('body > p')->text();
```
Resources
---------

View File

@ -4,16 +4,18 @@ EventDispatcher Component
The Symfony2 EventDispatcher component implements the Mediator pattern in a
simple and effective way to make your projects truly extensible.
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\Event;
```php
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\Event;
$dispatcher = new EventDispatcher();
$dispatcher = new EventDispatcher();
$dispatcher->addListener('event_name', function (Event $event) {
// ...
});
$dispatcher->addListener('event_name', function (Event $event) {
// ...
});
$dispatcher->dispatch('event_name');
$dispatcher->dispatch('event_name');
```
Resources
---------

View File

@ -3,32 +3,36 @@ Finder Component
Finder finds files and directories via an intuitive fluent interface.
use Symfony\Component\Finder\Finder;
```php
use Symfony\Component\Finder\Finder;
$finder = new Finder();
$finder = new Finder();
$iterator = $finder
->files()
->name('*.php')
->depth(0)
->size('>= 1K')
->in(__DIR__);
$iterator = $finder
->files()
->name('*.php')
->depth(0)
->size('>= 1K')
->in(__DIR__);
foreach ($iterator as $file) {
print $file->getRealpath()."\n";
}
foreach ($iterator as $file) {
print $file->getRealpath()."\n";
}
```
But you can also use it to find files stored remotely like in this example where
we are looking for files on Amazon S3:
$s3 = new \Zend_Service_Amazon_S3($key, $secret);
$s3->registerStreamWrapper("s3");
```php
$s3 = new \Zend_Service_Amazon_S3($key, $secret);
$s3->registerStreamWrapper("s3");
$finder = new Finder();
$finder->name('photos*')->size('< 100K')->date('since 1 hour ago');
foreach ($finder->in('s3://bucket-name') as $file) {
print $file->getFilename()."\n";
}
$finder = new Finder();
$finder->name('photos*')->size('< 100K')->date('since 1 hour ago');
foreach ($finder->in('s3://bucket-name') as $file) {
print $file->getFilename()."\n";
}
```
Resources
---------
@ -38,4 +42,3 @@ You can run the unit tests with the following command:
$ cd path/to/Symfony/Component/Finder/
$ composer.phar install
$ phpunit

View File

@ -9,21 +9,27 @@ sessions, ...
In this example, we get a Request object from the current PHP global
variables:
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
```php
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
$request = Request::createFromGlobals();
echo $request->getPathInfo();
$request = Request::createFromGlobals();
echo $request->getPathInfo();
```
You can also create a Request directly -- that's interesting for unit testing:
$request = Request::create('/?foo=bar', 'GET');
echo $request->getPathInfo();
```php
$request = Request::create('/?foo=bar', 'GET');
echo $request->getPathInfo();
```
And here is how to create and send a Response:
$response = new Response('Not Found', 404, array('Content-Type' => 'text/plain'));
$response->send();
```php
$response = new Response('Not Found', 404, array('Content-Type' => 'text/plain'));
$response->send();
```
The Request and the Response classes have many other methods that implement
the HTTP specification.
@ -33,10 +39,12 @@ Loading
If you are not using Composer but are using PHP 5.3.x, you must add the following to your autoloader:
// SessionHandlerInterface
if (!interface_exists('SessionHandlerInterface')) {
$loader->registerPrefixFallback(__DIR__.'/../vendor/symfony/src/Symfony/Component/HttpFoundation/Resources/stubs');
}
```php
// SessionHandlerInterface
if (!interface_exists('SessionHandlerInterface')) {
$loader->registerPrefixFallback(__DIR__.'/../vendor/symfony/src/Symfony/Component/HttpFoundation/Resources/stubs');
}
```
Resources
---------

View File

@ -7,17 +7,19 @@ frameworks.
``HttpKernelInterface`` is the core interface of the Symfony2 full-stack
framework:
interface HttpKernelInterface
{
/**
* Handles a Request to convert it to a Response.
*
* @param Request $request A Request instance
*
* @return Response A Response instance
*/
function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true);
}
```php
interface HttpKernelInterface
{
/**
* Handles a Request to convert it to a Response.
*
* @param Request $request A Request instance
*
* @return Response A Response instance
*/
function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true);
}
```
It takes a ``Request`` as an input and should return a ``Response`` as an
output. Using this interface makes your code compatible with all frameworks
@ -27,28 +29,30 @@ free.
Creating a framework based on the Symfony2 components is really easy. Here is
a very simple, but fully-featured framework based on the Symfony2 components:
$routes = new RouteCollection();
$routes->add('hello', new Route('/hello', array('_controller' =>
function (Request $request) {
return new Response(sprintf("Hello %s", $request->get('name')));
}
)));
```php
$routes = new RouteCollection();
$routes->add('hello', new Route('/hello', array('_controller' =>
function (Request $request) {
return new Response(sprintf("Hello %s", $request->get('name')));
}
)));
$request = Request::createFromGlobals();
$request = Request::createFromGlobals();
$context = new RequestContext();
$context->fromRequest($request);
$context = new RequestContext();
$context->fromRequest($request);
$matcher = new UrlMatcher($routes, $context);
$matcher = new UrlMatcher($routes, $context);
$dispatcher = new EventDispatcher();
$dispatcher->addSubscriber(new RouterListener($matcher));
$dispatcher = new EventDispatcher();
$dispatcher->addSubscriber(new RouterListener($matcher));
$resolver = new ControllerResolver();
$resolver = new ControllerResolver();
$kernel = new HttpKernel($dispatcher, $resolver);
$kernel = new HttpKernel($dispatcher, $resolver);
$kernel->handle($request)->send();
$kernel->handle($request)->send();
```
This is all you need to create a flexible framework with the Symfony2
components.
@ -56,24 +60,30 @@ components.
Want to add an HTTP reverse proxy and benefit from HTTP caching and Edge Side
Includes?
$kernel = new HttpKernel($dispatcher, $resolver);
```php
$kernel = new HttpKernel($dispatcher, $resolver);
$kernel = new HttpCache($kernel, new Store(__DIR__.'/cache'));
$kernel = new HttpCache($kernel, new Store(__DIR__.'/cache'));
```
Want to functional test this small framework?
$client = new Client($kernel);
$crawler = $client->request('GET', '/hello/Fabien');
```php
$client = new Client($kernel);
$crawler = $client->request('GET', '/hello/Fabien');
$this->assertEquals('Fabien', $crawler->filter('p > span')->text());
$this->assertEquals('Fabien', $crawler->filter('p > span')->text());
```
Want nice error pages instead of ugly PHP exceptions?
$dispatcher->addSubscriber(new ExceptionListener(function (Request $request) {
$msg = 'Something went wrong! ('.$request->get('exception')->getMessage().')';
```php
$dispatcher->addSubscriber(new ExceptionListener(function (Request $request) {
$msg = 'Something went wrong! ('.$request->get('exception')->getMessage().')';
return new Response($msg, 500);
}));
return new Response($msg, 500);
}));
```
And that's why the simple looking ``HttpKernelInterface`` is so powerful. It
gives you access to a lot of cool features, ready to be used out of the box,

View File

@ -12,88 +12,96 @@ The following example demonstrates a Person class with two required options
the default value of "gender" is derived from the passed first name, if
possible, and may only be one of "male" and "female".
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\OptionsResolver\Options;
```php
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\OptionsResolver\Options;
class Person
class Person
{
protected $options;
public function __construct(array $options = array())
{
protected $options;
$resolver = new OptionsResolver();
$this->setDefaultOptions($resolver);
public function __construct(array $options = array())
{
$resolver = new OptionsResolver();
$this->setDefaultOptions($resolver);
$this->options = $resolver->resolve($options);
}
protected function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setRequired(array(
'firstName',
'lastName',
));
$resolver->setDefaults(array(
'age' => null,
'gender' => function (Options $options) {
if (self::isKnownMaleName($options['firstName'])) {
return 'male';
}
return 'female';
},
));
$resolver->setAllowedValues(array(
'gender' => array('male', 'female'),
));
}
$this->options = $resolver->resolve($options);
}
protected function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setRequired(array(
'firstName',
'lastName',
));
$resolver->setDefaults(array(
'age' => null,
'gender' => function (Options $options) {
if (self::isKnownMaleName($options['firstName'])) {
return 'male';
}
return 'female';
},
));
$resolver->setAllowedValues(array(
'gender' => array('male', 'female'),
));
}
}
```
We can now easily instantiate a Person object:
// 'gender' is implicitly set to 'female'
$person = new Person(array(
'firstName' => 'Jane',
'lastName' => 'Doe',
));
```php
// 'gender' is implicitly set to 'female'
$person = new Person(array(
'firstName' => 'Jane',
'lastName' => 'Doe',
));
```
We can also override the default values of the optional options:
$person = new Person(array(
'firstName' => 'Abdullah',
'lastName' => 'Mogashi',
'gender' => 'male',
'age' => 30,
));
```php
$person = new Person(array(
'firstName' => 'Abdullah',
'lastName' => 'Mogashi',
'gender' => 'male',
'age' => 30,
));
```
Options can be added or changed in subclasses by overriding the `setDefaultOptions`
method:
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\OptionsResolver\Options;
```php
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\OptionsResolver\Options;
class Employee extends Person
class Employee extends Person
{
protected function setDefaultOptions(OptionsResolverInterface $resolver)
{
protected function setDefaultOptions(OptionsResolverInterface $resolver)
{
parent::setDefaultOptions($resolver);
parent::setDefaultOptions($resolver);
$resolver->setRequired(array(
'birthDate',
));
$resolver->setRequired(array(
'birthDate',
));
$resolver->setDefaults(array(
// $previousValue contains the default value configured in the
// parent class
'age' => function (Options $options, $previousValue) {
return self::calculateAge($options['birthDate']);
}
));
}
$resolver->setDefaults(array(
// $previousValue contains the default value configured in the
// parent class
'age' => function (Options $options, $previousValue) {
return self::calculateAge($options['birthDate']);
}
));
}
}
```

View File

@ -5,16 +5,18 @@ Process executes commands in sub-processes.
In this example, we run a simple directory listing and get the result back:
use Symfony\Component\Process\Process;
```php
use Symfony\Component\Process\Process;
$process = new Process('ls -lsa');
$process->setTimeout(3600);
$process->run();
if (!$process->isSuccessful()) {
throw new RuntimeException($process->getErrorOutput());
}
$process = new Process('ls -lsa');
$process->setTimeout(3600);
$process->run();
if (!$process->isSuccessful()) {
throw new RuntimeException($process->getErrorOutput());
}
print $process->getOutput();
print $process->getOutput();
```
You can think that this is easy to achieve with plain PHP but it's not especially
if you want to take care of the subtle differences between the different platforms.
@ -23,16 +25,18 @@ And if you want to be able to get some feedback in real-time, just pass an
anonymous function to the ``run()`` method and you will get the output buffer
as it becomes available:
use Symfony\Component\Process\Process;
```php
use Symfony\Component\Process\Process;
$process = new Process('ls -lsa');
$process->run(function ($type, $buffer) {
if (Process::ERR === $type) {
echo 'ERR > '.$buffer;
} else {
echo 'OUT > '.$buffer;
}
});
$process = new Process('ls -lsa');
$process->run(function ($type, $buffer) {
if (Process::ERR === $type) {
echo 'ERR > '.$buffer;
} else {
echo 'OUT > '.$buffer;
}
});
```
That's great if you want to execute a long running command (like rsync-ing files to a
remote server) and give feedback to the user in real-time.

View File

@ -16,17 +16,21 @@ CHANGELOG
Before:
```
```yaml
article_edit:
pattern: /article/{id}
requirements: { '_method': 'POST|PUT', '_scheme': 'https', 'id': '\d+' }
```
```xml
<route id="article_edit" pattern="/article/{id}">
<requirement key="_method">POST|PUT</requirement>
<requirement key="_scheme">https</requirement>
<requirement key="id">\d+</requirement>
</route>
```
```php
$route = new Route();
$route->setPattern('/article/{id}');
$route->setRequirement('_method', 'POST|PUT');
@ -35,17 +39,21 @@ CHANGELOG
After:
```
```yaml
article_edit:
path: /article/{id}
methods: [POST, PUT]
schemes: https
requirements: { 'id': '\d+' }
```
```xml
<route id="article_edit" pattern="/article/{id}" methods="POST PUT" schemes="https">
<requirement key="id">\d+</requirement>
</route>
```
```php
$route = new Route();
$route->setPath('/article/{id}');
$route->setMethods(array('POST', 'PUT'));
@ -59,7 +67,7 @@ CHANGELOG
Before:
```
```php
$rootCollection = new RouteCollection();
$subCollection = new RouteCollection();
$rootCollection->addCollection($subCollection);
@ -68,7 +76,7 @@ CHANGELOG
After:
```
```php
$rootCollection = new RouteCollection();
$subCollection = new RouteCollection();
$subCollection->add('foo', new Route('/foo'));
@ -78,8 +86,8 @@ CHANGELOG
Also one must call `addCollection` from the bottom to the top hierarchy.
So the correct sequence is the following (and not the reverse):
```
$childCollection->->addCollection($grandchildCollection);
```php
$childCollection->addCollection($grandchildCollection);
$rootCollection->addCollection($childCollection);
```
@ -105,7 +113,7 @@ CHANGELOG
use-case instead.
Before: `$parentCollection->addCollection($collection, '/prefix', array(...), array(...))`
After:
```
```php
$collection->addPrefix('/prefix', array(...), array(...));
$parentCollection->addCollection($collection);
```
@ -157,6 +165,6 @@ CHANGELOG
been used anyway without creating inconsistencies
* [BC BREAK] RouteCollection::remove also removes a route from parent
collections (not only from its children)
* added ConfigurableRequirementsInterface that allows to disable exceptions
* added ConfigurableRequirementsInterface that allows to disable exceptions
(and generate empty URLs instead) when generating a route with an invalid
parameter value

View File

@ -6,23 +6,25 @@ Routing associates a request with the code that will convert it to a response.
The example below demonstrates how you can set up a fully working routing
system:
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
```php
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$routes = new RouteCollection();
$routes->add('hello', new Route('/hello', array('controller' => 'foo')));
$routes = new RouteCollection();
$routes->add('hello', new Route('/hello', array('controller' => 'foo')));
$context = new RequestContext();
$context = new RequestContext();
// this is optional and can be done without a Request instance
$context->fromRequest(Request::createFromGlobals());
// this is optional and can be done without a Request instance
$context->fromRequest(Request::createFromGlobals());
$matcher = new UrlMatcher($routes, $context);
$matcher = new UrlMatcher($routes, $context);
$parameters = $matcher->match('/hello');
$parameters = $matcher->match('/hello');
```
Resources
---------

View File

@ -4,18 +4,20 @@ Translation Component
Translation provides tools for loading translation files and generating
translated strings from these including support for pluralization.
use Symfony\Component\Translation\Translator;
use Symfony\Component\Translation\MessageSelector;
use Symfony\Component\Translation\Loader\ArrayLoader;
```php
use Symfony\Component\Translation\Translator;
use Symfony\Component\Translation\MessageSelector;
use Symfony\Component\Translation\Loader\ArrayLoader;
$translator = new Translator('fr_FR', new MessageSelector());
$translator->setFallbackLocales(array('fr'));
$translator->addLoader('array', new ArrayLoader());
$translator->addResource('array', array(
'Hello World!' => 'Bonjour',
), 'fr');
$translator = new Translator('fr_FR', new MessageSelector());
$translator->setFallbackLocales(array('fr'));
$translator->addLoader('array', new ArrayLoader());
$translator->addResource('array', array(
'Hello World!' => 'Bonjour',
), 'fr');
echo $translator->trans('Hello World!')."\n";
echo $translator->trans('Hello World!')."\n";
```
Resources
---------

View File

@ -12,12 +12,14 @@ The component provides "validation constraints", which are simple objects
containing the rules for the validation. Let's validate a simple string
as an example:
use Symfony\Component\Validator\Validation;
use Symfony\Component\Validator\Constraints\Length;
```php
use Symfony\Component\Validator\Validation;
use Symfony\Component\Validator\Constraints\Length;
$validator = Validation::createValidator();
$validator = Validation::createValidator();
$violations = $validator->validateValue('Bernhard', new Length(array('min' => 10)));
$violations = $validator->validateValue('Bernhard', new Length(array('min' => 10)));
```
This validation will fail because the given string is shorter than ten
characters. The precise errors, here called "constraint violations", are
@ -26,24 +28,26 @@ If the violation list is empty, validation succeeded.
Validation of arrays is possible using the `Collection` constraint:
use Symfony\Component\Validator\Validation;
use Symfony\Component\Validator\Constraints as Assert;
```php
use Symfony\Component\Validator\Validation;
use Symfony\Component\Validator\Constraints as Assert;
$validator = Validation::createValidator();
$validator = Validation::createValidator();
$constraint = new Assert\Collection(array(
'name' => new Assert\Collection(array(
'first_name' => new Assert\Length(array('min' => 101)),
'last_name' => new Assert\Length(array('min' => 1)),
)),
'email' => new Assert\Email(),
'simple' => new Assert\Length(array('min' => 102)),
'gender' => new Assert\Choice(array(3, 4)),
'file' => new Assert\File(),
'password' => new Assert\Length(array('min' => 60)),
));
$constraint = new Assert\Collection(array(
'name' => new Assert\Collection(array(
'first_name' => new Assert\Length(array('min' => 101)),
'last_name' => new Assert\Length(array('min' => 1)),
)),
'email' => new Assert\Email(),
'simple' => new Assert\Length(array('min' => 102)),
'gender' => new Assert\Choice(array(3, 4)),
'file' => new Assert\File(),
'password' => new Assert\Length(array('min' => 60)),
));
$violations = $validator->validateValue($input, $constraint);
$violations = $validator->validateValue($input, $constraint);
```
Again, the validator returns the list of violations.
@ -52,45 +56,47 @@ a mapping you can put constraints onto properties and objects of classes.
Whenever an object of this class is validated, its properties and
method results are matched against the constraints.
use Symfony\Component\Validator\Validation;
use Symfony\Component\Validator\Constraints as Assert;
```php
use Symfony\Component\Validator\Validation;
use Symfony\Component\Validator\Constraints as Assert;
class User
class User
{
/**
* @Assert\Length(min = 3)
* @Assert\NotBlank
*/
private $name;
/**
* @Assert\Email
* @Assert\NotBlank
*/
private $email;
public function __construct($name, $email)
{
/**
* @Assert\Length(min = 3)
* @Assert\NotBlank
*/
private $name;
/**
* @Assert\Email
* @Assert\NotBlank
*/
private $email;
public function __construct($name, $email)
{
$this->name = $name;
$this->email = $email;
}
/**
* @Assert\True(message = "The user should have a Google Mail account")
*/
public function isGmailUser()
{
return false !== strpos($this->email, '@gmail.com');
}
$this->name = $name;
$this->email = $email;
}
$validator = Validation::createValidatorBuilder()
->enableAnnotationMapping()
->getValidator();
/**
* @Assert\True(message = "The user should have a Google Mail account")
*/
public function isGmailUser()
{
return false !== strpos($this->email, '@gmail.com');
}
}
$user = new User('John Doe', 'john@example.com');
$validator = Validation::createValidatorBuilder()
->enableAnnotationMapping()
->getValidator();
$violations = $validator->validate($user);
$user = new User('John Doe', 'john@example.com');
$violations = $validator->validate($user);
```
This example uses the annotation support of Doctrine Common to
map constraints to properties and methods. You can also map constraints

View File

@ -3,11 +3,13 @@ Yaml Component
YAML implements most of the YAML 1.2 specification.
use Symfony\Component\Yaml\Yaml;
```php
use Symfony\Component\Yaml\Yaml;
$array = Yaml::parse($file);
$array = Yaml::parse($file);
print Yaml::dump($array);
print Yaml::dump($array);
```
Resources
---------