Можно ли отобразить URL-адреса mod_rewrite в обратном порядке? - PullRequest
0 голосов
/ 30 июня 2009

У меня есть простая настройка перезаписи URL с файлом .htaccess. Выдержки:

RewriteEngine On

RewriteRule ^home(/)?$          index.php?mod=frontpage&com=showFrontpage
RewriteRule ^signup(/)?$            index.php?mod=usermanager&com=showRegistrationForm

Это прекрасно работает. Однако так же поступает запрос по старому стилю URL. Когда приходит такой запрос, я хочу выполнить перманентное перенаправление 301 на URL-адрес, дружественный SEO, однако я не могу понять, как мне сопоставить /index.php?mod=frontpage&com=showFrontpage с /home. Должен ли я проанализировать файл .htaccess и сделать для этого какой-нибудь взлом Regex?

Перезапись URL была введена довольно поздно в проект, поэтому PHP-скрипт не «знает» о происходящем перезаписи URL; файл .htaccess является единственным местом, где сохраняются эти данные ...

Ответы [ 3 ]

1 голос
/ 21 января 2011
RewriteEngine On
RewriteBase /

RewriteCond %{REQUEST_URI}  ^/index.php$
RewriteCond %{QUERY_STRING} ^id=(.*)$
RewriteRule ^(.*)$ /home/%1? [R=302] 

example.com / index.php? Id = uri перенаправит на: example.com / home / uri

0 голосов
/ 10 октября 2009

В случае, если кому-то интересно, я решил это сам, используя этот (возможно, абсолютно ужасный) фрагмент кода PHP.

class clsURL {
    static function checkURL() {
        // don't allow requests on old style URL's
        if (($_SERVER['SCRIPT_NAME'] . '?' . $_SERVER['QUERY_STRING']) == $_SERVER['REQUEST_URI'] &&
                $_SERVER['REQUEST_METHOD'] != 'POST') {

            // redirect to new style URL
            $redirectTable = self::createReverseTable();
            $currentURL = $_SERVER['REQUEST_URI'];
            if (substr($currentURL, 0, 1) == "/")
                $currentURL = substr($currentURL, 1);
            $newURL = self::getReverseURL($currentURL, $redirectTable);

            if ($newURL) {
                header ('HTTP/1.1 301 Moved Permanently');
                header ('Location: /' . $newURL);

                exit;
            }
        }
    }

    static function getReverseURL($current, $reverseTable) {
        // filter out some common stuff
        $current = preg_replace("/&mid=[0-9]+/", "", $current);

        foreach ($reverseTable as $pair) {
            if (preg_match("|" . $pair['from'] . "|", $current)) {
                return preg_replace("|" . $pair['from'] . "|", $pair['to'], $current);
            }
        }

        // nothing found
        return false;
    }

    static function createReverseTable() {
        $file = fopen('.htaccess', 'r');
        $reverse = array();

        while ($line = fgets($file)) {
            if (stripos($line, 'RewriteRule') === 0) {
                $parts = preg_split("/[\\s\\t]/", $line, 3, PREG_SPLIT_NO_EMPTY);

                $regex = trim($parts[1]);
                $url = trim($parts[2]);
                $parts[2] = $url;

                $matches = array();
                if (preg_match_all("/\\$[0-9]/", $url, $matches)) {
                    $matches = $matches[0]; // why? don't know.
                    $from = str_replace('?', '\\?', $url);
                    $to = $regex;

                    foreach ($matches as $match) {
                        $index = substr($match, 1);
                        $bracket = 0;

                        for ($i = 0; $i < strlen($regex); ++$i) {
                            if (substr($regex, $i, 1) == "(") {
                                $bracket++;

                                if ($bracket == $index) {
                                    $pattern = "";

                                    $j = $i + 1;
                                    while (substr($regex, $j, 1) != ")") {
                                        $pattern .= substr($regex, $j, 1);
                                        $j++;
                                    }

                                    $from = str_replace('$' . $index, '(' . $pattern . ')', $from);
                                    $to = preg_replace('/\\(' . preg_quote($pattern, '/') . '\\)/', '\\$' . $index, $to, 1);
                                }
                            }
                        }
                    }

                    // remove optional stuff that we don't use
                    $to = str_replace('(-(.*))?', '', $to);

                    // remove ^ and (/)?$
                    $to = substr($to, 1);
                    if (substr($to, -5) == '(/)?$')
                        $to = substr($to, 0, strlen($to) - 5);
                    $from = '^' . $from . '$';

                    // index.php is optional
                    $from = str_replace('index.php', '(?:index\\.php)?', $from);

                    $reverse[] = array(
                        'from' => $from,
                        'to'   => $to
                    );
                } else {
                    $from = str_replace('?', '\\?', $url);
                    $to = $regex;

                    // remove ^ and (/)?$
                    $to = substr($to, 1);
                    if (substr($to, -5) == '(/)?$')
                        $to = substr($to, 0, strlen($to) - 5);
                    $from = '^' . $from . '$';

                    // index.php is optional
                    $from = str_replace('index.php', '(?:index\\.php)?', $from);

                    $reverse[] = array(
                        'from' => $from,
                        'to'   => $to
                    );
                }
            }
        }
        fclose($file);

        return $reverse;
    }
}
0 голосов
/ 30 июня 2009

Вы можете сделать это двумя способами:

  1. через .htaccess
  2. через phpcode

В любом случае, не попадите в петлю перенаправления.

Через .htaccess

Используйте RewriteCond для проверки перенаправления QUERY_STRING и в зависимости от строки запроса . Не забудьте добавить флаг [L], чтобы Apache не выполнял другие правила перезаписи, и флаг R = 301 для перенаправления клиента.

Через php

Здесь вы должны различать запрос от клиента и запросы от сервера. Возможно, вы захотите изменить правило перезаписи и передать дополнительный параметр, например

RewriteRule ^home(/)?$ index.php?mod=frontpage&com=showFrontpage&server=1

Затем в своем коде проверьте, существует ли параметр, и перенаправьте, если нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...