Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
185 changes: 120 additions & 65 deletions docs/en/controllers.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,47 @@ description: "Learn CakePHP controllers: handle requests, render views, manage c

`class` Cake\\Controller\\**Controller**

Controllers are the 'C' in MVC. After routing has been applied and the correct
controller has been found, your controller's action is called. Your controller
should handle interpreting the request data, making sure the correct models
are called, and the right response or view is rendered. Controllers can be
thought of as middle layer between the Model and View. You want to keep your
controllers thin, and your models fat. This will help you reuse
your code and makes your code easier to test.

Commonly, a controller is used to manage the logic around a single model. For
example, if you were building a site for an online bakery, you might have a
RecipesController managing your recipes and an IngredientsController managing your
ingredients. However, it's also possible to have controllers work with more than
one model. In CakePHP, a controller is named after the primary model it
handles.

Your application's controllers extend the `AppController` class, which in turn
extends the core `Controller` class. The `AppController`
class can be defined in **src/Controller/AppController.php** and it should
contain methods that are shared between all of your application's controllers.

Controllers provide a number of methods that handle requests. These are called
*actions*. By default, each public method in
a controller is an action, and is accessible from a URL. An action is responsible
for interpreting the request and creating the response. Usually responses are
in the form of a rendered view, but there are other ways to create responses as
well.
Controllers are the 'C' in MVC. After routing is applied and the correct
controller is found, your controller's action is called. Your controller
should interpret the request, ensure the right models are called, and return
the appropriate response or view. Controllers sit between Model and View.

::: tip Keep Controllers Thin
Move heavy business logic into models and services. Thin controllers are easier
to test and reuse.
:::

Commonly, a controller manages logic around a single model. For example, for
an online bakery you might have a RecipesController managing recipes and an
IngredientsController managing ingredients. However, it's also possible to have
controllers work with more than one model. In CakePHP, a controller is named
after the primary model it handles.

::: info At a Glance

- Controllers coordinate request handling, model calls, and responses.
- Each public method is an action by default.
- Shared logic goes into `AppController`.

:::

Your application's controllers extend the `AppController` class, which extends
the core `Controller` class. The `AppController` class can be defined in
**src/Controller/AppController.php** and should contain methods shared between
all of your application's controllers.

Controllers provide methods that handle requests. These are called *actions*.
By default, each public method in a controller is an action and is accessible
from a URL. An action interprets the request and creates the response. Usually
responses are rendered views, but there are other response types as well.

::: details Naming and Conventions

- Controller names are plural, e.g. `RecipesController`.
- Action names map to view templates by convention.
- Use `AppController` for shared behavior.

:::

<a id="app-controller"></a>

Expand Down Expand Up @@ -88,6 +103,14 @@ CakePHP puts all the important request information into the `$this->request`
property. See the section on [Cake Request](controllers/request-response#cake-request) for more information on the
CakePHP request object.

::: info Request Flow Summary

- Routes map URLs to a controller/action.
- The request data is available via `$this->request`.
- The action returns a response (often a rendered view).

:::

## Controller Actions

Controller actions are responsible for converting the request parameters into a
Expand Down Expand Up @@ -138,6 +161,11 @@ If for some reason you'd like to skip the default behavior, you can return a
`Cake\Http\Response` object from the action with the fully
created response.

::: tip Explicit Responses
Return a `Response` when you need full control (JSON, file downloads, or
custom status codes).
:::

In order for you to use a controller effectively in your own application, we'll
cover some of the core attributes and methods provided by CakePHP's controllers.

Expand All @@ -158,17 +186,20 @@ The `Controller::set()` method is the main way to send data from your
controller to your view. Once you've used `Controller::set()`, the variable
can be accessed in your view:

```php
// First you pass data from the controller:
::: code-group

```php [Controller]
// First you pass data from the controller:
$this->set('color', 'pink');
```

```php [Template]
// Then, in the view, you can utilize the data:
?>

You have selected <?= h($color) ?> icing for the cake.
```

:::

The `Controller::set()` method also takes an
associative array as its first parameter. This can often be a quick way to
assign a set of information to the view:
Expand All @@ -190,6 +221,11 @@ Keep in mind that view vars are shared among all parts rendered by your view.
They will be available in all parts of the view: the template, the layout and
all elements inside the former two.

::: tip View Data Scope
View variables are shared with the layout and elements. Prefer specific keys
to avoid accidental collisions.
:::

### Setting View Options

If you want to customize the view class, layout/template paths, helpers or the
Expand Down Expand Up @@ -228,6 +264,13 @@ Available strategies are:

You can retrieve the current strategy using `getConfigMergeStrategy()`.

::: details When to Change Merge Strategy

- Use shallow merges for small, explicit overrides.
- Use deep merges when you want to extend nested defaults.

:::

::: info Added in version 5.3.0
`ViewBuilder::setConfigMergeStrategy()` and `ViewBuilder::getConfigMergeStrategy()` were added.
:::
Expand Down Expand Up @@ -265,25 +308,22 @@ Although CakePHP will automatically call it after every action's logic
an alternate view file by specifying a view file name as first argument of
`Controller::render()` method.

::: tip Skipping Auto-Render
Call `$this->disableAutoRender()` when the action fully handles the response.
:::

If `$view` starts with '/', it is assumed to be a view or
element file relative to the **templates** folder. This allows
direct rendering of elements, very useful in AJAX calls:

```php
::: code-group

```php [Element]
// Render the element in templates/element/ajaxreturn.php
$this->render('/element/ajaxreturn');
return $this->render('/element/ajaxreturn');
```

The second parameter `$layout` of `Controller::render()` allows you to specify the layout
with which the view is rendered.

#### Rendering a Specific Template

In your controller, you may want to render a different view than the
conventional one. You can do this by calling `Controller::render()` directly. Once you
have called `Controller::render()`, CakePHP will not try to re-render the view:

```php
```php [Custom Template]
namespace App\Controller;

class PostsController extends AppController
Expand All @@ -295,14 +335,7 @@ class PostsController extends AppController
}
```

This would render **templates/Posts/custom_file.php** instead of
**templates/Posts/my_action.php**.

You can also render views inside plugins using the following syntax:
`$this->render('PluginName.PluginController/custom_file')`.
For example:

```php
```php [Plugin Template]
namespace App\Controller;

class PostsController extends AppController
Expand All @@ -314,7 +347,22 @@ class PostsController extends AppController
}
```

This would render **plugins/Users/templates/UserDetails/custom_file.php**
:::

The second parameter `$layout` of `Controller::render()` allows you to specify the layout
with which the view is rendered.

#### Rendering a Specific Template

In your controller, you may want to render a different view than the
conventional one. You can do this by calling `Controller::render()` directly.
Once you have called `Controller::render()`, CakePHP will not try to re-render
the view.

This renders **templates/Posts/custom_file.php** instead of
**templates/Posts/my_action.php**. Rendering plugin templates uses the syntax
`$this->render('Users.UserDetails/custom_file')` and renders
**plugins/Users/templates/UserDetails/custom_file.php**.

<a id="controller-viewclasses"></a>

Expand All @@ -330,6 +378,10 @@ render an HTML view or render a JSON or XML response. To define the list of
supported view classes for a controller is done with the `addViewClasses()`
method:

::: info Content Negotiation
Use `addViewClasses()` to serve multiple formats from the same action.
:::

```php
namespace App\Controller;

Expand Down Expand Up @@ -450,7 +502,9 @@ controller action and rendering a view.

You can redirect using `routing array` values:

```php
::: code-group

```php [Array URL]
return $this->redirect([
'controller' => 'Orders',
'action' => 'confirm',
Expand All @@ -463,20 +517,20 @@ return $this->redirect([
]);
```

Or using a relative or absolute URL:

```php
```php [Relative URL]
return $this->redirect('/orders/confirm');
```

```php [Absolute URL]
return $this->redirect('https://www.example.com');
```

Or to the referer page:

```php
```php [Referer]
return $this->redirect($this->referer());
```

:::

By using the second parameter you can define a status code for your redirect:

```php
Expand Down Expand Up @@ -573,20 +627,22 @@ public function initialize(): void
## Request Life-cycle Callbacks

CakePHP controllers trigger several events/callbacks that you can use to insert
logic around the request life-cycle:
logic around the request life-cycle.

### Event List
::: details Event List

- `Controller.initialize`
- `Controller.startup`
- `Controller.beforeRedirect`
- `Controller.beforeRender`
- `Controller.shutdown`

:::

### Controller Callback Methods

By default, the following callback methods are connected to related events if the
methods are implemented by your controllers
By default, the following callback methods are connected to related events if
the methods are implemented by your controllers.

#### beforeFilter()

Expand Down Expand Up @@ -623,13 +679,12 @@ To redirect from within a controller callback method you can use the following:
```php
public function beforeFilter(EventInterface $event): void
{
if (...) {
if ($this->request->getParam('prefix') !== 'Admin') {
$event->setResult($this->redirect('/'));

return;
}

...
// Normal request handling continues.
}
```

Expand Down