Skip to main content
Version: 4.x

Controllers in BowPHP

Introduction​

Controllers are a way to simplify the organization of your projects.

Instead of defining all your request-handling logic as closures in your routing files, you can organize this behavior using controller classes. Controllers can group related request-handling logic into a single class.

Controllers are stored in the app/Controllers directory.

Configuration​

You have the ability to change the namespace of controllers and middlewares. To do so, open the app\Kernel.php file. The middlewares method lets Bow know which is the correct namespace to add to the controller when executing the request or when generating a controller or middleware through the php bow task runner.

Imagine you have an application for managing a school's buses and you want to group all your controllers under App\Bus\Controllers. So how do you do that?

Here is what the code might look like:

# In the `app\Kernel.php` file
public function namespaces()
{
return [
"controller" => "App\\Bus\\Controllers",
...
]
}

Then you will also need to slightly change the task runner configuration:

# In the `bow` file
$command = new Bow\Console\Command(__DIR__);
...
$command->setControllerDirectory(__DIR__.'/app/Bus/Controllers');

Visit this link for more information on customizing the application structure.

Basic controller​

Defining a controller​

Here is an example of a basic controller class. Note that the controller inherits from the base App\Controllers\Controller class. This base class provides a few convenient methods such as the render method, which can be used to compile a view.

namespace App\Controllers;

use App\Controllers\Controller;
use App\Models\User;

class UserController extends Controller
{
/**
* Display the profile for the given user.
*
* @param int $id
* @return mixed
*/
public function show($id)
{
return $this->render('user/profile', ['user' => User::findOrFail($id)]);
}
}

You can define a route in the routes/app.php file to this controller action as follows:

$app->get('user/:id', 'UserController::show');

From now on, when a request matches the URI of the specified route, the show method of the UserController class will be executed. Of course, the route parameters will also be passed to the method.

You can generate a controller using the add:controller command of php bow:

php bow add:controller UserController

Controllers and namespaces​

It is very important to note that we did not need to specify the full controller namespace when defining the controller route. Since public/index.php loads your route files into a routing group containing the namespace, we only specified the part of the class name that comes after the App\Controllers part of the namespace.

If you choose to nest your controllers more deeply within the App\Controllers directory, use the specific class name relative to the App\Controllers root namespace. So, if your full controller class is App\Controllers\Photo\AdminController, you should register the controller routes as follows:

$app->get('/foo', 'Photo\AdminController::action');

You can generate a controller using the add:controller command of php bow:

php bow add:controller Photo/AdminController

Note that the folder name is in camel case. The framework will create the appropriate namespace for the AdminController class, which will be namepsace App\Controllers\Photo;. You will find the controller in an app/Controllers/Photo/AdminController folder.

More information on routing.

Controllers and Middleware​

Middlewares can be assigned to a controller route in your route files. Middlewares are stored in the app\Middlewares folder. For more information on middlewares, visit this link.

Example:

$app->get('profile', 'UserController::show')->middleware('auth');

REST controller​

REST controllers are a simple way to set up a REST API. This approach lets you focus on your logic and let the Framework handle the routing for you.

Defining a rest controller​

To define a new REST controller, you must use the php bow task runner with the generate:resource command in your console or command prompt 😎.

php bow generate:resource PetController

A controller named PetController will then be created. What makes it special is that it already contains predefined methods, and these methods must remain as they are.

namespace App\Controllers;

use App\Controllers\Controller;
use App\Models\Pet;

class PetController extends Controller
{
/**
* Entry point
*
* @return void
*/
public function index()
{
// Code Here
}

/**
* Display the view for creating a resource.
*
* @return void
*/
public function create()
{
// Code Here
}

/**
* Add a new resource to the data store.
*
* @return void
*/
public function store()
{
// Code Here
}

/**
* Retrieve a specific piece of information by identifier.
*
* @param mixed $id
* @return void
*/
public function show($id)
{
// Code Here
}

/**
* Update a resource using a GET parameter.
*
* @param mixed $id
* @return void
*/
public function edit($id)
{
// Code Here
}

/**
* Update a resource.
*
* @param mixed $id
* @return void
*/
public function update($id)
{
// Code Here
}

/**
* Delete a resource.
*
* @param mixed $id
* @return void
*/
public function destroy($id)
{
// Code Here
}
}

Using our REST controller​

To use the REST controller you just have to use the rest method on the global $app variable in your routing files.

Prototype of the rest method​

$app->rest(url, action, where = []);
parameterType
urlString, Array - The name of the route
actionString - The name of the route
whereArray - Constraint on the id variable

Simple usage​

And it looks like this:

$app->rest('pets', 'PetController');

Usage with constraints​

With a constraint it looks like this:

$app->rest('pets', 'PetController', ['id' => '\d+']);

Here the constraint applies to all methods. But you also have the ability to restrict constraints on individual methods like this:

$app->rest('pets', 'PetController', [
'show' => ['id' => '\d+'],
'edit' => ['id' => '[a-z]+'],
]);

Usage with an array as action​

In the case where action is an array, here are the possible key/value pairs.

$action = [
'controller' => 'PetController',
'ignores' => ['index', 'create'],
];

$app->rest('pets', $action, ['id' => '\d+']);

Ignoring methods​

The value of ignores is a list of methods/urls that will be ignored by the router. So, in the previous example, the index and create methods will be unavailable.

Url and Action​

Considering the following REST definition:

$action = [
'controller' => 'PetController',
'ignores' => ['index', 'create'],
];

$app->rest('pets', $action, ['id' => '\d+']);
URLHTTP MethodRoute nameDescription
/petsGETpets.indexReturns the list of pets
/petsPOSTpets.storeAdd another pet
/pets/:idGETpets.showDisplay a single pet
/pets/:idPUT/PATCHpets.updateUpdate the information of a pet
/pets/:idDELETEpets.deleteThis will delete a pet
/pets/createGETpets.createDisplay the creation form

Is something missing?

If you run into problems with the documentation or have suggestions to improve the documentation or the project in general, please open an issue for us, or send a tweet mentioning the Twitter account @bowframework or directly on github.