SlideShare a Scribd company logo
The Naked Bundle
Matthias Noback
High Quality Symfony Bundles tutorial - Dutch PHP Conference 2014
Assuming you all have a
working project
https://github.com/matthiasnoback/
high-quality-bundles-project
Generate a bundle
Use app/console generate:bundle
Namespace: Dpc/Bundle/TutorialBundle
Bundle name: DpcTutorialBundle
Configuration: yml
Whole directory structure: yes
The full directory structure of a bundle:
What's wrong?
Too many comments
Routing and a controller
Translations
Twig templates
A useless test
You are not going to use it all,
but it will be committed!
Before we continue, clean up your
bundle
Remove the following files and directories:
Controller
Resources/doc
Resources/public
Resources/translations
Resources/views
Tests
Also remove any superfluous comments!
The official
view on
bundles
First-class citizens
Documentation » The Quick Tour » The Architecture
I think your code is more important than the framework,
which should be considered an implementation detail.
All your code lives in a
bundle
Documentation » The Book » Creating Pages in Symfony2
I don't think that's a good idea.
It contradicts the promise of reuse of "pre-built feature
packages".
Almost everything lives
inside a bundle
Documentation » Glossary
Which is not really true, because many things live inside
libraries (e.g. the Symfony components), which is good.
Best practices
Documentation » Cookbook » Bundles
Controllers
Controllers don't need to extend anything at all.
ContainerAware*should be avoided in all cases.
Tests
What's up with the 95%?
Twig
Why Twig? I though Symfony didn't care about this.
Documentation » The Book » Creating and Using Templates
The old view on bundles is
not sufficient anymore
People are reimplementing things because existing
solutions are too tightly coupled to a framework (or even a
specific version).
Why is it necessary to do all these things again for Symfony,
Laravel, Zend, CodeIgniter, CakePHP, etc.?
Last year I started working
on this
Then it became this
About bundles
A bundle is...
A thin layer of Framework-specific
configuration to make resources from some
library available in a Symfony2 application.
A "Symfony application"
meaning:
A project that depends on the Symfony FrameworkBundle.
Resources are
Routes (Symfony Routing Component)
Services (Symfony DependencyInjection Component)
Templates (Twig)
Form types (Symfony Form Component)
Mapping metadata (Doctrine ORM, MongoDB ODM, etc.)
Translations (Symfony Translation Component)
Commands (Symfony Console Component)
...?
So: a bundle is mainly configuration to make these resources
available, the rest is elsewhere in a library.
I also wrote
The challenge
Make the bundle as clean as possible
Entities
Create an entity
Use app/console doctrine:generate:entity
Specs
The entity shortcut name: DpcTutorialBundle:Post.
Configuration format: annotation
It has a title(string) field.
Run app/console doctrine:schema:createor
update --forceand make sure your entity has a
corresponding table in your database.
Let's say you've modelled the Post
entity very well
You may want to reuse this in other projects.
Yet it's only useful if that project uses Doctrine ORM too!
Why?
Annotations couple the Postclass to Doctrine ORM.
(Since annotations are classes!)
Also: why are my entities inside a
bundle?
They are not only useful inside a Symfony project.
Move the entity to another
namespace
E.g. DpcTutorialModelPost.
Create an XML mapping file
E.g. DpcTutorialModelMappingPost.orm.xml
<doctrine-mappingxmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-ma
http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entityname="DpcTutorialModelPost">
<idname="id"type="integer">
<generatorstrategy="AUTO"/>
</id>
<fieldname="title"type="string"/>
</entity>
</doctrine-mapping>
You can copy the basic XML from
/vendor/doctrine/orm/docs/en/reference/xml-
mapping.rst.
In fact
Always use XML mapping, it makes a lot of sense, and you
get auto-completion in your IDE!
Remove all ORM things (annotations) from the Postclass
If you are going to try the following at home:
Update DoctrineBundle
Modify composer.json:
{
"require":{
...
"doctrine/doctrine-bundle":"~1.2@dev"
}
}
Run composer update doctrine/doctrine-bundle
Add a compiler pass to your bundle
It will load the XML mapping files
useDoctrineBundleDoctrineBundleDependencyInjectionCompilerDoctrineOrmMappingsPass;
classDpcTutorialBundle
{
publicfunctionbuild(ContainerBuilder$container)
{
$container->addCompilerPass($this->buildMappingCompilerPass());
}
privatefunctionbuildMappingCompilerPass()
{
returnDoctrineOrmMappingsPass::createXmlMappingDriver(
array(
__DIR__.'/../../Test/Model/Mapping/'
=>'DpcTutorialModel'
)
);
}
}
What have we won?
Clean model classes
They are reusable in non-Symfony projects
They are reusable with different persistence libraries
Documentation » The Cookbook » Doctrine » How to provide model classes for several Doctrine
implementations
Controllers
Create a controller
Use app/console generate:controller
Specs
Name: DpcTutorialBundle:Post
Configuration: annotation
Template: twig
The route contains an idparameter.
Action: showAction
Route: /post/{id}/show
Implement the following logic
Modify the action to retrieve a Postentity from the
database:
publicfunctionshowAction(Post$post)
{
returnarray('post'=>$post);
}
Don't forget to register the route
#inthebundle'srouting.ymlfile:
DpcTutorialBundle_Controllers:
resource:"@DpcTutorialBundle/Controller"
type:"annotation"
By the way
Consider using XML for routing too!
For the same reasons
Does all of this really need
to be inside the bundle?
Move the controller class to the
library
Remove parent Controllerclass
We are going to inject every dependency by hand instead of
relying on the service container.
Create a service for the controller
services:
dpc_tutorial.post_controller:
class:DpcTutorialControllerPostController
Remove @Routeannotations
Instead: define actual routes in the bundle's routing.yml
file.
Use the service id of the controller instead of its class name.
dpc_tutorial.post_controller.show:
path:/post/{id}/show
defaults:
_controller:dpc_tutorial.post_controller:showAction
Remove @Templateannotations
Inject the templatingservice instead and use it to render
the template.
useSymfonyComponentHttpFoundationResponse;
useSymfonyComponentTemplatingEngineInterface;
classPostController
{
publicfunction__construct(EngineInterface$templating)
{
$this->templating=$templating;
}
publicfunctionshowAction(Post$post)
{
returnnewResponse(
$this->templating->render(
'DpcTutorialBundle:Post:show.html.twig',
array('post'=>$post)
)
);
}
}
services:
dpc_tutorial.post_controller:
class:DpcTutorialControllerPostController
arguments:
-@templating
What about the
Templates
Move the template to the library
E.g. from Dpc/Bundle/TutorialBundle/Resources/views/Post/show.html.twigto
Dpc/Tutorial/View/Post/show.html.twig
Change the template reference
$this->templating->render(
'@DpcTutorial/Post/show.html.twig',
array('post'=>$post)
)
Register the new location of the
templates
#inconfig.yml
twig:
...
paths:
"%kernel.root_dir%/../src/Dpc/Tutorial/View":DpcTutorial
Documentation » The Cookbook » Templating » How to use and Register namespaced Twig Paths
Well...
We don't want to ask users to modify their config.yml!
Let's prepend
configuration
useSymfonyComponentDependencyInjectionExtensionPrependExtensionInterface;
classDpcTutorialExtensionextendsConfigurableExtensionimplementsPrependExtensionInter
{
...
publicfunctionprepend(ContainerBuilder$container)
{
$bundles=$container->getParameter('kernel.bundles');
if(!isset($bundles['TwigBundle'])){
return;
}
$container->prependExtensionConfig(
'twig',
array(
'paths'=>array(
"%kernel.root_dir%/../src/Dpc/Tutorial/View"=>'DpcTutorial'
)
)
);
}
}
Documentation » The Cookbook » Bundles » How to simplify configuration of multiple Bundles
One last step!
The action's $postargument relies on something called
.param converters
Those convert the idfrom the route to the actual Post
entity.
This is actually Symfony framework-specific behavior
Rewrite the controller to make use
of a repository
useDoctrineCommonPersistenceObjectRepository;
classPostController
{
publicfunction__construct(...,ObjectRepository$postRepository)
{
...
$this->postRepository=$postRepository;
}
publicfunctionshowAction($id)
{
$post=$this->postRepository->find($id);
if(!($postinstanceofPost)){
thrownewNotFoundHttpException();
}
...
}
}
services:
dpc_tutorial.post_controller:
class:DpcTutorialControllerPostController
arguments:
-@templating
-@dpc_tutorial.post_repository
dpc_tutorial.post_repository:
class:DoctrineCommonPersistenceObjectRepository
factory_service:doctrine
factory_method:getRepository
arguments:
-DpcTutorialModelPost
What do we have now?
Reusable templates
Reusable controllers
They work with Silex too!
Who would have though that was possible?
Console commands
Create a console command
Use app/console generate:console-command
Make it insert a new post in the database.
It takes one argument: the post's title.
Something like this
useDpcTutorialModelPost;
useSymfonyBundleFrameworkBundleCommandContainerAwareCommand;
useSymfonyComponentConsoleInputInputArgument;
useSymfonyComponentConsoleInputInputInterface;
useSymfonyComponentConsoleOutputOutputInterface;
classCreatePostCommandextendsContainerAwareCommand
{
protectedfunctionconfigure()
{
$this
->setName('post:create')
->addArgument('title',InputArgument::REQUIRED);
}
protectedfunctionexecute(InputInterface$input,OutputInterface$output)
{
$manager=$this->getContainer()
->get('doctrine')
->getManagerForClass('DpcTutorialModelPost');
$post=newPost();
$post->setTitle($input->getArgument('title'));
$manager->persist($post);
$manager->flush();
$output->writeln('Newpostcreated:'.$post->getTitle());
}
}
Why is it inside a bundle?
Because it is automatically registered when it's in the
Commanddirectory.
So let's move it out!
Move the command to the library
Create a service for it
Give it the tag console.command.
Or else it won't be recognized anymore!
services:
dpc_tutorial.create_post_command:
class:DpcTutorialCommandCreatePostCommand
tags:
-{name:console.command}
What about ContainerAware?
It couples our command to the Symfony framework.
Which is not needed at all.
Extend from Command
Then inject dependencies instead of fetching them from the
container.
useDoctrineCommonPersistenceManagerRegistry;
classCreatePostCommandextendsCommand
{
private$doctrine;
publicfunction__construct(ManagerRegistry$doctrine)
{
parent::__construct();
$this->doctrine=$doctrine;
}
...
protectedfunctionexecute(InputInterface$input,OutputInterface$output)
{
$manager=$this->doctrine->getManager();
...
}
}
services:
dpc_tutorial.create_post_command:
class:DpcTutorialCommandCreatePostCommand
arguments:
-@doctrine
tags:
-{name:console.command}
What do we have?
Explicit dependencies
Reusable commands that works in all projects that use the
Symfony Console Component (like )
A bit less magic (no auto-registering commands)
Which means now we can put anything we want in the
Commanddirectory
Cilex
Testing a
bundle
Or: testing configuration
The Configurationclass
I don't get it!
I don't trust myself with it.
And when I don't trust myself, I write tests
SymfonyConfigTest
On GitHub: SymfonyConfigTest
{
"require-dev":{
"matthiasnoback/symfony-config-test":"~0.1"
}
}
Prepare a test suite for your
Configurationclass
Create a directory Tests/DependencyInjectioninside
the bundle.
In that directory create a new class:
ConfigurationTest.
Create the test class
The ConfigurationTestshould extend from
AbstractConfigurationTestCase
Implement the missing method getConfiguration()
namespaceDpcBundleTutorialBundleTestsDependencyInjection;
useDpcBundleTutorialBundleDependencyInjectionConfiguration;
useMatthiasSymfonyConfigTestPhpUnitAbstractConfigurationTestCase;
classConfigurationTestextendsAbstractConfigurationTestCase
{
protectedfunctiongetConfiguration()
{
returnnewConfiguration();
}
}
Desired structure in config.yml
dpc_tutorial:
#hostshouldbearequiredkey
host:localhost
A required value: host
Test first
/**
*@test
*/
publicfunctionthe_host_key_is_required()
{
$this->assertConfigurationIsInvalid(
array(
array()
),
'host'
);
}
If we provide no values at all, we expect an exception
containing "host".
See it fail
bin/phpunit-capp
Make the test pass
$rootNode
->children()
->scalarNode('host')
->isRequired()
->end()
->end();
Trial and error
You're done when the test passes!
Repeated configuration values
Desired structure in config.yml
dpc_tutorial:
servers:
a:
host:server-a.nobacksoffice.nl
port:2730
b:
host:server-b.nobacksoffice.nl
port:2730
...
hostand portare required keys for each server
configuration
Test first
/**
*@test
*/
publicfunctionhost_is_required_for_each_server()
{
$this->assertConfigurationIsInvalid(
array(
array(
'servers'=>array(
'a'=>array()
)
)
),
'host'
);
}
Run the tests
bin/phpunit-capp
Write the code
$rootNode
->children()
->arrayNode('servers')
->useAttributeAsKey('name')
->prototype('array')
->children()
->scalarNode('host')
->isRequired()
->end()
Run the tests
Test first
Repeat these steps for port
Make sure your test first fails
Then you add some code
Then the test should pass
Merging config values
$this->assertConfigurationIsInvalid(
array(
array(
...//e.g.valuesfromconfig.yml
),
array(
...//e.g.valuesfromconfig_dev.yml
)
),
'host'
);
Disable merging
Test first
/**
*@test
*/
publicfunctionserver_configurations_are_not_merged()
{
$this->assertProcessedConfigurationEquals(
array(
array(
'servers'=>array(
'a'=>array('host'=>'host-a','port'=>1)
)
),
array(
'servers'=>array(
'b'=>array('host'=>'host-b','port'=>2)
)
)
),
array(
'servers'=>array(
'b'=>array('host'=>'host-b','port'=>2)
)
)
);
}
Add some code
$rootNode
->children()
->arrayNode('servers')
->useAttributeAsKey('name')//don'treindexthearray
->prototype('array')//means:repeatable
->children()
->scalarNode('host')->end()
->scalarNode('port')->end()
->end()
->end()
->end()
->end();
Run the tests
bin/phpunit-capp
Disable deep merging
Values from different configuration sources should not be
merged.
$rootNode
->children()
->arrayNode('servers')
->performNoDeepMerging()
...
->end()
->end();
Advantages of TDD for
Configurationclasses
We gradually approach our goal.
We immediately get feedback on what's wrong.
We can test different configuration values without
changing config.ymlmanually.
We can make sure the user gets very specific error
messages about wrong configuration values.
Learn more about all the options by reading the
.
offical
documentation of the Config component
Testing Extension
classes
dpc_tutorial:
servers:
a:
host:localhost
port:2730
Should give us a dpc_tutorial.a_serverservice with
hostand portas constructor arguments.
Create a test class for your extension
Directory: Tests/DependencyInjection
Class name: [NameOfTheExtension]Test
Class should extend AbstractExtensionTestCase
Implement getContainerExtensions(): return an
instance of your extension class
namespaceDpcBundleTutorialBundleTestsDependencyInjection;
useDpcBundleTutorialBundleDependencyInjectionDpcTutorialExtension;
useMatthiasSymfonyDependencyInjectionTestPhpUnitAbstractExtensionTestCase;
classDpcTutorialExtensionTestextendsAbstractExtensionTestCase
{
protectedfunctiongetContainerExtensions()
{
returnarray(
newDpcTutorialExtension()
);
}
}
Test first
/**
*@test
*/
publicfunctionit_creates_service_definitions_for_each_server()
{
$this->load(
array(
'servers'=>array(
'a'=>array('host'=>'host-a','port'=>123),
'b'=>array('host'=>'host-b','port'=>234)
)
)
);
$this->assertContainerBuilderHasServiceDefinitionWithArgument(
'dpc_tutorial.a_server',0,'host-a'
);
$this->assertContainerBuilderHasServiceDefinitionWithArgument(
'dpc_tutorial.a_server',1,123
);
$this->assertContainerBuilderHasServiceDefinitionWithArgument(
'dpc_tutorial.b_server',0,'host-b'
);
$this->assertContainerBuilderHasServiceDefinitionWithArgument(
'dpc_tutorial.b_server',1,234
);
}
See it fail
Write the code
useSymfonyComponentDependencyInjectionDefinition;
publicfunctionload(array$configs,ContainerBuilder$container)
{
$configuration=newConfiguration();
$config=$this->processConfiguration($configuration,$configs);
foreach($config['servers']as$name=>$serverConfig){
$serverDefinition=newDefinition();
$serverDefinition->setArguments(
array(
$serverConfig['host'],
$serverConfig['port'],
)
);
$container->setDefinition(
'dpc_tutorial.'.$name.'_server',
$serverDefinition
);
}
}
See it pass
Refactor!
publicfunctionload(array$configs,ContainerBuilder$container)
{
$configuration=newConfiguration();
$config=$this->processConfiguration($configuration,$configs);
$this->configureServers($container,$config['servers']);
}
privatefunctionconfigureServers(ContainerBuilder$container,array$servers)
{
foreach($serversas$name=>$server){
$this->configureServer($container,$name,$server['host'],$server['port']);
}
}
privatefunctionconfigureServer(ContainerBuilder$container,$name,$host,$port)
{
$serverDefinition=newDefinition(null,array($host,$port));
$container->setDefinition(
'dpc_tutorial.'.$name.'_server',
$serverDefinition
);
}
Shortcuts versus the Real deal
The base class provides some useful shortcuts
To get the most out of testing your extension:
Read all about classes like Definitionin the official
documentation
Patterns of Dependency Injection
A Bundle
called Bandle
I thought a bundle is just a class that
implements BundleInterface...
Why the suffix is
necessary
abstractclassBundleextendsContainerAwareimplementsBundleInterface
{
publicfunctiongetContainerExtension()
{
...
$basename=preg_replace('/Bundle$/','',$this->getName());
$class=$this->getNamespace()
.'DependencyInjection'
.$basename
.'Extension';
if(class_exists($class)){
$extension=new$class();
...
}
...
}
}
Line 6: '/Bundle$/'
But: no need to guess, you
already know which class
it is, right?
Override the
getContainerExtension()of your
bundle class
Then make it return an instance of your extension class.
useDpcBundleTutorialBundleDependencyInjectionDpcTutorialExtension;
classDpcTutorialBundleextendsBundle
{
publicfunctiongetContainerExtension()
{
returnnewDpcTutorialExtension();
}
}
Now the extension doesn't need to be in the
DependencyInjectiondirectory anymore!
It still needs to have the Extensionsuffix though...
Open the Extensionclass (from the
HttpKernelcomponent)
Take a look at the getAlias()method.
abstractclassExtensionimplementsExtensionInterface,ConfigurationExtensionInterface
{
publicfunctiongetAlias()
{
$className=get_class($this);
if(substr($className,-9)!='Extension'){
thrownewBadMethodCallException(
'Thisextensiondoesnotfollowthenamingconvention;'
.'youmustoverwritethegetAlias()method.'
);
}
$classBaseName=substr(strrchr($className,''),1,-9);
returnContainer::underscore($classBaseName);
}
}
The alias is used to find out which configuration belongs to
which bundle:
#inconfig.yml
dpc_tutorial:
...
By convention it's the lowercase underscored bundle name.
But what happens when I
rename the bundle?
The alias changes too, which means configuration in
config.ymlwon't be recognized anymore.
Also:
The extension needs to be renamed too, because of the
naming conventions...
DpcTutorialBundle,DpcTutorialExtension,dpc_tutorial
NobackTestBundle,NobackTestExtension,noback_test
So: open your extension class
Override the getAlias()method.
Make it return the alias of your extension (a string).
E.g. DpcTutorialBundle::getAlias()returns
dpc_tutorial.
classDpcTutorialExtensionextendsExtension
{
publicfunctiongetAlias()
{
return'dpc_tutorial';
}
}
But now we have some
duplication of information
The alias is also mentioned inside the Configuration
class.
classConfigurationimplementsConfigurationInterface
{
publicfunctiongetConfigTreeBuilder()
{
$treeBuilder=newTreeBuilder();
$rootNode=$treeBuilder->root('dpc_tutorial');
...
return$treeBuilder;
}
}
Modify extension and configuration
How can we make sure that the name of the root node in
the configuration class is the same as the alias returned by
getAlias()?
classConfigurationimplementsConfigurationInterface
{
private$alias;
publicfunction__construct($alias)
{
$this->alias=$alias;
}
publicfunctiongetConfigTreeBuilder()
{
$treeBuilder=newTreeBuilder();
$rootNode=$treeBuilder->root($this->alias);
...
}
}
$configuration=newConfiguration($this->getAlias());
This introduces a bug
Run app/console config:dump-reference
[extension-alias]
High Quality Symfony Bundles tutorial - Dutch PHP Conference 2014
Open the Extensionclass
Take the one from the DependencyInjection
component.
publicfunctiongetConfiguration(array$config,ContainerBuilder$container)
{
$reflected=newReflectionClass($this);
$namespace=$reflected->getNamespaceName();
$class=$namespace.'Configuration';
if(class_exists($class)){
$r=newReflectionClass($class);
$container->addResource(newFileResource($r->getFileName()));
if(!method_exists($class,'__construct')){
$configuration=new$class();
return$configuration;
}
}
}
Our Configurationclass has a constructor...
Override getConfiguration()in
your extension
Also: make sure only one instance of Configurationis
created in the extension class.
classDpcTutorialExtensionextendsExtension
{
publicfunctionload(array$configs,ContainerBuilder$container)
{
$configuration=$this->getConfiguration($configs,$container);
$config=$this->processConfiguration($configuration,$configs);
...
}
publicfunctiongetConfiguration(array$config,ContainerBuilder$container)
{
returnnewConfiguration($this->getAlias());
}
...
}
Now we are allowed to rename Configurationor put it
somewhere else entirely!
Some last improvement
Extend from ConfigurableExtension.
abstractclassConfigurableExtensionextendsExtension
{
finalpublicfunctionload(array$configs,ContainerBuilder$container)
{
$this->loadInternal(
$this->processConfiguration(
$this->getConfiguration($configs,$container),
$configs
),
$container
);
}
abstractprotectedfunctionloadInternal(array$mergedConfig,ContainerBuilder$conta
}
It will save you a call to processConfiguration().
classDpcTutorialExtensionextendsConfigurableExtension
{
publicfunctionloadInternal(array$mergedConfig,ContainerBuilder$container)
{
//$mergedConfighasalreadybeenprocessed
$loader=newXmlFileLoader($container,newFileLocator(__DIR__.'/../Resources/co
$loader->load('services.xml');
}
...
}
We introduced flexibility...
By hard-coding the alias
And by skipping all the magic stuff
Now we can
Change *Bundleinto *Bandle
Change *Extensioninto *Plugin
Change Configurationinto Complexity
If we want...
High Quality Symfony Bundles tutorial - Dutch PHP Conference 2014
€ 15,00
I’m impressed. — Robert C. Martin
leanpub.com/principles-of-php-package-design/c/dpc2014
Feedback
joind.in/10849
Twitter
@matthiasnoback

More Related Content

What's hot

Sf2 wtf
Sf2 wtfSf2 wtf
Symfony internals [english]
Symfony internals [english]Symfony internals [english]
Symfony internals [english]
Raul Fraile
 
Twig: Friendly Curly Braces Invade Your Templates!
Twig: Friendly Curly Braces Invade Your Templates!Twig: Friendly Curly Braces Invade Your Templates!
Twig: Friendly Curly Braces Invade Your Templates!
Ryan Weaver
 
Symfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worldsSymfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worlds
Ignacio Martín
 
Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3
Fabien Potencier
 
Puppet at Pinterest
Puppet at PinterestPuppet at Pinterest
Puppet at Pinterest
Puppet
 
Puppet at GitHub / ChatOps
Puppet at GitHub / ChatOpsPuppet at GitHub / ChatOps
Puppet at GitHub / ChatOps
Puppet
 
Learning puppet chapter 2
Learning puppet chapter 2Learning puppet chapter 2
Learning puppet chapter 2
Vishal Biyani
 
A dive into Symfony 4
A dive into Symfony 4A dive into Symfony 4
A dive into Symfony 4
Michele Orselli
 
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry PiGrâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Jérémy Derussé
 
Keeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and WebpackKeeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and Webpack
Ignacio Martín
 
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro frameworkKeeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
Jeremy Kendall
 
Writing Pluggable Software
Writing Pluggable SoftwareWriting Pluggable Software
Writing Pluggable Software
Tatsuhiko Miyagawa
 
The road to Ember.js 2.0
The road to Ember.js 2.0The road to Ember.js 2.0
The road to Ember.js 2.0
Codemotion
 
Being Dangerous with Twig
Being Dangerous with TwigBeing Dangerous with Twig
Being Dangerous with Twig
Ryan Weaver
 
Puppet for Sys Admins
Puppet for Sys AdminsPuppet for Sys Admins
Puppet for Sys Admins
Puppet
 
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
Ryan Weaver
 
Create a Symfony Application from a Drupal Perspective
Create a Symfony Application from a Drupal PerspectiveCreate a Symfony Application from a Drupal Perspective
Create a Symfony Application from a Drupal Perspective
Acquia
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Paulo Ragonha
 
Keeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro FrameworkKeeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro Framework
Jeremy Kendall
 

What's hot (20)

Sf2 wtf
Sf2 wtfSf2 wtf
Sf2 wtf
 
Symfony internals [english]
Symfony internals [english]Symfony internals [english]
Symfony internals [english]
 
Twig: Friendly Curly Braces Invade Your Templates!
Twig: Friendly Curly Braces Invade Your Templates!Twig: Friendly Curly Braces Invade Your Templates!
Twig: Friendly Curly Braces Invade Your Templates!
 
Symfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worldsSymfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worlds
 
Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3
 
Puppet at Pinterest
Puppet at PinterestPuppet at Pinterest
Puppet at Pinterest
 
Puppet at GitHub / ChatOps
Puppet at GitHub / ChatOpsPuppet at GitHub / ChatOps
Puppet at GitHub / ChatOps
 
Learning puppet chapter 2
Learning puppet chapter 2Learning puppet chapter 2
Learning puppet chapter 2
 
A dive into Symfony 4
A dive into Symfony 4A dive into Symfony 4
A dive into Symfony 4
 
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry PiGrâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
 
Keeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and WebpackKeeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and Webpack
 
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro frameworkKeeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
 
Writing Pluggable Software
Writing Pluggable SoftwareWriting Pluggable Software
Writing Pluggable Software
 
The road to Ember.js 2.0
The road to Ember.js 2.0The road to Ember.js 2.0
The road to Ember.js 2.0
 
Being Dangerous with Twig
Being Dangerous with TwigBeing Dangerous with Twig
Being Dangerous with Twig
 
Puppet for Sys Admins
Puppet for Sys AdminsPuppet for Sys Admins
Puppet for Sys Admins
 
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
 
Create a Symfony Application from a Drupal Perspective
Create a Symfony Application from a Drupal PerspectiveCreate a Symfony Application from a Drupal Perspective
Create a Symfony Application from a Drupal Perspective
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
 
Keeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro FrameworkKeeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro Framework
 

Viewers also liked

How I Built A Reusable Symfony2 TaggingBundle
How I Built A Reusable Symfony2 TaggingBundleHow I Built A Reusable Symfony2 TaggingBundle
How I Built A Reusable Symfony2 TaggingBundle
fogs24
 
What mom never told you about bundle configurations - Symfony Live Paris 2012
What mom never told you about bundle configurations - Symfony Live Paris 2012What mom never told you about bundle configurations - Symfony Live Paris 2012
What mom never told you about bundle configurations - Symfony Live Paris 2012
D
 
Guard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful SecurityGuard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful Security
Ryan Weaver
 
Symfony: Your Next Microframework (SymfonyCon 2015)
Symfony: Your Next Microframework (SymfonyCon 2015)Symfony: Your Next Microframework (SymfonyCon 2015)
Symfony: Your Next Microframework (SymfonyCon 2015)
Ryan Weaver
 
Amongst models
Amongst modelsAmongst models
Amongst models
Yves Reynhout
 
Confoo - Javascript Server Side : How to start
Confoo - Javascript Server Side : How to startConfoo - Javascript Server Side : How to start
Confoo - Javascript Server Side : How to start
Quentin Adam
 
Techniques d'accélération des pages web
Techniques d'accélération des pages webTechniques d'accélération des pages web
Techniques d'accélération des pages web
Jean-Pierre Vincent
 
Get Soaked - An In Depth Look At PHP Streams
Get Soaked - An In Depth Look At PHP StreamsGet Soaked - An In Depth Look At PHP Streams
Get Soaked - An In Depth Look At PHP Streams
Davey Shafik
 
Elastic Searching With PHP
Elastic Searching With PHPElastic Searching With PHP
Elastic Searching With PHP
Lea Hänsenberger
 
Diving deep into twig
Diving deep into twigDiving deep into twig
Diving deep into twig
Matthias Noback
 
Electrify your code with PHP Generators
Electrify your code with PHP GeneratorsElectrify your code with PHP Generators
Electrify your code with PHP Generators
Mark Baker
 
PHP5.5 is Here
PHP5.5 is HerePHP5.5 is Here
PHP5.5 is Here
julien pauli
 
Automation using-phing
Automation using-phingAutomation using-phing
Automation using-phing
Rajat Pandit
 
The quest for global design principles (SymfonyLive Berlin 2015)
The quest for global design principles (SymfonyLive Berlin 2015)The quest for global design principles (SymfonyLive Berlin 2015)
The quest for global design principles (SymfonyLive Berlin 2015)
Matthias Noback
 
Mocking Demystified
Mocking DemystifiedMocking Demystified
Mocking Demystified
Marcello Duarte
 
Top tips my_sql_performance
Top tips my_sql_performanceTop tips my_sql_performance
Top tips my_sql_performance
afup Paris
 
Nodejs and WebSockets
Nodejs and WebSocketsNodejs and WebSockets
Nodejs and WebSockets
Gonzalo Ayuso
 
Understanding Craftsmanship SwanseaCon2015
Understanding Craftsmanship SwanseaCon2015Understanding Craftsmanship SwanseaCon2015
Understanding Craftsmanship SwanseaCon2015
Marcello Duarte
 
Why elasticsearch rocks!
Why elasticsearch rocks!Why elasticsearch rocks!
Why elasticsearch rocks!
tlrx
 
Si le tdd est mort alors pratiquons une autopsie mix-it 2015
Si le tdd est mort alors pratiquons une autopsie mix-it 2015Si le tdd est mort alors pratiquons une autopsie mix-it 2015
Si le tdd est mort alors pratiquons une autopsie mix-it 2015
Bruno Boucard
 

Viewers also liked (20)

How I Built A Reusable Symfony2 TaggingBundle
How I Built A Reusable Symfony2 TaggingBundleHow I Built A Reusable Symfony2 TaggingBundle
How I Built A Reusable Symfony2 TaggingBundle
 
What mom never told you about bundle configurations - Symfony Live Paris 2012
What mom never told you about bundle configurations - Symfony Live Paris 2012What mom never told you about bundle configurations - Symfony Live Paris 2012
What mom never told you about bundle configurations - Symfony Live Paris 2012
 
Guard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful SecurityGuard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful Security
 
Symfony: Your Next Microframework (SymfonyCon 2015)
Symfony: Your Next Microframework (SymfonyCon 2015)Symfony: Your Next Microframework (SymfonyCon 2015)
Symfony: Your Next Microframework (SymfonyCon 2015)
 
Amongst models
Amongst modelsAmongst models
Amongst models
 
Confoo - Javascript Server Side : How to start
Confoo - Javascript Server Side : How to startConfoo - Javascript Server Side : How to start
Confoo - Javascript Server Side : How to start
 
Techniques d'accélération des pages web
Techniques d'accélération des pages webTechniques d'accélération des pages web
Techniques d'accélération des pages web
 
Get Soaked - An In Depth Look At PHP Streams
Get Soaked - An In Depth Look At PHP StreamsGet Soaked - An In Depth Look At PHP Streams
Get Soaked - An In Depth Look At PHP Streams
 
Elastic Searching With PHP
Elastic Searching With PHPElastic Searching With PHP
Elastic Searching With PHP
 
Diving deep into twig
Diving deep into twigDiving deep into twig
Diving deep into twig
 
Electrify your code with PHP Generators
Electrify your code with PHP GeneratorsElectrify your code with PHP Generators
Electrify your code with PHP Generators
 
PHP5.5 is Here
PHP5.5 is HerePHP5.5 is Here
PHP5.5 is Here
 
Automation using-phing
Automation using-phingAutomation using-phing
Automation using-phing
 
The quest for global design principles (SymfonyLive Berlin 2015)
The quest for global design principles (SymfonyLive Berlin 2015)The quest for global design principles (SymfonyLive Berlin 2015)
The quest for global design principles (SymfonyLive Berlin 2015)
 
Mocking Demystified
Mocking DemystifiedMocking Demystified
Mocking Demystified
 
Top tips my_sql_performance
Top tips my_sql_performanceTop tips my_sql_performance
Top tips my_sql_performance
 
Nodejs and WebSockets
Nodejs and WebSocketsNodejs and WebSockets
Nodejs and WebSockets
 
Understanding Craftsmanship SwanseaCon2015
Understanding Craftsmanship SwanseaCon2015Understanding Craftsmanship SwanseaCon2015
Understanding Craftsmanship SwanseaCon2015
 
Why elasticsearch rocks!
Why elasticsearch rocks!Why elasticsearch rocks!
Why elasticsearch rocks!
 
Si le tdd est mort alors pratiquons une autopsie mix-it 2015
Si le tdd est mort alors pratiquons une autopsie mix-it 2015Si le tdd est mort alors pratiquons une autopsie mix-it 2015
Si le tdd est mort alors pratiquons une autopsie mix-it 2015
 

Similar to High Quality Symfony Bundles tutorial - Dutch PHP Conference 2014

The Naked Bundle - Symfony Barcelona
The Naked Bundle - Symfony BarcelonaThe Naked Bundle - Symfony Barcelona
The Naked Bundle - Symfony Barcelona
Matthias Noback
 
The Naked Bundle - Symfony Usergroup Belgium
The Naked Bundle - Symfony Usergroup BelgiumThe Naked Bundle - Symfony Usergroup Belgium
The Naked Bundle - Symfony Usergroup Belgium
Matthias Noback
 
The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014
Matthias Noback
 
The Naked Bundle - Tryout
The Naked Bundle - TryoutThe Naked Bundle - Tryout
The Naked Bundle - Tryout
Matthias Noback
 
Angular performance slides
Angular performance slidesAngular performance slides
Angular performance slides
David Barreto
 
Building a p2 update site using Buckminster
Building a p2 update site using BuckminsterBuilding a p2 update site using Buckminster
Building a p2 update site using Buckminster
guest5e2b6b
 
Readme
ReadmeReadme
Readme
rec2006
 
Drupal Best Practices
Drupal Best PracticesDrupal Best Practices
Drupal Best Practices
manugoel2003
 
Angular Optimization Web Performance Meetup
Angular Optimization Web Performance MeetupAngular Optimization Web Performance Meetup
Angular Optimization Web Performance Meetup
David Barreto
 
Understanding Framework Architecture using Eclipse
Understanding Framework Architecture using EclipseUnderstanding Framework Architecture using Eclipse
Understanding Framework Architecture using Eclipse
anshunjain
 
Cpp17 and Beyond
Cpp17 and BeyondCpp17 and Beyond
Cpp17 and Beyond
ComicSansMS
 
Android application architecture
Android application architectureAndroid application architecture
Android application architecture
Romain Rochegude
 
C++ development within OOo
C++ development within OOoC++ development within OOo
C++ development within OOo
Alexandro Colorado
 
Framework engineering JCO 2011
Framework engineering JCO 2011Framework engineering JCO 2011
Framework engineering JCO 2011
YoungSu Son
 
React hooks
React hooksReact hooks
React hooks
Ramy ElBasyouni
 
LabDocumentation
LabDocumentationLabDocumentation
LabDocumentation
Yeshasvi Tirupachuri
 
Frankenstein's IDE: NetBeans and OSGi
Frankenstein's IDE: NetBeans and OSGiFrankenstein's IDE: NetBeans and OSGi
Frankenstein's IDE: NetBeans and OSGi
Toni Epple
 
High quality ap is with api platform
High quality ap is with api platformHigh quality ap is with api platform
High quality ap is with api platform
Nelson Kopliku
 
CS8251_QB_answers.pdf
CS8251_QB_answers.pdfCS8251_QB_answers.pdf
CS8251_QB_answers.pdf
vino108206
 
Adding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsAdding a modern twist to legacy web applications
Adding a modern twist to legacy web applications
Jeff Durta
 

Similar to High Quality Symfony Bundles tutorial - Dutch PHP Conference 2014 (20)

The Naked Bundle - Symfony Barcelona
The Naked Bundle - Symfony BarcelonaThe Naked Bundle - Symfony Barcelona
The Naked Bundle - Symfony Barcelona
 
The Naked Bundle - Symfony Usergroup Belgium
The Naked Bundle - Symfony Usergroup BelgiumThe Naked Bundle - Symfony Usergroup Belgium
The Naked Bundle - Symfony Usergroup Belgium
 
The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014
 
The Naked Bundle - Tryout
The Naked Bundle - TryoutThe Naked Bundle - Tryout
The Naked Bundle - Tryout
 
Angular performance slides
Angular performance slidesAngular performance slides
Angular performance slides
 
Building a p2 update site using Buckminster
Building a p2 update site using BuckminsterBuilding a p2 update site using Buckminster
Building a p2 update site using Buckminster
 
Readme
ReadmeReadme
Readme
 
Drupal Best Practices
Drupal Best PracticesDrupal Best Practices
Drupal Best Practices
 
Angular Optimization Web Performance Meetup
Angular Optimization Web Performance MeetupAngular Optimization Web Performance Meetup
Angular Optimization Web Performance Meetup
 
Understanding Framework Architecture using Eclipse
Understanding Framework Architecture using EclipseUnderstanding Framework Architecture using Eclipse
Understanding Framework Architecture using Eclipse
 
Cpp17 and Beyond
Cpp17 and BeyondCpp17 and Beyond
Cpp17 and Beyond
 
Android application architecture
Android application architectureAndroid application architecture
Android application architecture
 
C++ development within OOo
C++ development within OOoC++ development within OOo
C++ development within OOo
 
Framework engineering JCO 2011
Framework engineering JCO 2011Framework engineering JCO 2011
Framework engineering JCO 2011
 
React hooks
React hooksReact hooks
React hooks
 
LabDocumentation
LabDocumentationLabDocumentation
LabDocumentation
 
Frankenstein's IDE: NetBeans and OSGi
Frankenstein's IDE: NetBeans and OSGiFrankenstein's IDE: NetBeans and OSGi
Frankenstein's IDE: NetBeans and OSGi
 
High quality ap is with api platform
High quality ap is with api platformHigh quality ap is with api platform
High quality ap is with api platform
 
CS8251_QB_answers.pdf
CS8251_QB_answers.pdfCS8251_QB_answers.pdf
CS8251_QB_answers.pdf
 
Adding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsAdding a modern twist to legacy web applications
Adding a modern twist to legacy web applications
 

More from Matthias Noback

Rector fireside chat - PHPMiNDS meetup
Rector fireside chat - PHPMiNDS meetupRector fireside chat - PHPMiNDS meetup
Rector fireside chat - PHPMiNDS meetup
Matthias Noback
 
Service abstractions - Part 1: Queries
Service abstractions - Part 1: QueriesService abstractions - Part 1: Queries
Service abstractions - Part 1: Queries
Matthias Noback
 
Hexagonal Symfony - SymfonyCon Amsterdam 2019
Hexagonal Symfony - SymfonyCon Amsterdam 2019Hexagonal Symfony - SymfonyCon Amsterdam 2019
Hexagonal Symfony - SymfonyCon Amsterdam 2019
Matthias Noback
 
Advanced web application architecture - PHP Barcelona
Advanced web application architecture  - PHP BarcelonaAdvanced web application architecture  - PHP Barcelona
Advanced web application architecture - PHP Barcelona
Matthias Noback
 
A testing strategy for hexagonal applications
A testing strategy for hexagonal applicationsA testing strategy for hexagonal applications
A testing strategy for hexagonal applications
Matthias Noback
 
Advanced web application architecture - Talk
Advanced web application architecture - TalkAdvanced web application architecture - Talk
Advanced web application architecture - Talk
Matthias Noback
 
DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...
DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...
DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...
Matthias Noback
 
Layers, ports and adapters
Layers, ports and adaptersLayers, ports and adapters
Layers, ports and adapters
Matthias Noback
 
Beyond design principles and patterns (muCon 2019 edition)
Beyond design principles and patterns (muCon 2019 edition)Beyond design principles and patterns (muCon 2019 edition)
Beyond design principles and patterns (muCon 2019 edition)
Matthias Noback
 
Brutal refactoring, lying code, the Churn, and other emotional stories from L...
Brutal refactoring, lying code, the Churn, and other emotional stories from L...Brutal refactoring, lying code, the Churn, and other emotional stories from L...
Brutal refactoring, lying code, the Churn, and other emotional stories from L...
Matthias Noback
 
Advanced web application architecture Way2Web
Advanced web application architecture Way2WebAdvanced web application architecture Way2Web
Advanced web application architecture Way2Web
Matthias Noback
 
Brutal refactoring, lying code, the Churn, and other emotional stories from L...
Brutal refactoring, lying code, the Churn, and other emotional stories from L...Brutal refactoring, lying code, the Churn, and other emotional stories from L...
Brutal refactoring, lying code, the Churn, and other emotional stories from L...
Matthias Noback
 
Beyond Design Principles and Patterns
Beyond Design Principles and PatternsBeyond Design Principles and Patterns
Beyond Design Principles and Patterns
Matthias Noback
 
Building Autonomous Services
Building Autonomous ServicesBuilding Autonomous Services
Building Autonomous Services
Matthias Noback
 
Advanced Application Architecture Symfony Live Berlin 2018
Advanced Application Architecture Symfony Live Berlin 2018Advanced Application Architecture Symfony Live Berlin 2018
Advanced Application Architecture Symfony Live Berlin 2018
Matthias Noback
 
Designing for Autonomy
Designing for AutonomyDesigning for Autonomy
Designing for Autonomy
Matthias Noback
 
Docker workshop
Docker workshopDocker workshop
Docker workshop
Matthias Noback
 
Docker swarm workshop
Docker swarm workshopDocker swarm workshop
Docker swarm workshop
Matthias Noback
 
Docker compose workshop
Docker compose workshopDocker compose workshop
Docker compose workshop
Matthias Noback
 
Building autonomous services
Building autonomous servicesBuilding autonomous services
Building autonomous services
Matthias Noback
 

More from Matthias Noback (20)

Rector fireside chat - PHPMiNDS meetup
Rector fireside chat - PHPMiNDS meetupRector fireside chat - PHPMiNDS meetup
Rector fireside chat - PHPMiNDS meetup
 
Service abstractions - Part 1: Queries
Service abstractions - Part 1: QueriesService abstractions - Part 1: Queries
Service abstractions - Part 1: Queries
 
Hexagonal Symfony - SymfonyCon Amsterdam 2019
Hexagonal Symfony - SymfonyCon Amsterdam 2019Hexagonal Symfony - SymfonyCon Amsterdam 2019
Hexagonal Symfony - SymfonyCon Amsterdam 2019
 
Advanced web application architecture - PHP Barcelona
Advanced web application architecture  - PHP BarcelonaAdvanced web application architecture  - PHP Barcelona
Advanced web application architecture - PHP Barcelona
 
A testing strategy for hexagonal applications
A testing strategy for hexagonal applicationsA testing strategy for hexagonal applications
A testing strategy for hexagonal applications
 
Advanced web application architecture - Talk
Advanced web application architecture - TalkAdvanced web application architecture - Talk
Advanced web application architecture - Talk
 
DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...
DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...
DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...
 
Layers, ports and adapters
Layers, ports and adaptersLayers, ports and adapters
Layers, ports and adapters
 
Beyond design principles and patterns (muCon 2019 edition)
Beyond design principles and patterns (muCon 2019 edition)Beyond design principles and patterns (muCon 2019 edition)
Beyond design principles and patterns (muCon 2019 edition)
 
Brutal refactoring, lying code, the Churn, and other emotional stories from L...
Brutal refactoring, lying code, the Churn, and other emotional stories from L...Brutal refactoring, lying code, the Churn, and other emotional stories from L...
Brutal refactoring, lying code, the Churn, and other emotional stories from L...
 
Advanced web application architecture Way2Web
Advanced web application architecture Way2WebAdvanced web application architecture Way2Web
Advanced web application architecture Way2Web
 
Brutal refactoring, lying code, the Churn, and other emotional stories from L...
Brutal refactoring, lying code, the Churn, and other emotional stories from L...Brutal refactoring, lying code, the Churn, and other emotional stories from L...
Brutal refactoring, lying code, the Churn, and other emotional stories from L...
 
Beyond Design Principles and Patterns
Beyond Design Principles and PatternsBeyond Design Principles and Patterns
Beyond Design Principles and Patterns
 
Building Autonomous Services
Building Autonomous ServicesBuilding Autonomous Services
Building Autonomous Services
 
Advanced Application Architecture Symfony Live Berlin 2018
Advanced Application Architecture Symfony Live Berlin 2018Advanced Application Architecture Symfony Live Berlin 2018
Advanced Application Architecture Symfony Live Berlin 2018
 
Designing for Autonomy
Designing for AutonomyDesigning for Autonomy
Designing for Autonomy
 
Docker workshop
Docker workshopDocker workshop
Docker workshop
 
Docker swarm workshop
Docker swarm workshopDocker swarm workshop
Docker swarm workshop
 
Docker compose workshop
Docker compose workshopDocker compose workshop
Docker compose workshop
 
Building autonomous services
Building autonomous servicesBuilding autonomous services
Building autonomous services
 

Recently uploaded

How Salesforce Development in the UK is Driving Digital Transformation
How Salesforce Development in the UK is Driving Digital TransformationHow Salesforce Development in the UK is Driving Digital Transformation
How Salesforce Development in the UK is Driving Digital Transformation
Sweet Potato Tec
 
optimized green synthesis characterization and evaluation
optimized green synthesis characterization and evaluationoptimized green synthesis characterization and evaluation
optimized green synthesis characterization and evaluation
ManojKumarr75
 
Female Service Girls Call Delhi 9873940964 Provide Best And Top Girl Service ...
Female Service Girls Call Delhi 9873940964 Provide Best And Top Girl Service ...Female Service Girls Call Delhi 9873940964 Provide Best And Top Girl Service ...
Female Service Girls Call Delhi 9873940964 Provide Best And Top Girl Service ...
elbertablack
 
Maximizing Network Efficiency with Large Language Models (LLM)
Maximizing Network Efficiency with Large Language Models (LLM)Maximizing Network Efficiency with Large Language Models (LLM)
Maximizing Network Efficiency with Large Language Models (LLM)
Bangladesh Network Operators Group
 
Trump Assassination Shirt Trump Assassination Shirt
Trump Assassination Shirt Trump Assassination ShirtTrump Assassination Shirt Trump Assassination Shirt
Trump Assassination Shirt Trump Assassination Shirt
exgf28
 
DASH, presented by Elly Tawhai at PacNOG 33
DASH, presented by Elly Tawhai at PacNOG 33DASH, presented by Elly Tawhai at PacNOG 33
DASH, presented by Elly Tawhai at PacNOG 33
APNIC
 
UMN degree offer diploma Transcript
UMN degree offer diploma TranscriptUMN degree offer diploma Transcript
UMN degree offer diploma Transcript
cenocb
 
Top 50 Data Science Jobs on LinkedIn.docx
Top 50 Data Science Jobs on LinkedIn.docxTop 50 Data Science Jobs on LinkedIn.docx
Top 50 Data Science Jobs on LinkedIn.docx
analyticsinsightmaga
 
My President is bulletproof t shirts hoodie
My President is bulletproof t shirts hoodieMy President is bulletproof t shirts hoodie
My President is bulletproof t shirts hoodie
exgf28
 
Girls Call Shimla 000XX00000 Provide Best And Top Girl Service And No1 in City
Girls Call Shimla 000XX00000 Provide Best And Top Girl Service And No1 in CityGirls Call Shimla 000XX00000 Provide Best And Top Girl Service And No1 in City
Girls Call Shimla 000XX00000 Provide Best And Top Girl Service And No1 in City
dilbaagsingh0898
 
Dewanstudio Project Portfolio 2023 show case
Dewanstudio Project Portfolio 2023 show caseDewanstudio Project Portfolio 2023 show case
Dewanstudio Project Portfolio 2023 show case
DEWANSTUDIO.COM
 
How-to-Diagnose-Hard-Drives-by-DFL-DDP-2024.pdf
How-to-Diagnose-Hard-Drives-by-DFL-DDP-2024.pdfHow-to-Diagnose-Hard-Drives-by-DFL-DDP-2024.pdf
How-to-Diagnose-Hard-Drives-by-DFL-DDP-2024.pdf
Dolphin Data Lab
 
Ontology for the semantic enhancement, database definition and management and...
Ontology for the semantic enhancement, database definition and management and...Ontology for the semantic enhancement, database definition and management and...
Ontology for the semantic enhancement, database definition and management and...
Edward Blurock
 
Career Development Advice for Network Engineers across the Pacific, presented...
Career Development Advice for Network Engineers across the Pacific, presented...Career Development Advice for Network Engineers across the Pacific, presented...
Career Development Advice for Network Engineers across the Pacific, presented...
APNIC
 
Digital ethnography of the Polish darknet drug trade community
Digital ethnography of the Polish darknet drug trade communityDigital ethnography of the Polish darknet drug trade community
Digital ethnography of the Polish darknet drug trade community
Piotr Siuda
 
Network Layer and its protocols mod .pptx
Network Layer and its protocols mod .pptxNetwork Layer and its protocols mod .pptx
Network Layer and its protocols mod .pptx
cossykin19
 
Girls Call Mahipalpur 000XX00000 Provide Best And Top Girl Service And No1 in...
Girls Call Mahipalpur 000XX00000 Provide Best And Top Girl Service And No1 in...Girls Call Mahipalpur 000XX00000 Provide Best And Top Girl Service And No1 in...
Girls Call Mahipalpur 000XX00000 Provide Best And Top Girl Service And No1 in...
mahigarg2024#G05
 
Enhancing seamless access using TIGERfed
Enhancing seamless access using TIGERfedEnhancing seamless access using TIGERfed
Enhancing seamless access using TIGERfed
Bangladesh Network Operators Group
 
202254.com香蕉影视,在线观看《我才不要和你做朋友呢》在线观看最新电影,香蕉影视在线观看《我才不要和你做朋友呢》在线观看高清电影
202254.com香蕉影视,在线观看《我才不要和你做朋友呢》在线观看最新电影,香蕉影视在线观看《我才不要和你做朋友呢》在线观看高清电影202254.com香蕉影视,在线观看《我才不要和你做朋友呢》在线观看最新电影,香蕉影视在线观看《我才不要和你做朋友呢》在线观看高清电影
202254.com香蕉影视,在线观看《我才不要和你做朋友呢》在线观看最新电影,香蕉影视在线观看《我才不要和你做朋友呢》在线观看高清电影
ffg01100
 
SisAi World - Software is AI - Providing AI as Software - Protecting the Inte...
SisAi World - Software is AI - Providing AI as Software - Protecting the Inte...SisAi World - Software is AI - Providing AI as Software - Protecting the Inte...
SisAi World - Software is AI - Providing AI as Software - Protecting the Inte...
QingjieDu1
 

Recently uploaded (20)

How Salesforce Development in the UK is Driving Digital Transformation
How Salesforce Development in the UK is Driving Digital TransformationHow Salesforce Development in the UK is Driving Digital Transformation
How Salesforce Development in the UK is Driving Digital Transformation
 
optimized green synthesis characterization and evaluation
optimized green synthesis characterization and evaluationoptimized green synthesis characterization and evaluation
optimized green synthesis characterization and evaluation
 
Female Service Girls Call Delhi 9873940964 Provide Best And Top Girl Service ...
Female Service Girls Call Delhi 9873940964 Provide Best And Top Girl Service ...Female Service Girls Call Delhi 9873940964 Provide Best And Top Girl Service ...
Female Service Girls Call Delhi 9873940964 Provide Best And Top Girl Service ...
 
Maximizing Network Efficiency with Large Language Models (LLM)
Maximizing Network Efficiency with Large Language Models (LLM)Maximizing Network Efficiency with Large Language Models (LLM)
Maximizing Network Efficiency with Large Language Models (LLM)
 
Trump Assassination Shirt Trump Assassination Shirt
Trump Assassination Shirt Trump Assassination ShirtTrump Assassination Shirt Trump Assassination Shirt
Trump Assassination Shirt Trump Assassination Shirt
 
DASH, presented by Elly Tawhai at PacNOG 33
DASH, presented by Elly Tawhai at PacNOG 33DASH, presented by Elly Tawhai at PacNOG 33
DASH, presented by Elly Tawhai at PacNOG 33
 
UMN degree offer diploma Transcript
UMN degree offer diploma TranscriptUMN degree offer diploma Transcript
UMN degree offer diploma Transcript
 
Top 50 Data Science Jobs on LinkedIn.docx
Top 50 Data Science Jobs on LinkedIn.docxTop 50 Data Science Jobs on LinkedIn.docx
Top 50 Data Science Jobs on LinkedIn.docx
 
My President is bulletproof t shirts hoodie
My President is bulletproof t shirts hoodieMy President is bulletproof t shirts hoodie
My President is bulletproof t shirts hoodie
 
Girls Call Shimla 000XX00000 Provide Best And Top Girl Service And No1 in City
Girls Call Shimla 000XX00000 Provide Best And Top Girl Service And No1 in CityGirls Call Shimla 000XX00000 Provide Best And Top Girl Service And No1 in City
Girls Call Shimla 000XX00000 Provide Best And Top Girl Service And No1 in City
 
Dewanstudio Project Portfolio 2023 show case
Dewanstudio Project Portfolio 2023 show caseDewanstudio Project Portfolio 2023 show case
Dewanstudio Project Portfolio 2023 show case
 
How-to-Diagnose-Hard-Drives-by-DFL-DDP-2024.pdf
How-to-Diagnose-Hard-Drives-by-DFL-DDP-2024.pdfHow-to-Diagnose-Hard-Drives-by-DFL-DDP-2024.pdf
How-to-Diagnose-Hard-Drives-by-DFL-DDP-2024.pdf
 
Ontology for the semantic enhancement, database definition and management and...
Ontology for the semantic enhancement, database definition and management and...Ontology for the semantic enhancement, database definition and management and...
Ontology for the semantic enhancement, database definition and management and...
 
Career Development Advice for Network Engineers across the Pacific, presented...
Career Development Advice for Network Engineers across the Pacific, presented...Career Development Advice for Network Engineers across the Pacific, presented...
Career Development Advice for Network Engineers across the Pacific, presented...
 
Digital ethnography of the Polish darknet drug trade community
Digital ethnography of the Polish darknet drug trade communityDigital ethnography of the Polish darknet drug trade community
Digital ethnography of the Polish darknet drug trade community
 
Network Layer and its protocols mod .pptx
Network Layer and its protocols mod .pptxNetwork Layer and its protocols mod .pptx
Network Layer and its protocols mod .pptx
 
Girls Call Mahipalpur 000XX00000 Provide Best And Top Girl Service And No1 in...
Girls Call Mahipalpur 000XX00000 Provide Best And Top Girl Service And No1 in...Girls Call Mahipalpur 000XX00000 Provide Best And Top Girl Service And No1 in...
Girls Call Mahipalpur 000XX00000 Provide Best And Top Girl Service And No1 in...
 
Enhancing seamless access using TIGERfed
Enhancing seamless access using TIGERfedEnhancing seamless access using TIGERfed
Enhancing seamless access using TIGERfed
 
202254.com香蕉影视,在线观看《我才不要和你做朋友呢》在线观看最新电影,香蕉影视在线观看《我才不要和你做朋友呢》在线观看高清电影
202254.com香蕉影视,在线观看《我才不要和你做朋友呢》在线观看最新电影,香蕉影视在线观看《我才不要和你做朋友呢》在线观看高清电影202254.com香蕉影视,在线观看《我才不要和你做朋友呢》在线观看最新电影,香蕉影视在线观看《我才不要和你做朋友呢》在线观看高清电影
202254.com香蕉影视,在线观看《我才不要和你做朋友呢》在线观看最新电影,香蕉影视在线观看《我才不要和你做朋友呢》在线观看高清电影
 
SisAi World - Software is AI - Providing AI as Software - Protecting the Inte...
SisAi World - Software is AI - Providing AI as Software - Protecting the Inte...SisAi World - Software is AI - Providing AI as Software - Protecting the Inte...
SisAi World - Software is AI - Providing AI as Software - Protecting the Inte...
 

High Quality Symfony Bundles tutorial - Dutch PHP Conference 2014