URL重写帮助

时间:2009-07-08 21:44:26

标签: php apache mod-rewrite url-rewriting

感谢您的耐心和帮助。我完全重申了这个问题,因为我的所有版本都要花很长时间。 我有一个带有4个入口点的PHP MVC框架:

从根:
的index.php
指数ajax.php
管理员/ index.php文件
管理员/索引ajax.php

我需要一个.htcaccess文件来接收任何请求,并根据url将其重写到相应的文件中。长网址是index.php?rt = cms / view / 15,我希望它是index / cms / view / 15。除了一个问题之外,那部分已经完成了。

现在是我的.htaccess文件:

# htaccess file for framework - GOOD
Options +FollowSymLinks

# Turn on the mod_rewrite engine - GOOD
RewriteEngine On

# Hide indexes - GOOD
Options -Indexes

# If a file is not one of these, continue processing. - GOOD
RewriteRule \.(css|js|jpg|jpeg|png|gif|ico)$ - [L]

# RewriteRules for folder index files
#RewriteRule ^(index)?(.php)?$ index.php [L] - GOOD
#RewriteRule ^admin(/?)(index)?(.php)?$ admin/index.php [L] - GOOD

# RewriteRules for admin folder arguements - going from more specific to less
RewriteRule ^admin/ajax/[A-Za-z0-9-_/]*$ admin/index-ajax.php?rt=$1 [L]
RewriteRule ^admin/[A-Za-z0-9-_/]*$ admin/index.php?rt=$1 [L]

# RewriteRule for root ajax file
RewriteRule ^ajax/[A-Za-z0-9-_/]*$ index-ajax.php?rt=$1 [L]

# RewriteRule for root file - by here, it is not ajax or admin related, so only
# possible option left if the root index file
RewriteRule ^[A-Za-z0-9-_/]*$ index.php?rt=$1 [L]

我创建了一个包含两个文件夹的简单网站 - “root”和“root / admin”,并且每个文件夹中包含一些带有虚拟内容的css,images和javascript文件夹。在“root”和“root / admin”中有一个index.php和index-ajax.php文件,无论url参数是什么,它都是简单的输出,并使用每个文件夹中的css,js和image文件。

我现在遇到的问题是,如果我做一个像index / blah或/ admin / index / blah这样的URL,那么页面显示正确,参数是正确的。然而,当我做一个像index / blah / view或admin / index / blah / view这样的url时,争论是正确的(?rt = blah / view)但是页面出错了,因为css / js / images文件转到索引/ blah / [css]而不是index / [css]。

有关如何处理此问题的任何想法?我允许css / js / image文件通过.htaccess进行,因此那里的工作量会减少。

7 个答案:

答案 0 :(得分:9)

您确定index.php应该处理所有内容吗?静态文件如images / css等呢?

以下是您可能感兴趣的替代方法。您可以将任何尚未作为文件或目录存在的URL转发到index.php文件,然后在那里解析URL,例如[domain.com] / cms / view / 15将被重写为[domain.com] /index.php/cms/view/15。对于这项工作,您需要将apache指令AcceptPathInfo设置为On。

<强> htaccess的:

RewriteEngine On
#check url is not a valid file
RewriteCond %{REQUEST_FILENAME} !-f
#check url is not a valid directory
RewriteCond %{REQUEST_FILENAME} !-d
#rewite anything left
RewriteRule ^(.*)$ index.php/$1 [L]

<强>的index.php

$path = trim($_SERVER['PATH_INFO'], '/');
$pathParts = explode('/', $path);

if (isset($pathParts[0])) {
    $com = $pathParts[0];
} else {
    $com = 'defaultcom';
}

//$com[1] will be 'view' if supplied
//$com[2] will be 15 if supplied

我喜欢这种方法,因为您不必在apache配置中定义和理解URL,但您可以在PHP中完成大部分工作。

修改

你可以使用它作为你的.htaccess,这会将任何带有不在列表中的扩展名的请求重定向到你的PHP脚本。 RewriteCond应该停止对admin文件夹的请求进行重写。

RewriteEngine On
#don't rewrite admin
RewriteCond %{REQUEST_URI} ^admin/
#rewrite anything with a file extension not in the list
RewriteRule !\.(js|gif|jpg|png|css|ico)$ /index.php [L]

答案 1 :(得分:3)

我会这样做like Tom Haigh said并使用PHP解析所请求的URL路径:

// extract the URL path
$_SERVER['REQUEST_URI_PATH'] = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
// extract the path segments
$segments = explode('/', trim($_SERVER['REQUEST_URI_PATH'], '/'));
// expected parameters and its default values
$params = array(
    'com'    => 'default',
    'action' => 'default',
    'val'    => 'default'
);
foreach ($params as $key => $val) {
    if (isset($segments[0])) {
        $_GET[rawurldecode($key)] = rawurldecode(array_shift($segments));
    } else {
        break;
    }
}
$restOfTheURLPath = implode('/', $segments);
var_dump($_GET);

mod_rewrite规则:

# redirect every request, that cannot be mapped to an existing file, to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^admin(/|$) admin/index.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]

修改回复您的评论和现在编辑过的问题:您可以使用结束重写过程的规则排除所需的目录:

RewriteRule ^(css|images)/ - [L]
RewriteRule ^admin/index\.php$ - [L]
RewriteRule !^index\.php$ index.php [L]

答案 2 :(得分:3)

除非我错过了你的问题(我在你的问题编辑之后投球),听起来好像你需要为多文件夹深度的URL修复相对图像/ css路径。简单的解决方案,不要使用相对图像路径!只需使用正斜杠启动您的图像/ CSS链接..

<img src="/img/logo.png" alt="something" />

我总是发现当你有一个模板为许多页面提供不可预测的文件夹深度时,这是一种更简单的方法。只要您有本地开发的测试URL,它就适用于本地和生产服务器。

答案 3 :(得分:2)

嗯,它看起来还不错,除了你放在中间的那些你有点毁了它; $表示正则表达式的结束,所以我认为它不会正常工作。

另外,我认为你可能需要逃避正斜杠,但我不确定。

答案 4 :(得分:1)

# htaccess file for framework - GOOD
Options +FollowSymLinks

# Turn on the mod_rewrite engine - GOOD
RewriteEngine On

# Hide indexes - GOOD
Options -Indexes

# If a file is not one of these, continue processing. - GOOD
RewriteRule ^images/([A-Za-z0-9\-_]*)\.(css|js|jpg|jpeg|png|gif|ico))$ - 
RewriteRule ^images/admin/([A-Za-z0-9\-_]*)\.(css|js|jpg|jpeg|png|gif|ico))$ - 
RewriteRule ^admin/(([A-Za-z0-9\-_/]*)/([A-Za-z0-9\-_]*)\.(css|js|jpg|jpeg|png|gif|ico))$ admin/images/$3.$4 [L]
RewriteRule ^(([A-Za-z0-9\-_/]*)/([A-Za-z0-9\-_]*)\.(css|js|jpg|jpeg|png|gif|ico))$ images/$3.$4 [L]

# RewriteRules for folder index files
#RewriteRule ^(index)?(.php)?$ index.php [L] - GOOD
#RewriteRule ^admin(/?)(index)?(.php)?$ admin/index.php [L] - GOOD

# RewriteRules for admin folder arguements - going from more specific to less
RewriteRule ^admin/ajax/([A-Za-z0-9\-_/]*)$ admin/index-ajax.php?rt=$1 [L]
RewriteRule ^admin/([A-Za-z0-9\-_/]*)$ admin/index.php?rt=$1 [L]

# RewriteRule for root ajax file
RewriteRule ^ajax/([A-Za-z0-9\-_/]*)$ index-ajax.php?rt=$1 [L]

# RewriteRule for root file - by here, it is not ajax or admin related, so only
# possible option left if the root index file
RewriteRule ^([A-Za-z0-9\-_/]*)$ index.php?rt=$1 [L]

上述.htaccess在Linux / apache服务器上使用目录和文件设置进行测试时可以正常工作

我用/或jj / hello / world / images中的图像请求的重写替换了ignore-images行,如果它在admin文件夹中,它将转到/ admin / images

答案 5 :(得分:0)

最后一行应该是:

RewriteRule ^/([A-Za-z\-_]+)/([A-Za-z\-_]+)/([A-Za-z0-9\-_]+)$ /index.php?com=$1&action=$2&val=$3 [L,R]

答案 6 :(得分:0)

所以images / css / etc因为你在HTML中使用了一个相对URL而破坏了,现在你要进行更多的嵌套它们会破坏它们?对于我遇到的其他一些MVC设置,通常会有某种“根路径”变量,由Controller根据请求URL设置,并由View组件用于为所有路径添加前缀,如图像/样式/脚本。 / p>

这会将你的.htaccess问题变成一个控制器/ PHP问题,如果这对你来说是一个可以接受的解决方案,那么你的控制器就会像在“/”上爆炸请求URL一样,计算结果数量,以及从结果中构造相对URL。

我为自定义的MVC设置做了类似的事情;查看http://avogadro.ws/hosted/skel/public/results/school-1并查看CSS位置的头源。该页面的CSS实际上处于http://avogadro.ws/hosted/skel/级别,Controller构建为相对字符串。