Files
FDMTech/app/Config.php
T

70 lines
2.4 KiB
PHP

<?php
declare(strict_types=1);
namespace FDMTech;
final class Config
{
public function __construct(private array $values, public readonly string $root) {}
public static function load(string $root): self
{
$values = [];
if (is_file($root . '/.env')) {
foreach (file($root . '/.env', FILE_IGNORE_NEW_LINES) as $line) {
$line = trim($line);
if ($line === '' || str_starts_with($line, '#')) {
continue;
}
if (!preg_match('/^([A-Z][A-Z0-9_]*)=(.*)$/D', $line, $match)) {
throw new \RuntimeException('Invalid environment configuration');
}
$value = trim($match[2]);
if (strlen($value) >= 2 && in_array($value[0], ['"', "'"], true) && $value[-1] === $value[0]) {
$value = substr($value, 1, -1);
}
$values[$match[1]] = $value;
}
}
return new self(array_replace($values, getenv()), $root);
}
public function get(string $key, string $default = ''): string
{
return (string) ($this->values[$key] ?? $default);
}
public function bool(string $key, bool $default = false): bool
{
$raw = $this->get($key, $default ? 'true' : 'false');
$value = filter_var($raw, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
if ($value === null) {
throw new \RuntimeException('Invalid boolean configuration');
}
return $value;
}
public function number(string $key, int $default): int
{
$value = filter_var($this->get($key, (string) $default), FILTER_VALIDATE_INT);
if ($value === false || $value < 1 || $value > 86400) {
throw new \RuntimeException('Invalid rate limit configuration');
}
return $value;
}
public function canonical(string $path): string
{
$url = rtrim($this->get('APP_URL'), '/');
if ($url === '') {
return '';
}
if (!filter_var($url, FILTER_VALIDATE_URL) || !in_array(parse_url($url, PHP_URL_SCHEME), ['https', 'http'], true)
|| parse_url($url, PHP_URL_USER) || parse_url($url, PHP_URL_QUERY) || parse_url($url, PHP_URL_FRAGMENT)
|| !in_array(parse_url($url, PHP_URL_PATH), [null, '', '/'], true)) {
throw new \RuntimeException('Invalid APP_URL');
}
return $url . $path;
}
}