Skip to content

Latest commit

 

History

History
642 lines (456 loc) · 13.3 KB

File metadata and controls

642 lines (456 loc) · 13.3 KB

Requests

The Helpers\Http\Request class provides a comprehensive interface for working with HTTP requests in your application.

Accessing Request Data

all

all(): array

Returns all input data (GET, POST, JSON, etc.) as a single associative array.

  • Example: $data = $request->all();.

post / get

post(?string $key = null, mixed $default = null): mixed
get(?string $key = null, mixed $default = null): mixed

Retrieves specific input from the POST body (including JSON) or the query string. Supports dot notation for accessing nested array data.

  • Example: $name = $request->post('user.profile.name', 'Anonymous');.

Nested Data Access

Anchor supports dot notation across all retrieval methods (post, get, cookies, server). This allows you to safely access deep array structures without manual checks.

// If POST data is: ['user' => ['profile' => ['name' => 'John']]]
$name = request()->post('user.profile.name'); // 'John'

// With a default value
$theme = request()->get('settings.theme', 'light');

only / exclude

only(array $keys): array
exclude(array $keys): array

Retrieves a subset of the request data or all data except the specified keys.

  • Use Case: Filtering data before mass-assigning to a model or service.
  • Example: $data = $request->only(['email', 'password']);.

Checking Input Existence

Check if Key Exists

if ($request->has('email')) {
    // Email field exists in request
}

// Check multiple keys
if ($request->has(['email', 'password'])) {
    // Both fields exist
}

Check if Field is Filled

if ($request->filled('email')) {
    // Email exists and is not empty
}

// Check multiple fields
if ($request->filled(['name', 'email'])) {
    // Both fields are filled
}

Check if Any Field is Filled

if ($request->anyIsFilled(['phone', 'mobile', 'email'])) {
    // At least one contact method is provided
}

Request Methods

Checking Request Method

if ($request->isPost()) {
    // Handle POST request
}

if ($request->isGet()) {
    // Handle GET request
}

if ($request->isPut()) {
    // Handle PUT request
}

if ($request->isPatch()) {
    // Handle PATCH request
}

if ($request->isDelete()) {
    // Handle DELETE request
}

// Check if method changes state
if ($request->isStateChanging()) {
    // POST, PUT, PATCH, or DELETE
}

// Multi-method checks
if ($request->isPostOrPut()) {
    // POST or PUT
}

if ($request->isPostOrPatch()) {
    // POST or PATCH
}

if ($request->isPutOrPatch()) {
    // PUT or PATCH
}

// Custom method check
if ($request->is('POST', 'PATCH')) {
    // Match against any provided methods
}

method

method(): string

Returns the HTTP request method in uppercase.

  • Example: GET, POST, PUT, PATCH, DELETE.

isOptions

if ($request->isOptions()) {
    // Handle OPTIONS request
}

File Uploads

hasFile

if ($request->hasFile()) {
    // Request contains uploaded files
}

file

file(?string $key = null): UploadedFile|array|null

Retrieves one or all uploaded files from the request. Returns an UploadedFile object for easy manipulation.

  • Example: $request->file('avatar')->move('/uploads');.

UploadedFile (FileHandler) Methods

When you retrieve a file using $request->file(), you get a FileHandler instance with several useful methods:

$file = $request->file('avatar');

if ($file->isValid()) {
    $name = $file->getClientOriginalName();
    $extension = $file->getExtension();
    $size = $file->getSize(); // in bytes
    $mimeType = $file->getClientMimeType();
} else {
    $error = $file->getErrorMessage();
}

Multiple File Uploads

$files = $request->file('documents');

if (is_array($files)) {
    foreach ($files as $file) {
        $file->move('/path/to/destination');
    }
}

Headers and Cookies

Accessing Headers

// Get specific header
$contentType = $request->header('content-type');

// Get all headers
$headers = $request->header();

// Check authorization header
$token = $request->getBearerToken();
$authHeader = $request->getAuthToken();

Accessing Cookies

// Get specific cookie
$sessionId = $request->cookies('session_id');

// Get all cookies
$cookies = $request->cookies();

Server Variables

$userAgent = $request->server('HTTP_USER_AGENT');
$remoteAddr = $request->server('REMOTE_ADDR');

Request Information

URL and Routing

// Get current URI
$uri = $request->uri();

// Get full URL
$url = $request->baseUrl();

// Get domain
$domain = $request->domain();

// Get host
$host = $request->host();

// Get scheme
$scheme = $request->scheme(); // 'http' or 'https'

// Check if HTTPS
if ($request->secure()) {
    // Request is over HTTPS
}

// Check if a URL is internal to the application
if ($request->isInternalUrl($url)) {
    // Safe to redirect
}

User Agent and IP

// Get user agent string
$userAgent = $request->userAgent();

// Get client IP address
$ip = $request->ip();

Request Type Detection

// Check if AJAX request
if ($this->request->isAjax()) {
    return $this->asJson(['data' => $data]);
}

// Check content type
if ($this->request->contentTypeIs('json')) {
    // Request content type is application/json
}

// Check accepted response type
if ($this->request->wantsJson()) {
    return $this->asJson($data);
}

if ($this->request->accepts(['html', 'json'])) {
    // Request accepts either HTML or JSON
}

// Check if bot (honeypot triggered)
if ($this->request->isBot()) {
    // Block request
}

// Check if request passes security validation
// Includes CSRF, Honeypot, and Robot check
if ($this->request->isSecurityValid()) {
    // Safe to proceed
}

Authenticated User

If the request has been processed by an authentication layer (like WebAuthMiddleware or ApiAuthMiddleware), you can access the user and their token directly:

// Get the authenticated user object
$user = $request->user();

// Get the raw authentication token
$token = $request->token();

Authentication middleware typically identifies the user and calls $request->setAuthenticatedUser($user) to make it available throughout the request lifecycle.

Validation

The Request object provides integrated support for triggering class-based validation.

validateUsing

validateUsing(string $class): self

Initiates validation using the specified validation class. If validation fails, it automatically triggers the framework's failure handling (e.g., flashing errors to the session and redirecting, or returning a JSON response for API/AJAX).

  • Example: $request->validateUsing(LoginFormRequestValidation::class);

validated

validated(): ?object

Retrieves the validated Data Transfer Object (DTO) populated by Smart Validation or validateUsing.

  • Example: $dto = $this->request->validated();

See Validation Documentation for more details.

Route Context

The Request object can carry structured metadata about the current route, such as the resource name, action being performed, and the required permission. This is typically hydrated by CheckPermissionMiddleware.

Accessing Context

// Get specific context (e.g., 'resource' or 'action')
$resource = $request->getRouteContext('resource'); // e.g., 'users'
$action = $request->getRouteContext('action');     // e.g., 'edit'

// Get all context
$context = $request->allRouteContext();

Route Permissions

You can retrieve the specific permission string that was determined for the current route.

// Get the route permission
$permission = $request->getRoutePermission(); // e.g., 'users.edit'
  • Use Case: Context-aware logging, sidebar highlighting, or dynamic breadcrumbs.

Request Macros

You can extend the Request class with custom methods using macros:

use Helpers\Http\Request;

// Register a macro
Request::macro('isAdmin', function() {
    return $this->user() && $this->user()->role === 'admin';
});

// Use the macro
if ($this->request->isAdmin()) {
    // ...
}

Security Features

CSRF Protection

// Get CSRF token
$token = $request->getCsrfToken();

// Check if CSRF token is valid (automatic in framework)
if ($request->csrfTokenIsValid()) {
    // Token is valid
}

// Check if request passes security validation
if ($request->isSecurityValid()) {
    // CSRF valid, not a bot, not a robot
}

Referer

$referer = $request->referer();

Input Sanitization

By default, all input is sanitized. You can disable this:

// Disable sanitization
$request->sanitize(false);
$rawData = $request->all();

// Re-enable sanitization
$request->sanitize(true);
$cleanData = $request->all();

JSON and XML Requests

The Request class automatically parses JSON and XML payloads:

JSON Requests

// Client sends: {"name": "John", "email": "john@example.com"}
// Content-Type: application/json

$name = $request->post('name'); // 'John'
$email = $request->post('email'); // 'john@example.com'

XML Requests

// Client sends XML
// Content-Type: application/xml

$data = $request->post();
// Automatically parsed from XML to array

PSR-7 Compliance

The Request class is PSR-7 compliant:

// Get URI object
$uri = $request->getUri();

// Get protocol version
$version = $request->getProtocolVersion();

// Get request target
$target = $request->getRequestTarget();

// Get headers (PSR-7 format)
$headers = $request->getHeaders();

// Check if header exists
if ($request->hasHeader('Authorization')) {
    $auth = $request->getHeader('Authorization');
}

// Get header line
$contentType = $request->getHeaderLine('Content-Type');

Immutable Request Modifications

// Create new request with different method
$newRequest = $request->withMethod('PUT');

// Create new request with different URI
$newRequest = $request->withUri($uri);

// Add header
$newRequest = $request->withHeader('X-Custom', 'value');

// Add additional header value
$newRequest = $request->withAddedHeader('Accept', 'application/json');

Route Helpers

The Request class provides several helpers to identify the current route and its properties:

// Check if the current route is an API route
if ($request->routeIsApi()) {
    // ...
}

// Check if current route is the login or logout route
if ($request->isLoginRoute()) {
    // ...
}

if ($request->isLogoutRoute()) {
    // ...
}

// Check if the route requires authentication (based on config)
if ($request->shouldRequireAuth()) {
    // ...
}

// Get the route of the referer (previous page)
$prevRoute = $request->refererRoute();

Route Metadata

// Get current route
$route = $request->route();

// Get route by name
$loginRoute = $request->routeName('auth.login');

// Get full URL for route
$url = $request->fullRoute('users/profile');

// Get full URL by route name
$url = $request->fullRouteByName('users.show');

// Get callback route
$callback = $request->callback();

Use Cases

Form Validation

public function store()
{
    // Check required fields
    if (!$this->request->filled(['name', 'email', 'password'])) {
        $this->flash->error('All fields are required');
        return $this->response->back();
    }

    // Get only needed fields
    $data = $this->request->only(['name', 'email', 'password']);

    // Create user
    User::create($data);
}

File Upload Handling

public function uploadAvatar()
{
    if (!$this->request->file('avatar')) {
        return $this->asJson(['error' => 'No file uploaded'], 400);
    }

    $file = $this->request->file('avatar');

    // Validate and move securely
    // This will validate type (image), size (2MB), and generate a safe filename
    $path = $file->moveSecurely('/uploads/avatars', [
        'type' => 'image',
        'maxSize' => 2097152
    ], false);

    if (empty($path)) {
        return $this->asJson(['error' => $file->getValidationError()], 400);
    }

    return $this->asJson(['filename' => basename($path)]);
}

API Request Handling

public function apiEndpoint()
{
    // Check if JSON request
    if ($this->request->contentTypeIs('json')) {
        $data = $this->request->post();

        // Validate bearer token
        $token = $this->request->getBearerToken();
        if (!$token) {
            return $this->asJson(['error' => 'Unauthorized'], 401);
        }

        // Process request
        return $this->asJson(['success' => true, 'data' => $data]);
    }

    return $this->asJson(['error' => 'Invalid content type'], 400);
}

AJAX Response

public function search()
{
    $query = $this->request->get('q');

    $results = Product::where('name', 'LIKE', "%{$query}%")->get();

    if ($this->request->isAjax()) {
        return $this->asJson($results->all());
    }

    return $this->asView('search/results', ['results' => $results]);
}

Best Practices

  • Always validate input: Never trust user input
  • Use only() or exclude(): Be explicit about what data you accept
  • Check filled() for required fields: Ensures fields exist and aren't empty
  • Sanitize when needed: Default sanitization is enabled, disable only when necessary
  • Use type checking: Validate file types and sizes before processing
  • Leverage security features: CSRF protection is automatic for state-changing requests