0

When my client adds a page to the site, the new pagename should be appended to a RewiteRule regex. So with, for instance fwrite(), I would like PHP to change that RewiteRule regex with values retracted from the database. If this could be done, are there any pitfalls in the process?

Edit: handling in a PHP script would be the solution, if there would'nt be more to it... First domain/index.php?page=pagename is 301 redirected to "domain/pagename" to warn the visitor this page is permanently moved - (this is the old PUBLIC location of the URL and should give this 301). Then requests like "domain/pagename" (the new public location), would be silently,internally rewritten to domain/index.php?page=pagename where verification takes place and a 404 is given when not valid. But just the key, the "page" part of ?page=pagename, is static and can be verified and will give a 404 directly from within the .htaccess . Now, requests like domain/index.php?page=crap will first nicely give a 301 like the valid domain/index.php?page=pagename does, and only when arrived in the index.php can be identified as crap. So there is still a need to get the pagenames from the database to inside the .htaccess.

This is a sample of the .htacces content to give some background to this problem:

ErrorDocument 404 http://localhost/testsite/404.php

RewriteEngine on
RewriteBase /testsite/

## block craprequests without extension like domain/crap > 404  
# The requests domain/pagename that do not go to existing pages, will now be redirected with a 302 to index.php?page=pagename and only then give a 404 through the errorcheck in the code.
# This should be done here, with a RewriteCond regex with database content
RewriteCond %{REQUEST_URI} !404.php$
RewriteRule .* 404.php [R=404,L]

## block-direct-queries ##
RewriteCond %{QUERY_STRING} !marker=1$
RewriteCond %{QUERY_STRING} page=(.*)
RewriteRule ^.*$ %1? [R=301,L]


## strip-extensions ##
RewriteCond %{QUERY_STRING} !.
RewriteCond %{REQUEST_URI} !404.php$
RewriteRule ^([\w+%*\d*\+*\-*]+)\.(php[\s]{0,3}|htm[\s]{0,3}|html[\s]{0,3})$ $1 [R=301,L]

## put-querystring
RewriteRule ^([\w\-_]+)\/?$ index.php?page=$1&marker=1 [L]
4

2 回答 2

2

很抱歉再次向您重复这一点,但没有必要将页面名称存储在 .htaccess 中。这一切都可以在 PHP 中更简单地完成。

您需要的唯一重写规则是:

RewriteCond %{REQUEST_URI} !^/?index\.php$
RewriteRule .* /index.php [L,QSA]

现在,在 PHP 中,您可以执行以下操作:

// The important point here is that $_SERVER['REQUEST_URI'] contains the actual
// path the user typed into their browser, which is what you are interested in

if (strtolower(basename(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH))) === 'index.php') {
    // The user directly requested index.php
    if (!empty($_GET['page']) || value_of_page_is_crap()) {
        // The user requested a bad page
        header("{$_SERVER['SERVER_PROTOCOL']} 404 Not Found");
    } else {
        // Redirect to correct URL
        header("{$_SERVER['SERVER_PROTOCOL']} 301 Moved Permanently");
        header("Location: http://{$_SERVER['HTTP_HOST']}/{$_GET['page']}");
    }
    exit;
}

// The request is allowed to continue
$requestedPage = pathinfo($_SERVER['REQUEST_URI'], PATHINFO_FILENAME);

.htaccess 将通过 PHP 盲目地路由每个请求,其中可以使用比 mod_rewrite 笨拙的基于 PCRE 的规则更精确的逻辑。

PHP 脚本检查用户在浏览器地址栏中键入的 URI。如果他们直接请求index.php,它将检查是否$_GET['page']包含合理的值,如果包含,则将它们重定向到正确的 URL,如果没有响应 404。如果用户没有直接请求 index.php,则脚本可以继续。我添加了一个示例行来展示如何提取他们请求的页面的值,但是如何从这里继续取决于您。

于 2012-08-15T10:00:22.547 回答
1

这很可能是可能的(尽管写入权限可能是一个问题)。但是,通过 index.php 文件路由来自客户端的所有请求并让 PHP 处理路由不是更好的方法吗?

这样,您将具有最大的灵活性,并且您不必做“hacky”的事情。

编辑

所有形式的重定向都可以通过 PHP 完成。例如一个301重定向的例子:

header ('HTTP/1.1 301 Moved Permanently');
header ('Location: http://example.com/new/path'); // note the full address
exit();

有关使用的更多信息,请参阅手册header()

于 2012-08-14T11:35:19.377 回答