corentin_wakdo/src/app/Core/Response.php
Imugiii a499607add feat(core): accesseurs form/IP du Request, Database::transaction + DatabaseInterface, getters Response
Request::formBody() decode un POST urlencode (le login back-office est un
formulaire, pas du JSON) ; Request::clientIp() resout l'IP client reelle derriere
Traefik (dernier hop X-Forwarded-For valide, repli REMOTE_ADDR). Database::transaction()
enveloppe un jeu d'ecritures dans un begin/commit atomique avec rollback sur exception
(RG-T08) ; DatabaseInterface extrait le seam d'acces aux donnees pour rendre les services
testables avec un double. Response gagne des accesseurs en lecture (body/header/headers)
pour les tests de controleur. Tout est additif et retro-compatible.
2026-06-15 18:15:32 +00:00

114 lines
2.4 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Core;
/**
* Reponse HTTP accumulee puis emise par send().
*
* Permet de construire entierement la reponse avant tout echo, ce qui rend
* le front controller testable et evite les "headers already sent".
*/
final class Response
{
/** @var array<string, string> */
private array $headers = [];
private string $body = '';
public function __construct(private int $status = 200)
{
}
public function setStatus(int $status): self
{
$this->status = $status;
return $this;
}
public function status(): int
{
return $this->status;
}
public function setHeader(string $name, string $value): self
{
$this->headers[$name] = $value;
return $this;
}
public function setBody(string $body): self
{
$this->body = $body;
return $this;
}
public function body(): string
{
return $this->body;
}
public function header(string $name): ?string
{
return $this->headers[$name] ?? null;
}
/**
* @return array<string, string>
*/
public function headers(): array
{
return $this->headers;
}
/**
* @param array<string, string> $headers
*/
public static function make(string $body, int $status, array $headers): self
{
$response = new self($status);
$response->body = $body;
foreach ($headers as $name => $value) {
$response->setHeader($name, $value);
}
return $response;
}
/**
* @param array<string|int, mixed> $data
*/
public function json(array $data, int $status = 200): self
{
$this->status = $status;
$this->setHeader('Content-Type', 'application/json; charset=utf-8');
$this->body = (string) json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
return $this;
}
public function html(string $body, int $status = 200): self
{
$this->status = $status;
$this->setHeader('Content-Type', 'text/html; charset=utf-8');
$this->body = $body;
return $this;
}
public function send(): void
{
http_response_code($this->status);
foreach ($this->headers as $name => $value) {
header($name . ': ' . $value);
}
echo $this->body;
}
}