$30 off During Our Annual Pro Sale. View Details »
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
890
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
170
Symfony Internals
meandmymonkey
3
900
Divide and Conquer
meandmymonkey
1
680
Deptrac - Keep Your Architecture Clean
meandmymonkey
0
730
Introduction to Docker at PHPBenelux2015
meandmymonkey
3
870
Best Practices in Symfony2
meandmymonkey
0
460
Introduction to Docker at PHPNW2014
meandmymonkey
4
410
O(ops), Authentication!
meandmymonkey
4
940
Best Practices in Symfony2
meandmymonkey
15
1.8k
Other Decks in Programming
See All in Programming
生成AIを活用したリファクタリング実践 ~コードスメルをなくすためのアプローチ
raedion
0
150
flutter_kaigi_2025.pdf
kyoheig3
2
380
海外登壇の心構え - コワクナイヨ - / how to prepare for a presentation abroad
kishida
2
110
WebRTC と Rust と8K 60fps
tnoho
1
560
Why Kotlin? 電子カルテを Kotlin で開発する理由 / Why Kotlin? at Henry
agatan
1
130
知られているようで知られていない JavaScriptの仕様 4選
syumai
0
640
JEP 496 と JEP 497 から学ぶ耐量子計算機暗号入門 / Learning Post-Quantum Crypto Basics from JEP 496 & 497
mackey0225
2
500
アーキテクチャと考える迷子にならない開発者テスト
irof
9
3.4k
20251127_ぼっちのための懇親会対策会議
kokamoto01_metaps
2
130
AIを駆使して新しい技術を効率的に理解する方法
nogu66
1
670
高単価案件で働くための心構え
nullnull
0
170
FlutterKaigi 2025 システム裏側
yumnumm
0
1.2k
Featured
See All Featured
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
61k
Raft: Consensus for Rubyists
vanstee
140
7.2k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
15k
KATA
mclloyd
PRO
32
15k
Bootstrapping a Software Product
garrettdimon
PRO
307
110k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
118
20k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
Reflections from 52 weeks, 52 projects
jeffersonlam
355
21k
Into the Great Unknown - MozCon
thekraken
40
2.2k
GraphQLとの向き合い方2022年版
quramy
49
14k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
285
14k
Git: the NoSQL Database
bkeepers
PRO
432
66k
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