changed to controllers
This commit is contained in:
parent
d51b44c6d9
commit
87b4cf3a76
4 changed files with 28 additions and 29 deletions
|
@ -2,20 +2,22 @@
|
||||||
|
|
||||||
### Dispatching to a Class
|
### Dispatching to a Class
|
||||||
|
|
||||||
In this tutorial we won't implement [MVC (Model-View-Controller)](http://martinfowler.com/eaaCatalog/modelViewController.html). MVC can't be implemented properly in PHP anyway, at least not in the way it was originally conceived. So forget about MVC and instead let's worry about [separation of concerns](http://en.wikipedia.org/wiki/Separation_of_concerns).
|
In this tutorial we won't implement [MVC (Model-View-Controller)](http://martinfowler.com/eaaCatalog/modelViewController.html). MVC can't be implemented properly in PHP anyway, at least not in the way it was originally conceived. If you want to learn more about this, read [A Beginner's Guide To MVC](http://blog.ircmaxell.com/2014/11/a-beginners-guide-to-mvc-for-web.html) and the followup posts.
|
||||||
|
|
||||||
Instead of just calling everything a controller, let's give our names descriptive names that describe what the class actually does. In this case, we will just display content, so a fitting name would be `Presenter`. If the class does something else, we will name it accordingly.
|
So forget about MVC and instead let's worry about [separation of concerns](http://en.wikipedia.org/wiki/Separation_of_concerns).
|
||||||
|
|
||||||
Create a new folder inside the `src/` folder with the name `HelloWorld`. This will be where all your hello world related code will end up in. In there, create `HelloWorldPresenter.php`.
|
We will need a descriptive name for the classes that handle the requests. For this tutorial I will use `Controllers` because that will be familiar for the people coming from a framework background. You could also name them `Handlers`.
|
||||||
|
|
||||||
|
Create a new folder inside the `src/` folder with the name `Controllers`.In this folder we will place all our controller classes. In there, create a `Homepage.php` file.
|
||||||
|
|
||||||
```php
|
```php
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Example\HelloWorld;
|
namespace Example\Controllers;
|
||||||
|
|
||||||
class HelloWorldPresenter
|
class Homepage
|
||||||
{
|
{
|
||||||
public function helloWorld()
|
public function show()
|
||||||
{
|
{
|
||||||
echo 'Hello World';
|
echo 'Hello World';
|
||||||
}
|
}
|
||||||
|
@ -28,10 +30,7 @@ Now let's change the hello world route so that it calls your new class method in
|
||||||
|
|
||||||
```php
|
```php
|
||||||
return [
|
return [
|
||||||
['GET', '/hello-world', [
|
['GET', '/', ['Example\Controllers\Homepage', 'show']],
|
||||||
'Example\HelloWorld\HelloWorldPresenter',
|
|
||||||
'helloWorld',
|
|
||||||
]],
|
|
||||||
];
|
];
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -52,6 +51,6 @@ case \FastRoute\Dispatcher::FOUND:
|
||||||
|
|
||||||
So instead of just calling a method you are now instantiating an object and then calling the method on it.
|
So instead of just calling a method you are now instantiating an object and then calling the method on it.
|
||||||
|
|
||||||
Now if you visit `http://localhost:8000/hello-world` everything should work. If not, go back and debug. And of course don't forget to commit your changes.
|
Now if you visit `http://localhost:8000/` everything should work. If not, go back and debug. And of course don't forget to commit your changes.
|
||||||
|
|
||||||
[<< previous](5-router.md) | [next >>](7-inversion-of-control.md)
|
[<< previous](5-router.md) | [next >>](7-inversion-of-control.md)
|
|
@ -2,22 +2,22 @@
|
||||||
|
|
||||||
### Inversion of Control
|
### Inversion of Control
|
||||||
|
|
||||||
In the last part you have set up a presenter class and generated output with `echo`. But let's not forget that you have a nice object oriented HTTP abstraction available. But right now it's not accessible inside your class.
|
In the last part you have set up a controller class and generated output with `echo`. But let's not forget that you have a nice object oriented HTTP abstraction available. But right now it's not accessible inside your class.
|
||||||
|
|
||||||
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).
|
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).
|
||||||
|
|
||||||
If it sounds a little complicated right now, don't worry. Just follow the tutorial and once you see how it is implemented things will make more sense.
|
If it sounds a little complicated right now, don't worry. Just follow the tutorial and once you see how it is implemented things will make more sense.
|
||||||
|
|
||||||
Change your `HelloWorldPresenter` to the following:
|
Change your `Homepage` controller to the following:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Example\HelloWorld;
|
namespace Example\Controller;
|
||||||
|
|
||||||
use Http\Response;
|
use Http\Response;
|
||||||
|
|
||||||
class HelloWorldPresenter
|
class Homepage
|
||||||
{
|
{
|
||||||
private $response;
|
private $response;
|
||||||
|
|
||||||
|
@ -26,14 +26,14 @@ class HelloWorldPresenter
|
||||||
$this->response = $response;
|
$this->response = $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function hello()
|
public function show()
|
||||||
{
|
{
|
||||||
$this->response->setContent('Hello World');
|
$this->response->setContent('Hello World');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Please note that you 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.
|
Note that you 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.
|
||||||
|
|
||||||
In the contructor you 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.
|
In the contructor you 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.
|
||||||
|
|
||||||
|
|
|
@ -60,17 +60,17 @@ $class->$method($vars);
|
||||||
|
|
||||||
Now all your controller constructor dependencies will be automatically resolved with Auryn.
|
Now all your controller constructor dependencies will be automatically resolved with Auryn.
|
||||||
|
|
||||||
Go back to your `HelloWorldPresenter.php` and change it to the following:
|
Go back to your `Homepage` controller and change it to the following:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Example\HelloWorld;
|
namespace Example\Controllers;
|
||||||
|
|
||||||
use Http\Request;
|
use Http\Request;
|
||||||
use Http\Response;
|
use Http\Response;
|
||||||
|
|
||||||
class HelloWorldPresenter
|
class Homepage
|
||||||
{
|
{
|
||||||
private $request;
|
private $request;
|
||||||
private $response;
|
private $response;
|
||||||
|
@ -81,7 +81,7 @@ class HelloWorldPresenter
|
||||||
$this->response = $response;
|
$this->response = $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function hello()
|
public function show()
|
||||||
{
|
{
|
||||||
$content = '<h1>Hello World</h1>';
|
$content = '<h1>Hello World</h1>';
|
||||||
$content .= 'Hello ' . $this->request->getParameter('name', 'stranger');
|
$content .= 'Hello ' . $this->request->getParameter('name', 'stranger');
|
||||||
|
@ -90,7 +90,7 @@ class HelloWorldPresenter
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
As you can see now the class has two dependencies. Try to access the page with a GET parameter like this `http://localhost:8000/hello-world?name=Arthur%20Dent`.
|
As you can see now the class has two dependencies. Try to access the page with a GET parameter like this `http://localhost:8000/?name=Arthur%20Dent`.
|
||||||
|
|
||||||
Congratulations, you have now successfully laid the groundwork for your application.
|
Congratulations, you have now successfully laid the groundwork for your application.
|
||||||
|
|
||||||
|
|
|
@ -68,18 +68,18 @@ Of course we also have to add a definition in our `Dependencies.php` file becaus
|
||||||
|
|
||||||
`$injector->alias('Example\Template\Engine', 'Example\Template\MustacheEngineAdapter');`
|
`$injector->alias('Example\Template\Engine', 'Example\Template\MustacheEngineAdapter');`
|
||||||
|
|
||||||
Now in your `HelloWorldPresenter`, add the new dependency like this:
|
Now in your `Homepage` controller, add the new dependency like this:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Example\HelloWorld;
|
namespace Example\Controllers;
|
||||||
|
|
||||||
use Http\Request;
|
use Http\Request;
|
||||||
use Http\Response;
|
use Http\Response;
|
||||||
use Example\Template\Engine as TemplateEngine;
|
use Example\Template\Engine as TemplateEngine;
|
||||||
|
|
||||||
class HelloWorldPresenter
|
class Homepage
|
||||||
{
|
{
|
||||||
private $request;
|
private $request;
|
||||||
private $response;
|
private $response;
|
||||||
|
@ -100,10 +100,10 @@ class HelloWorldPresenter
|
||||||
|
|
||||||
As you can see I imported the engine with an alias. Without the full namespace it would be relatively unclear what a class does if it is just referenced by `Engine`. Also, another part of the application might also have a class with the name `Engine`. So to avoid that I give it a short and descriptive alias.
|
As you can see I imported the engine with an alias. Without the full namespace it would be relatively unclear what a class does if it is just referenced by `Engine`. Also, another part of the application might also have a class with the name `Engine`. So to avoid that I give it a short and descriptive alias.
|
||||||
|
|
||||||
We also have to rewrite the `hello` method. Please note that while we are just passing in a simple array, Mustache also gives you the option to pass in a view context object. We will go over this later, for now let's keep it as simple as possible.
|
We also have to rewrite the `show` method. Please note that while we are just passing in a simple array, Mustache also gives you the option to pass in a view context object. We will go over this later, for now let's keep it as simple as possible.
|
||||||
|
|
||||||
```php
|
```php
|
||||||
public function hello()
|
public function show()
|
||||||
{
|
{
|
||||||
$data = [
|
$data = [
|
||||||
'name' => $this->request->getParameter('name', 'stranger'),
|
'name' => $this->request->getParameter('name', 'stranger'),
|
||||||
|
@ -125,14 +125,14 @@ $injector->define('Mustache_Engine', [
|
||||||
]);
|
]);
|
||||||
```
|
```
|
||||||
|
|
||||||
In your project root folder, create a `templates` folder. In there, create a folder `HelloWorld` and in there a file `Hello.mustache`. The content of the file should look like this:
|
In your project root folder, create a `templates` folder. In there, create a file `Homepage.mustache`. The content of the file should look like this:
|
||||||
|
|
||||||
```
|
```
|
||||||
<h1>Hello World</h1>
|
<h1>Hello World</h1>
|
||||||
Hello {{ name }}
|
Hello {{ name }}
|
||||||
```
|
```
|
||||||
|
|
||||||
Now you can go back to your `HelloWorldPresenter` and change the render line to `$content = $this->templateEngine->render('HelloWorld/Hello', $data);`
|
Now you can go back to your `Homepage` controller and change the render line to `$content = $this->templateEngine->render('Homepage', $data);`
|
||||||
|
|
||||||
Navigate to the hello page in your browser to make sure everything works. And as always, don't forget to commit your changes.
|
Navigate to the hello page in your browser to make sure everything works. And as always, don't forget to commit your changes.
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue