Various Yii 3.0 related documentation
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:
For the “Hello” task, you will create a handler class 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/Echo/Action.php
:
<?php
declare(strict_types=1);
namespace App\Controller\Echo;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Yiisoft\Html\Html;
use Yiisoft\Router\HydratorAttribute\RouteArgument;
final readonly class Action
{
public function __construct(
private ResponseFactoryInterface $responseFactory,
) {}
#[RouteArgument('message')]
public function __invoke(string $message = 'Hello!'): ResponseInterface
{
$response = $this->responseFactory->createResponse();
$response->getBody()->write('The message is: ' . Html::encode($message));
return $response;
}
}
In your example, the __invoke
method receives the $message
parameter that with the help of RouteArgument
attribute
gets the message from URL. The value defaults to "Hello!"
. If the request is made to /say/Goodbye
,
the action assigns the value “Goodbye” to the $message
variable.
The application passes the response through the middleware stack to the emitter that outputs the response to the end user.
Now, to map your handler to URL, you need to add a route in config/common/routes.php
:
<?php
declare(strict_types=1);
use Yiisoft\Router\Group;
use Yiisoft\Router\Route;
return [
Group::create()
->routes(
Route::get('/')
->action(\App\Controller\HomePage\Action::class)
->name('home'),
Route::get('/say[/{message}]')
->action(\App\Controller\Echo\Action::class)
->name('echo/say'),
),
];
In the above, you map the /say[/{message}]
pattern to \App\Controller\Echo\Action
.
For a request, the router creates an instance and calls the __invoke()
method.
The {message}
part of the pattern writes anything specified in this place to the message
request attribute.
[]
marks this part of the pattern as optional.
You also give a echo/say
name to this route to be able to generate URLs pointing to it.
After creating the action and the view open http://localhost/say/Hello+World
in your browser.
This URL displays a page with “The message is: Hello World”.
If you omit the message
parameter in the URL, the page displays “The message is: Hello!”.
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 view templates. They’re scripts you write to generate a response’s body.
For the “Hello” task, create a src/Controller/Echo/template.php
template 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>
In the above code, the message
parameter uses HTML encoding before you print it. You need that because the parameter comes from an end user and is 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 view service executes the say
view as a PHP script.
To use the view, you need to change src/Controller/Echo/Action.php
:
<?php
declare(strict_types=1);
namespace App\Controller\Echo;
use Psr\Http\Message\ResponseInterface;
use Yiisoft\Router\HydratorAttribute\RouteArgument;
use Yiisoft\Yii\View\Renderer\ViewRenderer;
final readonly class Action
{
public function __construct(
private ViewRenderer $viewRenderer,
) {}
#[RouteArgument('message')]
public function __invoke(string $message = 'Hello!'): ResponseInterface
{
return $this->viewRenderer->render(__DIR__ . '/template', [
'message' => $message,
]);
}
}
Now open your browser and check it again. You should see the 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.
In this section, you’ve touched the handler and template 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.
[!NOTE] ← Running applications | Working with forms →