2009-06-30 11 views
0

私は.htaccessファイルで簡単なURL書換え設定をしています。抜粋:mod_rewriteのURLを逆にマッピングすることはできますか?

RewriteEngine On 

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

これは完全に正常に動作します。ただし、古いスタイルのURLに対するリクエストも同様です。このようなリクエストが届くと、私はSEOフレンドリーなURLへの301永久リダイレクトを実行したいと思いますが、/index.php?mod=frontpage&com=showFrontpageをどのようにして/homeにマップするのか分かりません。 .htaccessファイルを解析し、正規表現のハッキングを行う必要がありますか?

URL書き換えはプロジェクトのかなり後半に導入されたため、PHPスクリプトは発生しているURL書き換えを認識していません。 .htaccessファイルには、次の2つの方法でこれを達成することができます...

答えて

0

誰かが興味がある場合は、私はこの(おそらく絶対に恐ろしい)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

、このデータが保存されている唯一の場所である:

  1. の.htaccess
  2. 経由phpcode

経由のいずれかの方法で、リダイレクションループには入らないようにしてください。

経由の.htaccess

使用するRewriteCond QUERY_STRINGとredirect depending on the querystringを確認します。 Apacheが他の書き換えルールの実行を継続するのを防ぐために[L]フラグを追加し、クライアントをリダイレクトするためにR = 301フラグを追加することを忘れないでください。あなたは、クライアントからの要求とサーバからの要求を区別しなければならないのphpここ

経由

。あなたは

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

次に、あなたのコードでは、パラメータが存在するかどうかを確認していない場合はリダイレクトたとえば、追加のパラメータをあなたの書き換えルールを変更し、合格することがあります。

1
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

関連する問題