HypervelHypervel
Hypervel
Documentation
GitHub
Hypervel
Documentation
GitHub
  • Documentation

    • Prologue

      • Contributing Guide
    • Getting Started

      • Introduction
      • Installation
      • Configuration
      • Directory Structure
      • Deployment
    • Architecture Concepts

      • Request Lifecycle
      • Service Container
      • Service Providers
      • Facades
    • The Basics

      • Routing
      • Middleware
      • CSRF Protection
      • Controllers
      • Requests
      • Responses
      • Views
      • Blade Templates
      • URL Generation
      • Session
      • Validation
      • Error Handling
      • Logging
    • Digging Deeper

      • Artisan Console
      • Broadcasting
      • Cache
      • Collections
      • Context
      • Coroutine
      • Contracts
      • Events
      • File Storage
      • Helpers
      • HTTP Client
      • Localization
      • Mail
      • Notifications
      • Package Development
      • Package Porting
      • Processes
      • Queues
      • Rate Limiting
      • Strings
      • Task Scheduling
    • Security

      • Authentication
      • Authorization
      • Encryption
      • Hashing
    • Database

      • Getting Started
      • Query Builder
      • Pagination
      • Migrations
      • Seeding
      • Redis
    • Eloquent ORM

      • Getting Started
      • Relationships
      • Collections
      • Mutators / Casts
      • API Resources
      • Serialization
      • Factories
    • Testing

      • Getting Started
      • HTTP Tests
      • Console Tests
      • Database
      • Mocking
      • Packages Toolkit

Controllers

  • Introduction
  • Writing Controllers
    • Basic Controllers
    • Single Action Controllers
  • Controller Middleware
  • Dependency Injection and Controllers
  • Proxying Controller Methods

Introduction

Instead of defining all of your request handling logic as closures in your route files, you may wish to organize this behavior using "controller" classes. Controllers can group related request handling logic into a single class. For example, a UserController class might handle all incoming requests related to users, including showing, creating, updating, and deleting users. By default, controllers are stored in the app/Http/Controllers directory.

Writing Controllers

Basic Controllers

By default, all of the controllers for your application are stored in the app/Http/Controllers directory:

Let's take a look at an example of a basic controller. A controller may have any number of public methods which will respond to incoming HTTP requests:

<?php

namespace App\Http\Controllers;

use App\Models\User;
use Psr\Http\Message\ResponseInterface;

class UserController extends Controller
{
    /**
     * Show the profile for a given user.
     */
    public function show(string $id): ResponseInterface
    {
        return view('user.profile', [
            'user' => User::findOrFail($id)
        ]);
    }
}

Once you have written a controller class and method, you may define a route to the controller method like so:

use App\Http\Controllers\UserController;

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

When an incoming request matches the specified route URI, the show method on the App\Http\Controllers\UserController class will be invoked and the route parameters will be passed to the method.

Note

Controllers are not required to extend a base class. However, it is sometimes convenient to extend a base controller class that contains methods that should be shared across all of your controllers.

Single Action Controllers

If a controller action is particularly complex, you might find it convenient to dedicate an entire controller class to that single action. To accomplish this, you may define a single __invoke method within the controller:

<?php

namespace App\Http\Controllers;

class ProvisionServer extends Controller
{
    /**
     * Provision a new web server.
     */
    public function __invoke()
    {
        // ...
    }
}

When registering routes for single action controllers, you do not need to specify a controller method. Instead, you may simply pass the name of the controller to the router:

use App\Http\Controllers\ProvisionServer;

Route::post('/server', ProvisionServer::class);

Controller Middleware

Middleware may be assigned to the controller's routes in your route files:

Route::get('profile', [UserController::class, 'show'], ['middleware' => 'auth']);

Dependency Injection and Controllers

Constructor Injection

The Hypervel service container is used to resolve all Hypervel controllers. As a result, you are able to type-hint any dependencies your controller may need in its constructor. The declared dependencies will automatically be resolved and injected into the controller instance:

<?php

namespace App\Http\Controllers;

use App\Repositories\UserRepository;

class UserController extends Controller
{
    /**
     * Create a new controller instance.
     */
    public function __construct(
        protected UserRepository $users,
    ) {}
}

Method Injection

In addition to constructor injection, you may also type-hint dependencies on your controller's methods. A common use-case for method injection is injecting the Hypervel\Http\Request instance into your controller methods:

<?php

namespace App\Http\Controllers;

use Hypervel\Http\Request;

class UserController extends Controller
{
    /**
     * Store a new user.
     */
    public function store(Request $request): array
    {
        $name = $request->name;

        // Store the user...

        return ['success' => true];
    }
}

If your controller method is also expecting input from a route parameter, list your route arguments after your other dependencies. For example, if your route is defined like so:

use App\Http\Controllers\UserController;

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

You may still type-hint the Hypervel\Http\Request and access your id parameter by defining your controller method as follows:

<?php

namespace App\Http\Controllers;

use Hypervel\Http\Request;

class UserController extends Controller
{
    /**
     * Update the given user.
     */
    public function update(Request $request, string $id): array
    {
        // Update the user...

        return ['success' => true];
    }
}

Proxying Controller Methods

Sometimes you may want to execute some logics before calling controller actions or redefine the action target. You can define callAction method in your controller:

public function callAction(string $action, array $parameters)
{
    if ($oldMethod = $this->oldVersionMethod('action')) {
        return $this->{$oldMethod}($parameters);
    }

    return $this->{$action}($parameters);
}
Edit this page
Last Updated:
Contributors: Albert Chen
Prev
CSRF Protection
Next
Requests