[英]Absolute URL from base folder with rewrite
I have a project running local on WampServer. 我有一个在WampServer上运行本地的项目。 It's an MVC-like structure;
这是一个类似MVC的结构; it rewrites the URL to
index.php?url=$1
. 它将URL重写为
index.php?url=$1
。 Full .htaccess
: 完整
.htaccess
:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]
When I want to send the user to another page using PHP location: <location>
it doesn't do this properly because of the rewriting (all-though I am technically always in index.php
). 当我想使用PHP
location: <location>
将用户发送到另一个页面时location: <location>
由于重写而没有正确执行此操作(尽管我在技术上总是在index.php
)。
For example if I am on http://localhost/project_name/controller/method/
and this controller's constructor or method tries to send me to: 例如,如果我在
http://localhost/project_name/controller/method/
并且此控制器的构造函数或方法尝试将我发送到:
header('location: another_controller/method');
sends me to http://localhost/project_name/controller/method/another_controller/method/
http://localhost/project_name/controller/method/another_controller/method/
header('location: /another_controller/method');
sends me to http://localhost/another_controller/method/
http://localhost/another_controller/method/
But I want it to send me like this: 但我希望它像这样发送给我:
header('location: /another_controller/method');
sends me to http://localhost/project_name/another_controller/method/
http://localhost/project_name/another_controller/method/
Now the only solution I have found is: 现在我找到的唯一解决方案是:
define('BASE_URL','http://localhost/project_name');
header('location: '.BASE_URL.'/another_controller/method/');
But this isn't perfect either because it causes me to have to change this defined constant BASE_URL
whenever the domain or folder name changes. 但这并不完美,因为只要域名或文件夹名称发生变化,我就必须更改此定义的常量
BASE_URL
。 I could also create a method in my BaseController
that creates absolute URLs, but this method would basically just prepend BASE_URL
too. 我也可以在我的
BaseController
中创建一个创建绝对URL的方法,但是这个方法基本上也只是前缀BASE_URL
。
Note: The same problem doesn't arise with HTML's src
and href
attributes, which can use relative paths (without project_name
folder in path). 注意: HTML的
src
和href
属性不会出现同样的问题,它们可以使用相对路径(路径中没有project_name
文件夹)。 I don't understand why however. 但是,我不明白为什么。 Because if the header
location
causes the browser to append the the relative-URL to the current location, why doesn't it have the same behavior when looking for .css
or .js
files. 因为如果标头
location
导致浏览器将相对URL附加到当前位置,为什么在查找.css
或.js
文件时它没有相同的行为。
So... this raises a couple of questions for me: 所以......这为我提出了几个问题:
src
and href
attributes not share this behavior? src
和href
属性不共享此行为? Now the only solution I have found is:
现在我找到的唯一解决方案是:
define('BASE_URL','http://localhost/project_name'); header('location: '.BASE_URL.'/another_controller/method/');
But this isn't perfect either because it causes me to have to change this defined constant BASE_URL whenever the domain or folder name changes.
但这并不完美,因为只要域名或文件夹名称发生变化,我就必须更改此定义的常量BASE_URL。
You shouldn't need to change the defined constant. 您不需要更改定义的常量。 These values can be found dynamically.
可以动态找到这些值。
Example: 例:
if ($_SERVER['DOCUMENT_ROOT'] == dirname($_SERVER['SCRIPT_FILENAME'])) {
define('BASE_PATH', '/');
} else {
define('BASE_PATH', dirname($_SERVER['SCRIPT_NAME']) . '/');
}
$protocol = isset($_SERVER['HTTPS']) ? 'https://' : 'http://';
define('BASE_URL', $protocol . $_SERVER['SERVER_NAME'] . BASE_PATH);
Additionally, rather than worrying about whether to specify an absolute URL or a path, you can wrap the redirect into a function which can handle both: 此外,您可以将重定向包装到可以同时处理两者的函数中,而不是担心是指定绝对URL还是路径。
function redirect($path = null) {
if (isset($path)) {
if (filter_var($path, FILTER_VALIDATE_URL)) {
header('Location: ' . $path);
} else {
header('Location: ' . BASE_URL . $path);
}
} else {
header('Location: ' . BASE_URL);
}
exit;
}
Finally, as @HarshSanghani mentioned in the comments, the base path in your .htaccess
file should match the base path in your code. 最后,正如@HarshSanghani在评论中提到的,
.htaccess
文件中的基本路径应该与代码中的基本路径匹配。 So if BASE_PATH
(based on the example above) outputs /project_name/
, then your .htaccess
should accommodate it: 因此,如果
BASE_PATH
(基于上面的示例)输出/project_name/
,那么您的.htaccess
应该适应它:
RewriteBase /project_name/
To answer your questions: 回答你的问题:
$baseUrl = dirname($_SERVER['SCRIPT_NAME']);
$baseUrl = dirname($_SERVER['SCRIPT_NAME']);
. src
and href
are interpreted by your browser which takes into account the page's <base>
tag. src
和href
由您的浏览器解释,它考虑了页面的<base>
标记。 All paths on a page with a <base>
tag get changed accordingly by your browser. <base>
标记的页面上的所有路径都会相应地由您的浏览器更改。 The HTTP headers you send from your server (for redirect) have nothing to do with the html page you send and are therefore not updated. 您从服务器发送的HTTP标头(用于重定向)与您发送的html页面无关,因此不会更新。
$baseUri
somehow. $baseUri
不知何故。 You should specify RewriteBase in your htaccess file. 您应该在htaccess文件中指定RewriteBase。 Use relative paths in your links and you need nothing more.
在链接中使用相对路径,您不需要任何其他路径。
RewriteBase /project_name/
RewriteEngine on
RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.