GitHub

HTTP Controllers

Controllers help organize your request handling logic into classes rather than defining everything in route files. Controllers are stored in the app/Http/Controllers directory.

Basic Controllers

Example of a basic controller class:

<?php
        
namespace App\Http\Controllers;

use App\Models\User;

class UserController
{
    /**
    * Retrieve the user for the given ID.
    *
    * @param  int  $id
    * @return Response
    */
    public function show($id)
    {
        $user = User::find($id);
        return view('admin/user', ['user' => $user]);
    }
}

Routing to Controllers

Route to controller actions using this syntax:

use App\Http\Controllers\UserController;
        
Route::get('user/{id}', [UserController::class, 'show']);
Note: Route parameters will automatically be passed to your controller methods in the order they appear in the route.

Controller Organization

You can organize controllers using subdirectories:

app/Http/Controllers/
├── Admin/
│   ├── UserController.php
│   └── DashboardController.php
└── Auth/
    ├── LoginController.php
    └── RegisterController.php

Reference nested controllers using namespace syntax:

Route::get('admin/users', [Admin\UserController::class, 'index']);
Tip: Use php spark make:controller Photo to generate a new controller.

Dependency Injection & Controllers

TinyMVC's service container automatically resolves controller dependencies through constructor and method injection.

Constructor Injection

Type-hint dependencies in your controller's constructor:

<?php

namespace App\Http\Controllers;

use Spark\Http\Auth;

class UserController
{
    /**
     * Create a new controller instance.
     *
     * @param  UserRepository  $users
     * @return void
     */
    public function __construct(private Auth $auth)
    {
    }
}
Note: The service container will automatically resolve and inject dependencies declared in your constructor.

Method Injection

Inject dependencies directly into controller methods:

<?php

namespace App\Http\Controllers;

use Spark\Http\Request;

class UserController
{
    /**
     * Store a new user.
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        $attributes = $request->validate(['name' => 'required']);
        // Logic here
    }
}

Combining Route Parameters and Dependency Injection

When your route has parameters, list them after injected dependencies:

Route definition:

Route::put('user/{id}', [UserController::class, 'update']);

Controller method implementation:

<?php

namespace App\Http\Controllers;

use Spark\Http\Request;

class UserController
{
    /**
     * Update the specified user.
     *
     * @param  Request  $request
     * @param  string  $id
     * @return Response
     */
    public function update(Request $request, $id)
    {
        // $id comes from route parameter
        // $request is injected automatically
    }
}
Best Practice: Use method injection for request-specific dependencies and constructor injection for dependencies needed across all controller methods.

Additional Injection Examples

You can combine multiple dependency types:

public function edit(
    Request $request,
    UserRepository $repository,
    $userId,
    ProfileService $profile
) {
    // $request - Injected
    // $repository - Injected
    // $userId - Route parameter
    // $profile - Injected
}