115 lines
3.3 KiB
PHP
115 lines
3.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Core\Http;
|
|
|
|
class Request
|
|
{
|
|
private string $method;
|
|
private string $uri;
|
|
private string $path;
|
|
private array $queryParams;
|
|
private array $bodyParams;
|
|
private array $headers;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->method = strtoupper($_SERVER['REQUEST_METHOD'] ?? 'GET');
|
|
|
|
// Handle method overriding via _method for forms (PUT/DELETE/PATCH)
|
|
if ($this->method === 'POST' && isset($_POST['_method'])) {
|
|
$this->method = strtoupper($_POST['_method']);
|
|
}
|
|
|
|
$this->uri = $_SERVER['REQUEST_URI'] ?? '/';
|
|
$parsedUrl = parse_url($this->uri);
|
|
$this->path = $parsedUrl['path'] ?? '/';
|
|
|
|
// Trim trailing slash for consistent routing (except root)
|
|
if ($this->path !== '/' && str_ends_with($this->path, '/')) {
|
|
$this->path = rtrim($this->path, '/');
|
|
}
|
|
|
|
$this->queryParams = $_GET;
|
|
|
|
// Safely extract headers in all SAPIs
|
|
if (function_exists('getallheaders')) {
|
|
$this->headers = getallheaders() ?: [];
|
|
} else {
|
|
$this->headers = [];
|
|
foreach ($_SERVER as $name => $value) {
|
|
if (str_starts_with($name, 'HTTP_')) {
|
|
$headerName = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))));
|
|
$this->headers[$headerName] = $value;
|
|
} elseif (in_array($name, ['CONTENT_TYPE', 'CONTENT_LENGTH'], true)) {
|
|
$headerName = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', $name))));
|
|
$this->headers[$headerName] = $value;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Parse JSON or form POST body
|
|
$contentType = $_SERVER['CONTENT_TYPE'] ?? '';
|
|
if (str_contains($contentType, 'application/json')) {
|
|
$rawBody = file_get_contents('php://input');
|
|
$this->bodyParams = json_decode($rawBody, true) ?: [];
|
|
} else {
|
|
$this->bodyParams = $_POST;
|
|
}
|
|
}
|
|
|
|
public function getMethod(): string
|
|
{
|
|
return $this->method;
|
|
}
|
|
|
|
public function getPath(): string
|
|
{
|
|
return $this->path;
|
|
}
|
|
|
|
public function getUri(): string
|
|
{
|
|
return $this->uri;
|
|
}
|
|
|
|
public function get(string $key, mixed $default = null): mixed
|
|
{
|
|
return $this->queryParams[$key] ?? $default;
|
|
}
|
|
|
|
public function post(string $key, mixed $default = null): mixed
|
|
{
|
|
return $this->bodyParams[$key] ?? $default;
|
|
}
|
|
|
|
public function all(): array
|
|
{
|
|
return array_merge($this->queryParams, $this->bodyParams);
|
|
}
|
|
|
|
public function getBody(): array
|
|
{
|
|
return $this->bodyParams;
|
|
}
|
|
|
|
public function getHeader(string $name, ?string $default = null): ?string
|
|
{
|
|
$name = strtolower($name);
|
|
foreach ($this->headers as $key => $value) {
|
|
if (strtolower($key) === $name) {
|
|
return $value;
|
|
}
|
|
}
|
|
return $default;
|
|
}
|
|
|
|
public function isJson(): bool
|
|
{
|
|
$contentType = $_SERVER['CONTENT_TYPE'] ?? '';
|
|
$accept = $_SERVER['HTTP_ACCEPT'] ?? '';
|
|
return str_contains($contentType, 'application/json') || str_contains($accept, 'application/json');
|
|
}
|
|
}
|