106 lines
2.9 KiB
PHP
106 lines
2.9 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Request represents an incoming HTTP request
|
|
*/
|
|
class Request
|
|
{
|
|
public string $method;
|
|
public string $uri;
|
|
public string $path;
|
|
public string $query;
|
|
public array $headers;
|
|
public string $body;
|
|
public array $params = [];
|
|
public array $queryParams = [];
|
|
public array $postData = [];
|
|
public array $cookies;
|
|
|
|
/**
|
|
* __construct creates a new Request from PHP globals
|
|
*/
|
|
public function __construct()
|
|
{
|
|
$this->method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
|
|
$this->uri = $_SERVER['REQUEST_URI'] ?? '/';
|
|
|
|
$urlParts = parse_url($this->uri);
|
|
$this->path = $urlParts['path'] ?? '/';
|
|
$this->query = $urlParts['query'] ?? '';
|
|
|
|
parse_str($this->query, $this->queryParams);
|
|
|
|
$this->headers = $this->parseHeaders();
|
|
$this->body = file_get_contents('php://input') ?: '';
|
|
$this->cookies = $_COOKIE ?? [];
|
|
|
|
if ($this->method === 'POST' && $this->contentType() === 'application/x-www-form-urlencoded') {
|
|
parse_str($this->body, $this->postData);
|
|
} elseif ($this->method === 'POST' && str_contains($this->contentType(), 'multipart/form-data')) {
|
|
$this->postData = $_POST ?? [];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* parseHeaders extracts HTTP headers from $_SERVER
|
|
*/
|
|
private function parseHeaders(): array
|
|
{
|
|
$headers = [];
|
|
foreach ($_SERVER as $key => $value) {
|
|
if (str_starts_with($key, 'HTTP_')) {
|
|
$header = str_replace('_', '-', substr($key, 5));
|
|
$headers[strtolower($header)] = $value;
|
|
}
|
|
}
|
|
if (isset($_SERVER['CONTENT_TYPE'])) {
|
|
$headers['content-type'] = $_SERVER['CONTENT_TYPE'];
|
|
}
|
|
if (isset($_SERVER['CONTENT_LENGTH'])) {
|
|
$headers['content-length'] = $_SERVER['CONTENT_LENGTH'];
|
|
}
|
|
return $headers;
|
|
}
|
|
|
|
/**
|
|
* header returns the value of the specified header
|
|
*/
|
|
public function header(string $name): ?string
|
|
{
|
|
return $this->headers[strtolower($name)] ?? null;
|
|
}
|
|
|
|
/**
|
|
* contentType returns the content type without charset
|
|
*/
|
|
public function contentType(): string
|
|
{
|
|
$contentType = $this->header('content-type') ?? '';
|
|
return explode(';', $contentType)[0];
|
|
}
|
|
|
|
/**
|
|
* json decodes the request body as JSON
|
|
*/
|
|
public function json(): mixed
|
|
{
|
|
return json_decode($this->body, true);
|
|
}
|
|
|
|
/**
|
|
* cookie returns the value of the specified cookie
|
|
*/
|
|
public function cookie(string $name): ?string
|
|
{
|
|
return $this->cookies[$name] ?? null;
|
|
}
|
|
|
|
/**
|
|
* param returns a parameter from route params, query params, or post data
|
|
*/
|
|
public function param(string $name): mixed
|
|
{
|
|
return $this->params[$name] ?? $this->queryParams[$name] ?? $this->postData[$name] ?? null;
|
|
}
|
|
}
|