Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Inside the Symfony DIC and Config
Search
Andreas Hucks
January 25, 2013
Programming
3
860
Inside the Symfony DIC and Config
Slides for my Symfony workshop at PHPBenelux 2013
Andreas Hucks
January 25, 2013
Tweet
Share
More Decks by Andreas Hucks
See All by Andreas Hucks
Divide and Conquer (LonghornPHP 2019)
meandmymonkey
0
140
Symfony Internals
meandmymonkey
3
810
Divide and Conquer
meandmymonkey
1
650
Deptrac - Keep Your Architecture Clean
meandmymonkey
0
650
Introduction to Docker at PHPBenelux2015
meandmymonkey
3
820
Best Practices in Symfony2
meandmymonkey
0
400
Introduction to Docker at PHPNW2014
meandmymonkey
4
400
O(ops), Authentication!
meandmymonkey
4
860
Best Practices in Symfony2
meandmymonkey
15
1.8k
Other Decks in Programming
See All in Programming
note の Elasticsearch 更新系を支える技術
tchov
9
3.6k
大LLM時代にこの先生きのこるには-ITエンジニア編
fumiyakume
8
3.4k
eBPF超入門「o11yに使える」とは (20250424_eBPF_o11y)
thousanda
1
120
AIコーディングの本質は“コード“ではなく“構造“だった / The essence of AI coding is not “code” but "structure
seike460
PRO
2
430
2025年のz-index設計を考える
tak_dcxi
11
4.5k
UMAPをざっくりと理解 / Overview of UMAP
kaityo256
PRO
3
1.5k
JAWS DAYS 2025 re_Cheers: WEB
komakichi
0
120
個人開発の学生アプリが企業譲渡されるまで
akidon0000
2
1.2k
プロダクトエンジニアのしごと 〜 受託 × 高難度を乗り越えるOptium開発 〜
algoartis
0
220
M5UnitUnified 最新動向 2025/05
gob
0
140
Rubyの!メソッドをちゃんと理解する
alstrocrack
1
310
Cloudflare Workersで進めるリモートMCP活用
syumai
5
560
Featured
See All Featured
The Cost Of JavaScript in 2023
addyosmani
49
7.8k
The Invisible Side of Design
smashingmag
299
50k
Gamification - CAS2011
davidbonilla
81
5.3k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
13
840
Into the Great Unknown - MozCon
thekraken
38
1.8k
Faster Mobile Websites
deanohume
307
31k
Building a Modern Day E-commerce SEO Strategy
aleyda
40
7.3k
StorybookのUI Testing Handbookを読んだ
zakiyama
30
5.7k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
Making the Leap to Tech Lead
cromwellryan
133
9.3k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
179
53k
Adopting Sorbet at Scale
ufuk
76
9.4k
Transcript
None
Symfony DIC and Configuration
Andreas Hucks @meandmymonkey Senior Developer, Trainer, Consultant SensioLabs Deutschland
The Project:
€
http://goo.gl/rS06X
Life without Dependency Injection
class Logger { public function log($message, $level =
'INFO') { $formatter = new XmlFormatter(); $log = $formatter-‐>format( $message, $level ); $this-‐>writeLog($log); } }
Problems?
class Logger { function __construct(FormatterInterface $formatter) {
$this-‐>formatter = $formatter; } [...] }
class Logger { [...] public function
log($message, $level = 'INFO') { $log = $this-‐>formatter-‐>format( $message, $level ); $this-‐>writeLog($log); } }
Alternative: Setter Injection
class Logger { [...] function setFormatter(FormatterInterface
$formatter) { $this-‐>formatter = $formatter; } [...] }
“Dependency Injection is where components are given their dependencies through
their constructors, methods, or directly into fields.”
Interfacing with the Webservice
interface ExchangeRatesInterface { /**
* @return array */ public function getRates(); /** * @param string $currency * @return float */ public function getRate($currency); }
interface AdapterInterface { /**
* @return string */ public function getRawData(); }
interface ParserInterface { /**
* @param string $rawData * @return array */ public function parse($rawData); }
Task Implement class ExchangeRates using MockAdapter and XmlParser. Generate output
using ExchangeRatesCommand .
The Service Container
The Service Container is simply a PHP object that manages
the instantiation of services.
$container-‐>get('logger'); $container-‐>getParameter('logger.class');
Vocabulary Elements
service An object managed by the Dependency Injection Container.
argument A parameter given by the DIC to a service,
via the constructor or a mutator method (setter).
parameter A configuration value.
<service id="sensio.logger" class="Sensio\Logger" > <!-‐-‐
Constructor arguments -‐-‐> <argument>/path/to/app/logs/app.log</argument> <argument type="service" id="sensio.logger.xml_formatter" /> <!-‐-‐ Methods to call -‐-‐> <call method="setDefaultSeverity"> <argument>DEBUG</argument> </call> <!-‐-‐ Tags -‐-‐> <tag name="tools.logger" /> </service>
Vocabulary Attributes
id The service identifier or name
class The service class to instantiate
alias An alias name for this service
public Set to false to make the service private and
used internally
<service id="sensio.logger" class="Sensio\Logger" > <!-‐-‐
Constructor arguments -‐-‐> <argument>/path/to/app/logs/app.log</argument> <argument type="service" id="sensio.logger.xml_formatter" /> <!-‐-‐ Methods to call -‐-‐> <call method="setDefaultSeverity"> <argument>DEBUG</argument> </call> <!-‐-‐ Tags -‐-‐> <tag name="tools.logger" /> </service>
Vocabulary Service Elements
argument An argument to pass to a method (constructor or
setter)
call A method to call on the newly created object
tag A tag to attach to the service definition
<service id="sensio.logger" class="Sensio\Logger" > <!-‐-‐
Constructor arguments -‐-‐> <argument>/path/to/app/logs/app.log</argument> <argument type="service" id="sensio.logger.xml_formatter" /> <!-‐-‐ Methods to call -‐-‐> <call method="setDefaultSeverity"> <argument>DEBUG</argument> </call> <!-‐-‐ Tags -‐-‐> <tag name="tools.logger" /> </service>
Vocabulary Argument Attributes
type Define the nature of the argument. Allowed values: string,
constant, collection or service
id The service name, if the argument is a service
key The argument key when dealing with the collection type
<service id="sensio.logger" class="Sensio\Logger" > <!-‐-‐
Constructor arguments -‐-‐> <argument>/path/to/app/logs/app.log</argument> <argument type="service" id="sensio.logger.xml_formatter" /> <!-‐-‐ Methods to call -‐-‐> <call method="setDefaultSeverity"> <argument>DEBUG</argument> </call> <!-‐-‐ Tags -‐-‐> <tag name="tools.logger" /> </service>
http://goo.gl/FNJ9H
Task Write a container configuration!
Configuration
public function load( array $configs, ContainerBuilder
$container ) { $configuration = new Configuration(); $config = $this -‐>processConfiguration($configuration, $configs); $loader = new Loader\XmlFileLoader( $container, new FileLocator(__DIR__.'/../Resources/config') ); $loader-‐>load('exchangerates.xml'); }
Array ( [0] => Array (
[exchange_rates] => Array ( [curl] => Array ( [CURLOPT_TIMEOUT] => 5 ) ) ) [1] => Array ( [exchange_rates] => Array ( [curl] => Array ( [CURLOPT_TIMEOUT] => 10, [CURLOPT_PROXY] => http:// localhost:8888 ) ) ) )
Array ( [exchange_rates] => Array (
[curl] => Array ( [CURLOPT_TIMEOUT] => 10 [CURLOPT_PROXY] => http://localhost:8888 ) [endpoint] => http://www.ecb.europa.eu/stats... ) )
class Configuration implements ConfigurationInterface { public function getConfigTreeBuilder()
{ $treeBuilder = new TreeBuilder(); $rootNode = $treeBuilder>root('acme_dic_workshop'); $rootNode -‐>children() -‐>scalarNode('some_config_var') -‐>isRequired() -‐>defaultValue('foo') -‐>end() -‐>end(); return $treeBuilder; } }
-‐>scalarNode(‘some_url') -‐>isRequired() -‐>cannotBeEmpty() -‐>validate() -‐>ifTrue(function($value)
{ return !filter_var($value, \FILTER_VALIDATE_URL); }) -‐>thenInvalid('Not a valid url.') -‐>end() -‐>end()
http://goo.gl/8sa6Q
Thanks! https://joind.in/7778