no-framework-tutorial/07-inversion-of-control.md

52 lines
2.4 KiB
Markdown
Raw Normal View History

[<< previous](06-dispatching-to-a-class.md) | [next >>](08-dependency-injector.md)
2014-09-16 19:48:41 +00:00
### Inversion of Control
2016-11-01 15:26:05 +00:00
In the last part you have set up a controller class and generated output with `echo`. But let's not forget that we have a nice object oriented HTTP abstraction available. But right now it's not accessible inside your class.
2014-09-16 19:48:41 +00:00
The sane option is to use [inversion of control](http://en.wikipedia.org/wiki/Inversion_of_control). This means that instead of giving the class the responsiblity of creating the object it needs, you just ask for them. This is done with [dependency injection](http://en.wikipedia.org/wiki/Dependency_injection).
2016-11-01 15:26:05 +00:00
If this sounds a little complicated right now, don't worry. Just follow the tutorial and once you see how it is implemented, it will make sense.
2014-09-16 19:48:41 +00:00
2014-11-30 20:06:11 +00:00
Change your `Homepage` controller to the following:
2014-09-16 19:48:41 +00:00
2014-09-17 20:06:16 +00:00
```php
2016-11-01 15:27:27 +00:00
<?php declare(strict_types = 1);
2014-09-16 19:48:41 +00:00
2015-09-24 12:07:04 +00:00
namespace Example\Controllers;
2014-09-16 19:48:41 +00:00
use Http\Response;
2014-11-30 20:06:11 +00:00
class Homepage
2014-09-16 19:48:41 +00:00
{
private $response;
public function __construct(Response $response)
{
$this->response = $response;
}
2014-11-30 20:06:11 +00:00
public function show()
2014-09-16 19:48:41 +00:00
{
$this->response->setContent('Hello World');
}
}
```
2016-11-01 15:26:05 +00:00
Note that we are [importing](http://php.net/manual/en/language.namespaces.importing.php) `Http\Response` at the top of the file. This means that whenever you use `Response` inside this file, it will resolve to the fully qualified name.
2014-09-16 19:48:41 +00:00
2016-11-01 15:26:05 +00:00
In the constructor we are now explicitly asking for a `Http\Response`. In this case, `Http\Response` is an interface. So any class that implements the interface can be injected. See [type hinting](http://php.net/manual/en/language.oop5.typehinting.php) and [interfaces](http://php.net/manual/en/language.oop5.interfaces.php) for reference.
2014-09-16 19:48:41 +00:00
2016-11-01 15:26:05 +00:00
Now the code will result in an error because we are not actually injecting anything. So let's fix that in the `Bootstrap.php` where we dispatch when a route was found:
2014-09-16 19:48:41 +00:00
2014-09-17 20:06:16 +00:00
```php
2014-09-16 19:48:41 +00:00
$class = new $className($response);
$class->$method($vars);
```
The `Http\HttpResponse` object implements the `Http\Response` interface, so it fulfills the contract and can be used.
2014-11-16 19:04:42 +00:00
Now everything should work again. But if you follow this example, all your objects that are instantiated this way will have the same objects injected. This is of course not good, so let's fix that in the next part.
2014-09-16 19:48:41 +00:00
2016-04-02 20:48:02 +00:00
[<< previous](06-dispatching-to-a-class.md) | [next >>](08-dependency-injector.md)