= 2) { $first = $value[0]; $last = $value[strlen($value) - 1]; if (($first === '"' && $last === '"') || ($first === "'" && $last === "'")) { $value = substr($value, 1, -1); } } $result[$key] = $value; } return $result; } function expand_env_values(array $env): array { $expanded = $env; $pattern = '/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/'; foreach ($expanded as $key => $value) { $expanded[$key] = preg_replace_callback( $pattern, static function (array $matches) use (&$expanded): string { $lookup = $matches[1]; return (string) ($expanded[$lookup] ?? getenv($lookup) ?: ''); }, (string) $value ) ?? (string) $value; } return $expanded; } function env_value(string $key, array $localEnv, string $default = ''): string { $runtime = getenv($key); if ($runtime !== false && $runtime !== '') { return $runtime; } if (isset($localEnv[$key]) && $localEnv[$key] !== '') { return (string) $localEnv[$key]; } return $default; } function connect_database(): PDO { $env = parse_env_file(__DIR__ . '/../.env'); $env = expand_env_values($env); $databaseUrl = env_value('DATABASE_URL', $env); if ($databaseUrl !== '') { $parts = parse_url($databaseUrl); if ($parts !== false && ($parts['scheme'] ?? '') === 'postgresql') { $host = (string) ($parts['host'] ?? ''); $port = (string) ($parts['port'] ?? '5432'); $dbName = ltrim((string) ($parts['path'] ?? ''), '/'); $user = (string) ($parts['user'] ?? ''); $pass = (string) ($parts['pass'] ?? ''); if ($host !== '' && $dbName !== '' && $user !== '') { $dsn = "pgsql:host={$host};port={$port};dbname={$dbName}"; return new PDO($dsn, $user, $pass, [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, ]); } } } $host = env_value('DB_HOST', $env); $port = env_value('DB_PORT', $env, '5432'); $dbName = env_value('DB_NAME', $env); $user = env_value('DB_USER', $env); $pass = env_value('DB_PASSWORD', $env); if ($host === '' || $dbName === '' || $user === '') { throw new RuntimeException('Missing DB configuration'); } $dsn = "pgsql:host={$host};port={$port};dbname={$dbName}"; return new PDO($dsn, $user, $pass, [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, ]); } function parse_number(mixed $value): ?float { if ($value === null || $value === '') { return null; } if (is_int($value) || is_float($value)) { return (float) $value; } if (!is_string($value)) { return null; } $normalized = str_replace(["\u{00A0}", ' '], '', trim($value)); $normalized = str_replace(',', '.', $normalized); if (!is_numeric($normalized)) { return null; } return (float) $normalized; } function json_response(int $status, array $payload): void { http_response_code($status); header('Content-Type: application/json; charset=utf-8'); echo json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); exit; }