CSS 自定义路由器的问题 - PHP
CSS problems with custom Router - PHP
我正在为我的网络应用程序创建自定义路由器。
我使用 MVC。
例如,当我输入 fab.app/portfolio
时,一切都很好。
但是当我输入 fab.app/portfolio/
时,css、图像和 js 都没有显示。
这是因为路径改变了。在第一种情况下,它正在寻找图像的路径是 fab.app/images/(the_image)
但在第二种情况下它是 fab.app/portfolio/images/(the_image)
.
此外,在 index.php 中,我必须为 url 加上和不带斜杠的条目添加一个条目。我不喜欢。我更愿意在没有斜杠的情况下编写它,它也应该与斜杠一起工作。
下面你可以找到路由器和index.php
index.php
<?php
require_once __DIR__ . '/../vendor/autoload.php';
require_once __DIR__ . '/../app/setup.php';
use Fab\Controllers;
use Fab\Router;
$router = new Router\Router();
$router->get('/', 'MainController', 'index');
$router->get('/portfolio', 'ItemsController', 'showAllItems');
$router->get('/portfolio/', 'ItemsController', 'showAllItems');
$router->get('/portfolio/[\w\d]+', 'ItemsController', 'single_item');
$router->get('/about', 'MainController', 'about');
$router->get('/contact', 'MainController', 'contact');
$router->get('/admin/dashboard', 'AdminController', 'index');
$router->get('/admin/dashboard/addItem', 'AdminController', 'addItem');
$router->get('/admin/dashboard/deleteItem', 'AdminController', 'deleteItem');
$router->get('/admin/dashboard/editItem', 'AdminController', 'editItem');
$router->get('/admin/dashboard/contactSupport', 'AdminController', 'contactSupport');
$router->post('/admin/addItem', 'AdminController', 'postAddItem');
$router->post('/admin/deleteItem', 'AdminController', 'postDeleteItem');
$router->post('/admin/editItem', 'AdminController', 'postEditItem');
//$router->get('/test', 'ItemsController', 'showAllItems');
////See inside $router
//echo "<pre>";
//print_r($router);
$router->submit();
Router.php
<?php
/**
* Created by PhpStorm.
* User: antony
* Date: 5/30/16
* Time: 3:31 PM
*/
namespace Fab\Router;
class Router
{
private $_getUri = array();
private $_getController = array();
private $_getMethod = array();
private $_postUri = array();
private $_postController = array();
private $_postMethod = array();
public function __construct()
{
}
/**
* Build a collection of internal GET URLs to look for
* @param $uri - The url that the user types in the browser
* @param $controller - The controller that will handle the url
* @param $method - The method of the controller that will run
*/
public function get($uri, $controller, $method)
{
$this->_getUri[] = $uri;
$this->_getController[] = $controller;
$this->_getMethod[] = $method;
}
/**
* Build a collection of internal POST URLs to look for
* @param $uri - The url that the user types in the browser
* @param $controller - The controller that will handle the url
* @param $method - The method of the controller that will run
*/
public function post($uri, $controller, $method)
{
$this->_postUri[] = $uri;
$this->_postController[] = $controller;
$this->_postMethod[] = $method;
}
public function submit()
{
$found = 0;
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); //get the url
//Map URL to page
foreach ($this->_getUri as $key => $value)
{
if ( $found = preg_match("#^$value$#", $path) )
{
// echo $key . ' => ' . $value; //See what the $path returns
//Find parameter if passed
$parts = explode('/', $path);
count($parts) > 2 ? $parameter=$parts[2] : $parameter=null;
//Instantiate Controller
$controller = 'Fab\Controllers\' . $this->_getController[$key];
$controller = new $controller($parameter);
//Call the appropriate method
$method = $this->_getMethod[$key];
$controller->$method();
break;
}
}
//Show 404 page
if ( $found == 0 )
{
//Instantiate Controller
$controller = 'Fab\Controllers\MainController';
$controller = new $controller();
//Call the appropriate method
$method = 'error404';
$controller->$method();
die();
}
} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); //get the url
foreach ($this->_postUri as $key => $value)
{
if ( $found = preg_match("#^$value$#", $path))
{
// echo $key . ' => ' . $value; //See what the $path returns
//Find parameter if passed
$parts = explode('/', $path);
count($parts) > 2 ? $parameter=$parts[2] : $parameter=null;
//Instantiate Controller
$controller = 'Fab\Controllers\' . $this->_postController[$key];
$controller = new $controller($parameter);
//Call the appropriate method
$method = $this->_postMethod[$key];
$controller->$method();
break;
}
}
//Show 404 page
if ( $found == 0 )
{
//Instantiate Controller
$controller = 'Fab\Controllers\MainController';
$controller = new $controller();
//Call the appropriate method
$method = 'error404';
$controller->$method();
die();
}
}
}
}
.htaccess
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ / [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
AddType 'text/css; charset=UTF-8' css
</IfModule>
在html
中调用css(还有图片和js)的例子
<link href="/css/my-admin-custom.css" rel="stylesheet">
-------------------------------------------- ----------------------
为了清楚起见,这是我解决问题的方法(根据@Max13 的回答)。
这进入 Router.php:
/**
* If last char in URL is '/' redirect without it
* and also check if url is root '/' because this would result
* in infinite loop
*/
if ( ($path[strlen($path)-1] === '/') && !($path === '/') ) { //
$newPath = substr($path, 0, -1);
header("Location: $newPath", true, 302);
exit;
}
带和不带尾部斜杠并不意味着相同的目录级别,所以我认为在您的路由器中 "accept" 两者都不是一个好主意。
因此,恕我直言,一个好的解决方案是:在检查期间,如果 path
以“/”结尾,则发送 302 Found
header 而不带尾部斜杠。
-- 编辑 --
参见(对于header重定向和元标记重定向,两者经常同时使用):https://www.arclab.com/en/websitelinkanalyzer/http-and-meta-redirects.html
我正在为我的网络应用程序创建自定义路由器。 我使用 MVC。
例如,当我输入 fab.app/portfolio
时,一切都很好。
但是当我输入 fab.app/portfolio/
时,css、图像和 js 都没有显示。
这是因为路径改变了。在第一种情况下,它正在寻找图像的路径是 fab.app/images/(the_image)
但在第二种情况下它是 fab.app/portfolio/images/(the_image)
.
此外,在 index.php 中,我必须为 url 加上和不带斜杠的条目添加一个条目。我不喜欢。我更愿意在没有斜杠的情况下编写它,它也应该与斜杠一起工作。
下面你可以找到路由器和index.php
index.php
<?php
require_once __DIR__ . '/../vendor/autoload.php';
require_once __DIR__ . '/../app/setup.php';
use Fab\Controllers;
use Fab\Router;
$router = new Router\Router();
$router->get('/', 'MainController', 'index');
$router->get('/portfolio', 'ItemsController', 'showAllItems');
$router->get('/portfolio/', 'ItemsController', 'showAllItems');
$router->get('/portfolio/[\w\d]+', 'ItemsController', 'single_item');
$router->get('/about', 'MainController', 'about');
$router->get('/contact', 'MainController', 'contact');
$router->get('/admin/dashboard', 'AdminController', 'index');
$router->get('/admin/dashboard/addItem', 'AdminController', 'addItem');
$router->get('/admin/dashboard/deleteItem', 'AdminController', 'deleteItem');
$router->get('/admin/dashboard/editItem', 'AdminController', 'editItem');
$router->get('/admin/dashboard/contactSupport', 'AdminController', 'contactSupport');
$router->post('/admin/addItem', 'AdminController', 'postAddItem');
$router->post('/admin/deleteItem', 'AdminController', 'postDeleteItem');
$router->post('/admin/editItem', 'AdminController', 'postEditItem');
//$router->get('/test', 'ItemsController', 'showAllItems');
////See inside $router
//echo "<pre>";
//print_r($router);
$router->submit();
Router.php
<?php
/**
* Created by PhpStorm.
* User: antony
* Date: 5/30/16
* Time: 3:31 PM
*/
namespace Fab\Router;
class Router
{
private $_getUri = array();
private $_getController = array();
private $_getMethod = array();
private $_postUri = array();
private $_postController = array();
private $_postMethod = array();
public function __construct()
{
}
/**
* Build a collection of internal GET URLs to look for
* @param $uri - The url that the user types in the browser
* @param $controller - The controller that will handle the url
* @param $method - The method of the controller that will run
*/
public function get($uri, $controller, $method)
{
$this->_getUri[] = $uri;
$this->_getController[] = $controller;
$this->_getMethod[] = $method;
}
/**
* Build a collection of internal POST URLs to look for
* @param $uri - The url that the user types in the browser
* @param $controller - The controller that will handle the url
* @param $method - The method of the controller that will run
*/
public function post($uri, $controller, $method)
{
$this->_postUri[] = $uri;
$this->_postController[] = $controller;
$this->_postMethod[] = $method;
}
public function submit()
{
$found = 0;
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); //get the url
//Map URL to page
foreach ($this->_getUri as $key => $value)
{
if ( $found = preg_match("#^$value$#", $path) )
{
// echo $key . ' => ' . $value; //See what the $path returns
//Find parameter if passed
$parts = explode('/', $path);
count($parts) > 2 ? $parameter=$parts[2] : $parameter=null;
//Instantiate Controller
$controller = 'Fab\Controllers\' . $this->_getController[$key];
$controller = new $controller($parameter);
//Call the appropriate method
$method = $this->_getMethod[$key];
$controller->$method();
break;
}
}
//Show 404 page
if ( $found == 0 )
{
//Instantiate Controller
$controller = 'Fab\Controllers\MainController';
$controller = new $controller();
//Call the appropriate method
$method = 'error404';
$controller->$method();
die();
}
} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); //get the url
foreach ($this->_postUri as $key => $value)
{
if ( $found = preg_match("#^$value$#", $path))
{
// echo $key . ' => ' . $value; //See what the $path returns
//Find parameter if passed
$parts = explode('/', $path);
count($parts) > 2 ? $parameter=$parts[2] : $parameter=null;
//Instantiate Controller
$controller = 'Fab\Controllers\' . $this->_postController[$key];
$controller = new $controller($parameter);
//Call the appropriate method
$method = $this->_postMethod[$key];
$controller->$method();
break;
}
}
//Show 404 page
if ( $found == 0 )
{
//Instantiate Controller
$controller = 'Fab\Controllers\MainController';
$controller = new $controller();
//Call the appropriate method
$method = 'error404';
$controller->$method();
die();
}
}
}
}
.htaccess
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ / [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
AddType 'text/css; charset=UTF-8' css
</IfModule>
在html
中调用css(还有图片和js)的例子<link href="/css/my-admin-custom.css" rel="stylesheet">
-------------------------------------------- ----------------------
为了清楚起见,这是我解决问题的方法(根据@Max13 的回答)。 这进入 Router.php:
/**
* If last char in URL is '/' redirect without it
* and also check if url is root '/' because this would result
* in infinite loop
*/
if ( ($path[strlen($path)-1] === '/') && !($path === '/') ) { //
$newPath = substr($path, 0, -1);
header("Location: $newPath", true, 302);
exit;
}
带和不带尾部斜杠并不意味着相同的目录级别,所以我认为在您的路由器中 "accept" 两者都不是一个好主意。
因此,恕我直言,一个好的解决方案是:在检查期间,如果 path
以“/”结尾,则发送 302 Found
header 而不带尾部斜杠。
-- 编辑 --
参见(对于header重定向和元标记重定向,两者经常同时使用):https://www.arclab.com/en/websitelinkanalyzer/http-and-meta-redirects.html