提问人:Manish Shahi 提问时间:11/17/2023 更新时间:11/17/2023 访问量:30
我的自定义PHP框架的路由系统无法有效地阻止直接访问“views/”目录中的文件
My custom PHP framework's routing system isn't effectively preventing direct access to files within the 'views/' directory
问:
我正在开发一个自定义的PHP框架来简化我的日常工作,特别是对于较小的Web项目,我觉得使用Laravel有点繁琐。我的路由器类运行良好,但我遇到了一个问题。“views”、“classes”、“models”和“controllers”文件夹中的文件可直接访问。如何防止这种直接访问?此外,我注意到可以通过 URL“https://localhost:8000/.htaccess”查看“.htaccess”文件。关于如何解决这些问题的任何想法?
类/SimpleRouter.php
<?php
namespace router;
class SimpleRouter
{
private $routes = [];
public function addRoute($method, $url, $handler)
{
// Convert the method to uppercase to standardize
$method = strtoupper($method);
// Check if the method is supported
if (!in_array($method, ['GET', 'POST', 'PUT', 'DELETE'])) {
throw new \Exception("Unsupported method: $method");
}
$this->routes[$method][$url] = $handler;
}
public function route($method, $url)
{
$url = rtrim($url, '/');
$urlParts = $url ? explode('/', $url) : [];
$handled = false;
if (isset($this->routes[$method][$url])) {
// Exact match found for the method and URL, call the handler
$handler = $this->routes[$method][$url];
$this->callHandler($handler);
$handled = true;
} elseif ($method !== 'GET') {
// If the method is not GET and route not found, attempt matching with parameters
$handled = $this->matchWithParams($method, $url, $urlParts);
}
if (!$handled) {
// No matching route found or method not supported, invoke the default 404 handler
$this->defaultRoute();
}
}
private function callHandler($handler, $data = null)
{
if (is_callable($handler)) {
// Callable function, invoke directly
$handler();
} elseif (is_string($handler) && strpos($handler, '@') !== false) {
// Handler is in "Controller@method" format
list($controllerName, $methodName) = explode('@', $handler, 2);
$controller = "\\controllers\\$controllerName";
if (class_exists($controller)) {
$instance = new $controller();
if (method_exists($instance, $methodName)) {
// Call the controller method and pass data if available
if ($data !== null) {
$instance->$methodName($data);
} else {
$instance->$methodName();
}
return;
}
}
// If the controller/method doesn't exist, invoke the default 404 handler
$this->defaultRoute();
} elseif (is_string($handler) && file_exists(__DIR__ . "/../views/{$handler}.php")) {
// Handler is a view file, include it
include_once __DIR__ . "/../views/{$handler}.php";
} else {
// Invalid handler or file not found, invoke the default 404 handler
$this->defaultRoute();
}
}
private function matchWithParams($method, $url, $urlParts)
{
foreach ($this->routes[$method] as $route => $handler) {
$route = rtrim($route, '/');
$routeParts = explode('/', $route);
if (count($routeParts) === count($urlParts)) {
$params = [];
foreach ($routeParts as $key => $part) {
if (!empty($part) && $part[0] === '{' && $part[strlen($part) - 1] === '}') {
// Extract parameter name and pattern from {param:pattern}
preg_match('/{([^:]+)(:([^}]+))?}/', $part, $matches);
$paramName = $matches[1];
$pattern = isset($matches[3]) ? $matches[3] : null;
if ($pattern && !preg_match("/^$pattern$/", $urlParts[$key])) {
// Parameter value doesn't match the pattern, break and try the next route
break 2;
}
$params[$paramName] = $urlParts[$key];
} elseif ($part !== $urlParts[$key]) {
// If parts don't match, break and try the next route
break;
}
}
if (count($params) > 0) {
// Match found, call the handler with parameters
$this->callHandlerWithParams($handler, $params);
return true;
}
}
}
// No match found for the given URL and parameters
return false;
}
private function callHandlerWithParams($handler, $params)
{
if (is_callable($handler)) {
// Callable function, invoke directly with parameters
$handler($params);
} elseif (is_string($handler) && strpos($handler, '@') !== false) {
// Handler is in "Controller@method" format
list($controller, $method) = explode('@', $handler, 2);
if (class_exists($controller) && method_exists($controller, $method)) {
// Controller and method exist, create instance and invoke method with parameters
$instance = new $controller();
$instance->$method($params);
} else {
// Controller or method not found, invoke the default 404 handler
$this->defaultRoute();
}
} elseif (is_string($handler) && file_exists("views/{$handler}.php")) {
// Handler is a view file, include it
include_once "views/{$handler}.php";
} else {
// Invalid handler, invoke the default 404 handler
$this->defaultRoute();
}
}
private function defaultRoute()
{
include('views/errors/404.php');
}
}
请帮忙。提前致谢!
答: 暂无答案
评论
.ht
<Files ~ "^\.htaccess"> Order allow,deny Deny from all Satisfy All </Files>
Satisfy All