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
870
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
150
Symfony Internals
meandmymonkey
3
840
Divide and Conquer
meandmymonkey
1
660
Deptrac - Keep Your Architecture Clean
meandmymonkey
0
690
Introduction to Docker at PHPBenelux2015
meandmymonkey
3
840
Best Practices in Symfony2
meandmymonkey
0
420
Introduction to Docker at PHPNW2014
meandmymonkey
4
400
O(ops), Authentication!
meandmymonkey
4
890
Best Practices in Symfony2
meandmymonkey
15
1.8k
Other Decks in Programming
See All in Programming
DMMを支える決済基盤の技術的負債にどう立ち向かうか / Addressing Technical Debt in Payment Infrastructure
yoshiyoshifujii
5
750
AIコーディングエージェント全社導入とセキュリティ対策
hikaruegashira
15
9.3k
Dart 参戦!!静的型付き言語界の隠れた実力者
kno3a87
0
160
副作用と戦う PHP リファクタリング ─ ドメインイベントでビジネスロジックを解きほぐす
kajitack
3
520
Reactの歴史を振り返る
tutinoko
1
170
Comparing decimals in Swift Testing
417_72ki
0
160
可変性を制する設計: 構造と振る舞いから考える概念モデリングとその実装
a_suenami
10
1.5k
Strands Agents で実現する名刺解析アーキテクチャ
omiya0555
1
110
Claude Code派?Gemini CLI派? みんなで比較LT会!_20250716
junholee
1
800
プロダクトという一杯を作る - プロダクトチームが味の責任を持つまでの煮込み奮闘記
hiliteeternal
0
370
DatadogのArchived LogsをSnowflakeで高速に検索する方法(Archive Searchでオワコンにならないことを祈って) / How to search Datadog Archived Logs quickly with Snowflake (hoping Datadog Archive Search doesn’t make this obsolete)
civitaspo
0
110
CEDEC 2025 『ゲームにおけるリアルタイム通信への QUIC導入事例の紹介』
segadevtech
2
740
Featured
See All Featured
RailsConf 2023
tenderlove
30
1.2k
jQuery: Nuts, Bolts and Bling
dougneiner
63
7.8k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
229
22k
Fashionably flexible responsive web design (full day workshop)
malarkey
407
66k
A designer walks into a library…
pauljervisheath
207
24k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
16k
Navigating Team Friction
lara
188
15k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
357
30k
Statistics for Hackers
jakevdp
799
220k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
251
21k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
15
1.6k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
126
53k
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