Saying hello
Note:
This document reflects the current configuration. The Yii team is going to make it simpler before release.
This section describes how to create a new "Hello" page in your application. It's a simple page that will echo back whatever you pass to it or, if nothing passed, will just say "Hello!".
To achieve this goal, you will define a route and create a handler that does the job and forms the response. Then you will improve it to use view for building the response.
Through this tutorial, you will learn three things:
- How to create a handler to respond to request.
- How to map URL to the handler.
- How to create a view to compose the response's content.
Creating a Handler
For the "Hello" task, you will create a EchoController
class with say
method that reads a message
parameter from the request and displays that message back to the user. If the request doesn't provide a message
parameter, the action will display the default "Hello" message.
Create src/Controller/EchoController.php
:
<?php
declare(strict_types=1);
namespace App\Controller;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Yiisoft\Html\Html;
use Yiisoft\Router\CurrentRoute;
class EchoController
{
private ResponseFactoryInterface $responseFactory;
public function __construct(ResponseFactoryInterface $responseFactory)
{
$this->responseFactory = $responseFactory;
}
public function say(CurrentRoute $currentRoute): ResponseInterface
{
$message = $currentRoute->getArgument('message', 'Hello!');
$response = $this->responseFactory->createResponse();
$response->getBody()->write('The message is: ' . Html::encode($message));
return $response;
}
}
The say
method in your example is given $currentRoute
parameter that you can use to obtain a message, whose value defaults to "Hello"
. If the request is made to /say/Goodbye
, the $message
variable within the action will be assigned that value.
The response returned goes through middleware stack into emitter that outputs response to the end user.
Configuring router
Now, to map your handler to URL, you need to add a route in config/common/routes.php
:
<?php
declare(strict_types=1);
use App\Controller\EchoController;
use App\Controller\SiteController;
use Yiisoft\Router\Route;
return [
Route::get('/')->action([SiteController::class, 'index'])->name('home'),
Route::get('/say[/{message}]')->action([EchoController::class, 'say'])->name('echo/say'),
];
In the above you're mapping /say[/{message}]
pattern to EchoController::say()
. For a request its instance will be created and say()
method will be called. The pattern {message}
part means that anything specified in this place will be written to message
request attribute. []
means that this part of the pattern is optional.
You also give a echo/say
name to this route to be able to generate URLs pointing to it.
Trying it out
After creating the action and the view, start a web server with ./yii serve
and follow the following URL:
http://localhost:8080/say/Hello+World
This URL will result in a page displaying "The message is: Hello World".
If you omit the message
parameter in the URL, you would see the page display "The message is: Hello!".
Creating a View Template
Usually, the task is more complicated than printing out "hello world" and involves rendering some complex HTML. For this task, it's handy to use views templates. They're scripts you write to generate a response's body.
For the "Hello" task, create a /resources/views/echo/say.php
view that prints the message
parameter received from the action method:
<?php
use Yiisoft\Html\Html;
/* @var string $message */
?>
<p>The message is: <?= Html::encode($message) ?></p>
Note that in the above code, the message
parameter is HTML-encoded before being printed. This is necessary as the parameter comes from an end user, making it vulnerable to cross-site scripting (XSS) attacks by embedding malicious JavaScript in the parameter.
Naturally, you may put more content in the say
view. The content can consist of HTML tags, plain text, and even PHP statements. In fact, the say
view is a PHP script that's executed by the view service.
To use the view you need to change src/Controller/EchoController.php
:
<?php
declare(strict_types=1);
namespace App\Controller;
use Yiisoft\Yii\View\ViewRenderer;
use Yiisoft\Router\CurrentRoute;
use Psr\Http\Message\ResponseInterface;
class EchoController
{
private ViewRenderer $viewRenderer;
public function __construct(ViewRenderer $viewRenderer)
{
$this->viewRenderer = $viewRenderer->withControllerName('echo');
}
public function say(CurrentRoute $route): ResponseInterface
{
$message = $route->getArgument('message', 'Hello!');
return $this->viewRenderer->render('say', [
'message' => $message,
]);
}
}
Now open your browser and check it again. It should give you similar text but with a layout applied.
Also, you've separated the part about how it works and part of how it's presented. In the larger applications, it helps a lot to deal with complexity.
Summary
In this section, you've touched the handler and view parts of the typical web application. You created a handler as part of a class to handle a specific request. You also created a view to compose the response's content. In this simple example, no data source was involved as the only data used was the message
parameter.
You've also learned about routing in Yii, which acts as the bridge between user requests and handlers.
In the next section, you will learn how to fetch data, and add a new page containing an HTML form.