HTTP Requests

Introduction

Slenix's Request class provides an object-oriented way to interact with the current HTTP request being handled by your application. It encapsulates all incoming data — route parameters, query strings, POST bodies, JSON payloads, uploaded files, cookies, and headers — in a single, expressive API.

The $request object is automatically injected as the first argument to every route handler and controller method:

php
use Slenix\Http\Routing\Router;

Router::get('/users/{id}', function ($request, $response, $params) {
    $id = $request->param('id');
    $ip = $request->ip();
});
php
namespace App\Controllers;

use Slenix\Http\Request;
use Slenix\Http\Response;

class UserController
{
    public function store(Request $request, Response $response): void
    {
        $name  = $request->input('name');
        $email = $request->input('email');
    }
}

Accessing the Request

Request Path and Method

php
// The URI path — e.g. /users/42
$path = $request->uri();

// Full URI including query string — e.g. /users?sort=asc
$full = $request->fullUri();

// HTTP method (respects X-HTTP-Method-Override and _method field)
$method = $request->method(); // 'GET', 'POST', 'PUT', etc.

// Check if the method matches
if ($request->isMethod('POST')) { }
if ($request->isMethod(['PUT', 'PATCH'])) { }

Request URL

php
// Full URL including scheme, host and path
$url = $request->url(); // https://example.com/users/42?page=1

// URL without query string
$base = $request->baseUrl(); // https://example.com/users/42

// Query string only
$qs = $request->queryString(); // page=1

Request Headers

php
// Get a specific header
$contentType = $request->getHeader('Content-Type');

// Get a header with a fallback
$accept = $request->getHeader('Accept', 'application/json');

// Get a header as a comma-separated string
$cacheControl = $request->getHeaderLine('Cache-Control');

// Check if a header exists
if ($request->hasHeader('Authorization')) { }

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

Route Parameters

Route parameters captured from the URI are available via the param() method. They are passed as the third argument $params to route handlers, or you can read them directly from the request:

php
Router::get('/users/{id}/posts/{post}', function ($request, $response, $params) {
    $userId = $request->param('id');
    $postId = $request->param('post');

    // With a fallback default
    $format = $request->param('format', 'json');
});

To retrieve all route parameters at once:

php
$all = $request->params(); // ['id' => '42', 'post' => '7']

Input

Retrieving Input

The input method reads from JSON body, POST data, and query string — in that order of priority:

php
$name  = $request->input('name');
$email = $request->input('email', 'default@example.com');

To retrieve all input data combined:

php
$all = $request->all();

To retrieve only specific fields:

php
$data = $request->only(['name', 'email']);

To retrieve everything except specific fields:

php
$data = $request->except(['password', '_csrf_token']);

Determining if Input is Present

php
// True if the field exists and is not null
if ($request->has('name')) { }

// True if any of the listed fields exist
if ($request->hasAny(['email', 'username'])) { }

// True if the field exists and is not empty
if ($request->filled('name')) { }

// True if the field is absent or empty
if ($request->missing('phone')) { }

Query String

php
// Single query parameter
$page = $request->query('page', 1);
$sort = $request->get('sort', 'asc');

// All query parameters
$params = $request->queryParams();

POST Data

php
// Single POST field
$name = $request->post('name');

// All POST data
$data = $request->postData();

JSON Input

When the incoming request has a Content-Type: application/json header, the input() and all() methods will automatically decode the JSON body. You do not need to call json_decode yourself:

php
Router::post('/api/users', function ($request, $response) {
    $name  = $request->input('name');
    $roles = $request->input('roles'); // array, if JSON contains an array
    $all   = $request->all();          // full decoded payload
});

Raw Request Body

php
$raw = $request->getRawBody();

// Check if the body is not empty
if ($request->hasBody()) { }

Sanitizing Input

The sanitize method retrieves and cleans a single input value:

php
$name  = $request->sanitize('name', 'string'); // strips tags, escapes HTML
$email = $request->sanitize('email', 'email');
$url   = $request->sanitize('website', 'url');
$age   = $request->sanitize('age', 'int');
$price = $request->sanitize('price', 'float');
$slug  = $request->sanitize('slug', 'slug');

To sanitize multiple fields at once:

php
$clean = $request->sanitizeMultiple([
    'name'    => 'string',
    'email'   => 'email',
    'website' => 'url',
    'age'     => 'int',
]);

Available sanitization filters:

FilterDescription
stringStrips HTML tags and escapes special characters
emailRemoves illegal email characters
urlRemoves illegal URL characters
intStrips everything except digits and sign
floatStrips everything except digits, sign, and decimal point
htmlEscapes HTML special characters
trimRemoves leading and trailing whitespace
lowerConverts to lowercase
upperConverts to uppercase
slugConverts to a URL-safe slug

Files

Checking for an Uploaded File

php
if ($request->hasFile('avatar')) {
    $file = $request->file('avatar');
}

Retrieving All Files

php
$files = $request->files(); // array<string, Upload>

For full documentation on handling uploaded files, refer to the File Uploads page.


Cookies

php
// Get a single cookie value
$token = $request->cookie('remember_token');

// With a default fallback
$theme = $request->cookie('theme', 'dark');

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

Request Information

IP Address

The ip() method returns the client's real IP address, automatically handling trusted proxies and X-Forwarded-For headers:

php
$ip = $request->ip();

If your application sits behind a trusted proxy (such as Nginx, Cloudflare, or a load balancer), register the proxy IP so the forwarded headers are respected:

php
$request->setTrustedProxies(['10.0.0.1', '192.168.1.0/24']);

User Agent

php
$ua = $request->userAgent();

Referrer

php
$referer = $request->referer();

// With a default fallback
$referer = $request->referer('/');

// Check if the request came from a specific origin
if ($request->isFromOrigin('https://your-app.com')) { }

Connection Security

php
if ($request->isSecure()) {
    // Request is over HTTPS
}

$scheme = $request->getScheme(); // 'http' or 'https'
$host   = $request->getHost();
$port   = $request->getPort();

Content Negotiation

php
// Is this an AJAX request?
if ($request->isAjax()) { }

// Does the request body contain JSON?
if ($request->isJson()) { }

// Does the client expect a JSON response?
if ($request->expectsJson()) { }

// Does the client accept HTML?
if ($request->acceptsHtml()) { }

Device Detection

php
if ($request->isMobile())  { /* smartphone */ }
if ($request->isTablet())  { /* tablet */ }
if ($request->isDesktop()) { /* desktop browser */ }
if ($request->isBot())     { /* crawler, scraper */ }

// Full device info array
$info = $request->getDeviceInfo();
// [
//   'is_mobile'  => false,
//   'is_tablet'  => false,
//   'is_desktop' => true,
//   'is_bot'     => false,
//   'os'         => 'macOS',
//   'browser'    => 'Chrome',
//   'user_agent' => 'Mozilla/5.0 ...',
// ]

Language Negotiation

php
// All accepted languages sorted by quality factor
$langs = $request->getAcceptableLanguages();
// ['pt-ao', 'pt', 'en-us', 'en']

// Preferred language from a list of available ones
$lang = $request->getPreferredLanguage(['pt', 'en', 'fr']);
// 'pt'

Request Attributes

Attributes are a way for middleware to share data with downstream handlers without polluting the input array:

php
// In a middleware
$request->setAttribute('user', $authenticatedUser);

// In the route handler
$user = $request->getAttribute('user');

// With a fallback
$role = $request->getAttribute('role', 'guest');

// Remove an attribute
$request->removeAttribute('temp');

// Get all attributes
$all = $request->getAttributes();

Server Variables

php
// All $_SERVER data
$server = $request->server();

// A specific server variable
$php = $request->server('SERVER_SOFTWARE');

// With a fallback
$addr = $request->server('REMOTE_ADDR', '127.0.0.1');

Debugging

php
// Full request state as array
$array = $request->toArray();

// Formatted JSON string (for logging)
$json = $request->debug();

// String representation (for log lines)
// "GET /users [HTTPS] - IP: 1.2.3.4 - UA: Mozilla/5.0 ..."
echo $request;

Creating Requests for Testing

You may create Request instances manually for unit and integration testing without simulating a real HTTP cycle:

php
use Slenix\Http\Request;

// GET request with query params
$request = Request::create('GET', '/users?page=2');

// POST request with body data
$request = Request::create('POST', '/users', [
    'name'  => 'Cláudio',
    'email' => 'claudio@example.com',
]);

// JSON request with custom headers
$request = Request::create('PUT', '/users/1', ['name' => 'New Name'], [
    'Content-Type' => 'application/json',
    'Authorization' => 'Bearer token123',
]);

// From current globals (normal usage)
$request = Request::createFromGlobals();

Method Reference

MethodReturnsDescription
param(key, default)mixedRoute parameter
params()arrayAll route parameters
method()stringHTTP method
uri()stringRequest path
fullUri()stringPath + query string
url()stringFull URL
baseUrl()stringURL without query string
queryString()?stringRaw query string
input(key, default)mixedJSON / POST / GET value
all()arrayAll input combined
only(keys)arraySubset of input
except(keys)arrayInput minus specified keys
has(key)boolField exists
hasAny(keys)boolAny of the fields exists
filled(key)boolField exists and is not empty
missing(key)boolField is absent or empty
post(key, default)mixedPOST field
get(key, default)mixedQuery parameter
query(key, default)mixedAlias for get()
sanitize(key, filter)mixedSanitized input value
sanitizeMultiple(rules)arrayMultiple sanitized values
hasFile(key)boolFile was uploaded
file(key)UploadSingle uploaded file
files()arrayAll uploaded files
cookie(key, default)mixedCookie value
cookies()arrayAll cookies
ip()?stringClient IP address
userAgent()?stringUser-Agent header
referer(default)?stringHTTP Referer
isSecure()boolConnection is HTTPS
isMethod(method)boolMethod matches
isAjax()boolXMLHttpRequest
isJson()boolBody is JSON
expectsJson()boolClient wants JSON
isMobile()boolMobile device
isTablet()boolTablet device
isDesktop()boolDesktop browser
isBot()boolBot or crawler
getHeader(name, default)mixedHTTP header
hasHeader(name)boolHeader exists
getAttribute(key, default)mixedRequest attribute
setAttribute(key, value)selfSet request attribute
server(key, default)mixedServer variable
getRawBody()stringRaw request body
toArray()arrayFull request as array
debug()stringJSON dump for logging