Files

38 lines
1.4 KiB
PHP

<?php
declare(strict_types=1);
/**
* Router for local dev (`php -S localhost:8000 scripts/dev-router.php`).
*
* PHP's built-in server ignores .htaccess, so without this it would serve
* the SQLite database, includes, and project files to anyone who can
* reach it — including other devices on the LAN via browser-sync.
* Anything not blocked falls through to the built-in server as normal.
*/
$path = rawurldecode(parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH) ?: '/');
$path = preg_replace('#/+#', '/', $path);
// Case-insensitive: macOS's filesystem is, so /DB/fitz.sqlite would match.
$blocked = '#^/(?:db|inc|bin|scripts|src|dist|node_modules)(?:/|$)'
. '|(?:^|/)\.'
. '|^/(?:package(?:-lock)?\.json|docker-compose\.ya?ml|config(?:\.example)?\.php)$#i';
if (preg_match($blocked, $path)) {
http_response_code(404);
echo 'Not Found';
return true;
}
// Apache (mod_dir) redirects /admin to /admin/; the built-in server just
// serves admin/index.php at /admin. Every relative link on that page then
// resolves against / instead of /admin/ — "menu.php" lands on the public
// menu, "users.php" 404s. Match Apache so dev behaves like production.
if ($path !== '/' && !str_ends_with($path, '/') && is_dir(__DIR__ . '/..' . $path)) {
$query = parse_url($_SERVER['REQUEST_URI'] ?? '', PHP_URL_QUERY);
header('Location: ' . $path . '/' . ($query ? '?' . $query : ''), true, 301);
return true;
}
return false;