If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.
Good news: we've got great flexibility! Bad news: we have to create the service objects by hand and this stuff is duplicated. We need to centralize what we've got here.
To do that, we'll create one special class whose only job is to create these service objects. This class is called a service container, ya know, because it's basically a container for all the service objects. You'll see.
In lib/
create a new file called Container.php
. Inside create a class
called Container
:
class Container | |
{ | |
... lines 5 - 24 | |
} |
In battle.php
and index.php
, we create a new PDO
object. Let's have
Container
do that instead. Create a new public function getPDO()
inside
Container
. Copy the code to make this and paste it here. Hmm, we need the
$configuration
variable, so copy that from bootstrap.php
and put it
here temporarily. Return $pdo
at the bottom and perfect the method by
adding some PHPDoc:
... lines 1 - 2 | |
class Container | |
{ | |
/** | |
* @return PDO | |
*/ | |
public function getPDO() | |
{ | |
$configuration = array( | |
'db_dsn' => 'mysql:host=localhost;dbname=oo_battle', | |
'db_user' => 'root', | |
'db_pass' => null, | |
); | |
$pdo = new PDO( | |
$configuration['db_dsn'], | |
$configuration['db_user'], | |
$configuration['db_pass'] | |
); | |
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); | |
return $pdo; | |
} | |
} |
Ok, nobody needs to do this work by hand anymore. Go to index.php
. At the
top, create a $container
variable and set it to new Container()
. Below
that, replace the new PDO()
stuff with just $container->getPDO()
:
... lines 1 - 3 | |
$container = new Container(); | |
$pdo = $container->getPDO(); | |
... lines 6 - 122 |
Copy those lines and repeat this in battle.php
:
... lines 1 - 3 | |
$container = new Container(); | |
$pdo = $container->getPDO(); | |
... lines 6 - 110 |
Before trying this, don't forget to go to bootstrap.php
: we need to require
the file so we can access the new class:
... lines 1 - 8 | |
require_once __DIR__.'/lib/Container.php'; | |
... lines 10 - 14 |
Hey, let's give it a shot! Refresh! No problems.
Ok, we've started removing duplication. But I made us go one step backwards:
once again, our configuration is buried inside a class - I'd rather have
that somewhere central. Fix this like we always do when we want to remove
some details from a class: create a public function __construct()
with
a $configuration
argument. Add the $configuration
property and assign
it in the construct function:
... lines 1 - 2 | |
class Container | |
{ | |
private $configuration; | |
public function __construct(array $configuration) | |
{ | |
$this->configuration = $configuration; | |
} | |
... lines 11 - 25 | |
} |
Down in getPDO()
, let's celebrate! Remove the $configuration
variable
and reference the property instead:
... lines 1 - 2 | |
class Container | |
{ | |
private $configuration; | |
... lines 6 - 14 | |
public function getPDO() | |
{ | |
$pdo = new PDO( | |
$this->configuration['db_dsn'], | |
$this->configuration['db_user'], | |
$this->configuration['db_pass'] | |
); | |
... lines 22 - 24 | |
} | |
} |
This is an easy change - bootstrap.php
already holds the central $configuration
array. In battle.php
pass $configuration
to the Container:
... lines 1 - 3 | |
$container = new Container($configuration); | |
... lines 5 - 110 |
And do the same thing for index.php
:
... lines 1 - 3 | |
$container = new Container($configuration); | |
$pdo = $container->getPDO(); | |
... lines 6 - 122 |
Time for a sanity check! Refresh! Oh no!
PDOException on Container.php line 21
Put on your debugging cap! That's the line that creates the new PDO
object.
Hmm, we didn't change anything - this is fishy. Dump $this->configuration
and
refresh. Ah, it's null
. Well, clearly that's not right. I see it. Silly
mistake: in __construct()
, I wasn't assigning the property. Make sure you
have $this->configuration = $configuration
:
... lines 1 - 2 | |
class Container | |
{ | |
private $configuration; | |
public function __construct(array $configuration) | |
{ | |
$this->configuration = $configuration; | |
} | |
... lines 11 - 25 | |
} |
We were passing in the configuration, but I had forgot to set it on my property. Try it again. Excellent!
This keeps my requirement of a centralized configuration array and centralizing where we create service objects. But we still need to move a few more service objects in here and fix one more issue. Almost there!
"Houston: no signs of life"
Start the conversation!