Files
scoutiq/app/Core/Request.php

216 lines
5.0 KiB
PHP

<?php
namespace App\Core;
class Request
{
private array $get;
private array $post;
private array $server;
private array $files;
private array $cookies;
private ?array $json = null;
private array $routeParams = [];
public function __construct()
{
$this->get = $_GET;
$this->post = $_POST;
$this->server = $_SERVER;
$this->files = $_FILES;
$this->cookies = $_COOKIE;
}
/**
* Get request path without query string.
*/
public function getPath(): string
{
$uri = $this->server['REQUEST_URI'] ?? '/';
$position = strpos($uri, '?');
if ($position === false) {
return $uri;
}
return substr($uri, 0, $position);
}
/**
* Get request HTTP method (e.g., GET, POST, PUT, DELETE).
*/
public function getMethod(): string
{
return strtoupper($this->server['REQUEST_METHOD'] ?? 'GET');
}
public function isGet(): bool
{
return $this->getMethod() === 'GET';
}
public function isPost(): bool
{
return $this->getMethod() === 'POST';
}
public function isPut(): bool
{
return $this->getMethod() === 'PUT';
}
public function isDelete(): bool
{
return $this->getMethod() === 'DELETE';
}
/**
* Set route parameters (extracted by Router).
*/
public function setRouteParams(array $params): void
{
$this->routeParams = $params;
}
/**
* Get route parameters or specific key.
*/
public function getRouteParams(): array
{
return $this->routeParams;
}
public function routeParam(string $key, mixed $default = null): mixed
{
return $this->routeParams[$key] ?? $default;
}
/**
* Fetch GET parameter.
*/
public function get(string $key, mixed $default = null): mixed
{
return $this->get[$key] ?? $default;
}
/**
* Fetch POST parameter.
*/
public function post(string $key, mixed $default = null): mixed
{
return $this->post[$key] ?? $default;
}
/**
* Fetch all request parameters parsed.
*/
public function getBody(): array
{
if ($this->isJson()) {
return $this->getJsonBody();
}
$body = [];
if ($this->isGet()) {
foreach ($this->get as $key => $value) {
$body[$key] = filter_input(INPUT_GET, $key, FILTER_DEFAULT);
}
}
if ($this->isPost()) {
foreach ($this->post as $key => $value) {
$body[$key] = filter_input(INPUT_POST, $key, FILTER_DEFAULT);
}
}
return $body;
}
/**
* Check if request is JSON.
*/
public function isJson(): bool
{
$contentType = $this->server['CONTENT_TYPE'] ?? $this->server['HTTP_CONTENT_TYPE'] ?? '';
return str_contains($contentType, 'application/json');
}
/**
* Parse raw JSON request payload.
*/
public function getJsonBody(): array
{
if ($this->json === null) {
$rawInput = file_get_contents('php://input');
$this->json = json_decode($rawInput, true) ?? [];
}
return $this->json;
}
/**
* Get a specific input value (works for GET, POST, and JSON).
*/
public function input(string $key, mixed $default = null): mixed
{
$body = $this->getBody();
return $body[$key] ?? $default;
}
/**
* Get all request headers.
*/
public function getHeaders(): array
{
$headers = [];
foreach ($this->server as $key => $value) {
if (str_starts_with($key, 'HTTP_')) {
$name = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($key, 5)))));
$headers[$name] = $value;
} elseif ($key === 'CONTENT_TYPE') {
$headers['Content-Type'] = $value;
} elseif ($key === 'CONTENT_LENGTH') {
$headers['Content-Length'] = $value;
}
}
return $headers;
}
/**
* Get specific request header.
*/
public function getHeader(string $name, ?string $default = null): ?string
{
$headers = $this->getHeaders();
// Match case-insensitively
foreach ($headers as $key => $val) {
if (strtolower($key) === strtolower($name)) {
return $val;
}
}
return $default;
}
/**
* Get Client IP address.
*/
public function getIp(): string
{
return $this->server['HTTP_CLIENT_IP']
?? $this->server['HTTP_X_FORWARDED_FOR']
?? $this->server['REMOTE_ADDR']
?? '127.0.0.1';
}
/**
* Get User Agent.
*/
public function getUserAgent(): string
{
return $this->server['HTTP_USER_AGENT'] ?? 'Unknown';
}
/**
* Get uploaded file array.
*/
public function file(string $key): ?array
{
return $this->files[$key] ?? null;
}
}