# Шапка
include("inc/_header.php");
$url = $_GET['url'];
if(isset($url)){
if(file_exists(dirname(__FILE__).'/pages/'.$url.'.php')){
include(dirname(__FILE__).'/pages/'.$url.'.php');
} else if(isset($_GET['url']) && $_GET['url'] == 'user'){
include(dirname(__FILE__).'/pages/user/'.$url.'.php');
} else{
include(dirname(__FILE__).'/pages/404.php'); // Если страница не найдена
}
} else{
include(dirname(__FILE__).'/pages/index.php'); // Главная
}
echo $_GET['url'];
# Подвал
include("inc/_footer.php");
$url = strval($_GET["url"]);
switch($url){
case "$url": include("pages/user/$url.php"); break; // Страницы
case "output": @session_destroy(); Header("Location: /"); return; break; // Выход
}
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.+)$ index.php?route=$1 [QSA,L]
try {
// берем переданный роут
$route = trim($_REQUEST['route']??'index');
// проверяем, если в конце слеш, то это index роут
if (substr($route,'-1') == '/') $route.='index';
// минимальная защита от инклуда неожидаемых файлов
// ограничиваем имена до символов a-b, 0-9, тире, нижнее подчеркивание и слеш
if (!preg_match('~^[-a-z0-9/_]+$~i', $route)) throw new Exception('Not allowed route');
// генерим путь к файлу
$filePath = dirname(__FILE__).'/pages/'.$route.'.php';
// если не существует выкидываем ошибку
if (!file_exists($filePath)) throw new Exception('Route not found');
// если существует, инклудим файл
include $filePath;
} catch (Throwable $ex) {
// в случае любых ошибок, показываем 404
// тут обычно делают разные типы эксепшенов и разделяют 400 и 500 ошибки
include dirname(__FILE__).'/pages/404.php';
}
# .htaccess
Options +FollowSymlinks -Indexes
DirectoryIndex public/index.html public/index.php
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.*)$ /public/index.php?_url=/$1 [L,QSA]
<?php
// app.php
define('__ROOT__', __DIR__);
define('__APP__', realpath(__ROOT__ . '/app'));
$routes = require_once __APP__ . '/routes.php';
foreach ($routes as $pattern => $action) {
if (! preg_match($pattern, $_SERVER['REQUEST_URI'], $matches)) continue;
$action = array_filter(explode('/', $action));
$file = basename(array_pop($action), '.php');
array_push($action, $file);
require __APP__ . '/controllers/' . implode('/', $action) . '.php';
break;
}
<?php
// public/index.php
// strict
register_shutdown_function(function () {
$error = error_get_last();
if (! $error) return;
if (! ($error['line'] ?? null)) return;
$errno = $error['type'];
$errmsg = $error['message'];
$errfile = $error['file'];
$errline = $error['line'];
handle(new \ErrorException($errmsg, $errcode = -1, $errno, $errfile, $errline));
});
// error
set_error_handler(function ($errno, $errmsg, $errfile, $errline) {
if (! $errline) return;
throw new \ErrorException($errmsg, $errcode = -1, $errno, $errfile, $errline);
}, E_ALL);
// handle
function handle(\Throwable $e)
{
echo '<pre>';
die(var_dump($e));
}
// index.php
try {
// run application
require_once __DIR__ . '/../app.php';
} catch (\Throwable $e) { handle($e); }
<?php
// app/routes.php
$routes = [];
foreach ([
'/' => 'index',
'/foo/bar' => 'index',
'/hello/world' => 'hello/world',
] as $pattern => $action) {
$routes[ '/^' . preg_quote($pattern, '/') . '$/' ] = $action;
}
return $routes;
<?php
// app/controllers/index.php
echo 'Index';
<?php
// app/controllers/hello/world.php
echo 'Hello/World';