8

以下のURLを変換するためにapache-rewriteルールを使用しようとしています:

http://localhost/foo/bar/news.php?id=24

この形式に:

http://localhost/foo/bar/news/foo-bar

番号24idMySQLテーブルのランダムな行であり、フィールドも含まれtitlecontentいます。

MariaDB [blog]> select * from articles;
+----+---------+----------+ 
| id | title   | content  |
+----+---------+----------+ 
|  1 | foo-bar | bla bla  | 
+----+---------+----------+ 
1 row in set (0.00 sec)

私の中には次のルールがあります.htaccess

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
^news/([A_Za_z0_9_]+)$ DIRECTORY/AID/news.php?id=$1 [QSA,L]

次のようなリンクを生成するphpコードもあります。

$link = "<a href='news.php?id={$row['id']}'></a>";
echo $link;  

ただし、目的の最終結果としてパスを変更するための書き換えルールを取得できません。

4

12 に答える 12

4

置換(実際の)URLには、リンクを識別するための番号-Code-があります(説明によると):http://localhost/DIRECTORY/AID/news.php?news = 42

この場合、そのコードは42ですが、表示するURLに含まれていません。その番号がないと、常にエラー404が発生します。次のように入力するだけです:http://localhost/DIRECTORY/AID/news.php?news =

たとえば、「/」の後にコードを追加して、表示するURLを変更する必要があります。ハイフンなどである可能性がありますが、それに応じて正規表現を変更する必要があります。

次のように入力する例を示します。http:// localhost / news / 42 /に移動してhttp:// localhost / DIRECTORY / AID / news.php?news = 42に移動します:

RewriteEngine On
RewriteRule ^news/([0-9]+)/?$ DIRECTORY/AID/news.php?news=$1 [NC,L]

必要なのはそれだけです。この例をテストするには、このコードのみをhttp:// localhost / DIRECTORY /AID/のnews.phpに挿入します。

<?php
if ( $_GET[ 'news' ] == '42' ) {
  echo  "HERE I AM<br /><br />";
}
?>

OPの説明に従って更新されました。This_is_newsの代わりに任意の名前を使用できます:

RewriteEngine On
RewriteRule ^news/([0-9a-zA-Z-_]+)/?$ DIRECTORY/AID/news.php?news=$1 [NC,L]
于 2012-11-26T09:30:34.163 に答える
2

まず、新しいURL形式を指定するには、HTMLのhrefを変更する必要があります。

function news_preview() {
$query = "SELECT * FROM news ORDER BY id DESC LIMIT 5  ";
$result = mysql_query($query) or die(mysql_error());
while($row=mysql_fetch_array($result)) 
{   
  echo "<a href=\"/news/$row[id]\">  ". substr($row['title'], 0,26)."...</a><br/>".; }
}

次のようなURLを生成しますhttp://localhost/news/24

/DIRECTORY/AIDhtaccessは、テキストで述べたものではなく、URLにすることを提案しているため、URLからを削除したことに注意してください。

しかし、今度http://localhost/news/this_is_article_titleはURLのタイプを取得します。this_is_article_titleとidの間に相関関係がないため24、これを実現する唯一の方法は、URLにもidを追加するか、データベースでこのタイトルのニュース記事をphpで検索することです。

ただし、この最後の解決策にはいくつかの問題があります。URLでタイトルだけを指定することはできないからです。文字をエスケープする必要があります。また、パフォーマンスを向上させるために、DBのタイトル行のインデックスを追加する必要があります。

だから私は最初の解決策に行きます。このようなURLを生成します

http://localhost/news/24/this_is_article_title

最初にphpの部分

function news_preview() {
$query = "SELECT * FROM news ORDER BY id DESC LIMIT 5  ";
$result = mysql_query($query) or die(mysql_error());
while($row=mysql_fetch_array($result)) 
{ 
  $url = "/news/$row[id]/".preg_replace('/[^a-zA-Z0-9-_]/', '_', $row['title']);  
  echo "<a href=\"$url\">  ". substr($row['title'], 0,26)."...</a><br/>".; }
}

次はhtaccessの部分です。

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^news/([0-9]+)/([A-Za-z0-9_-]+)$ DIRECTORY/AID/news.php?id=$1 [QSA,L]

それでいいと思います。

于 2012-12-01T20:51:38.213 に答える
1

残念ながら、PHPまたはApacheで質問に答えることはできません(ただし、現在のプロジェクトでURLアドレスを作成するために手動のRESTコンバーターを使用しています)が、私が理解していることから、ユーザーにhttp:/と入力してもらいます。 /localhost/DIRECTORY/AID/article.php?a_id=24で、アドレスバーはhttp:// localhost / DIRECTORY / AID / news/this_is_article_titleのようになります。

これがどのようなメリットをもたらすのか完全にはわかりません。私のソリューションでは、エンドユーザーがRESTful URLを入力して、QueryStringアドレスのページに到達することはできません。これを行うには追加のレッグワークが必要であり、DBとの同期を維持するためにさらに多くのレッグワークが必要です(RESTFUL URLを送信し、DBにトピックを照会してから、IDまたはページコンテンツを返すスクリプトをお勧めします)。 ..しかし、それは別の日の別のStackOverflowの質問です。

ソリューション 提案されたソリューションには、HTML5DoctypeとJavascriptの非常に軽い散水が必要です。

history.replaceState(null, "history title here", "news/this_is_article_title");

これは、ページのリダイレクトやリロードなどをトリガーせずに、アドレスバーのURLを変更することです。このJavaScriptは、PHPを使用して動的に記述できるため、ページが提供されると、アドレスが更新されます。ドキュメントの上位にあるほど、変更は速くなります。

jsFiddleリンクは次のとおりです:http://jsfiddle.net/uT3RP/1/

残念ながら、彼らはiframeでコードを実行しているため、メインのアドレスバーを制御していません。そのため、証拠として、アドレスバーの場所が何を示しているかを表示するアラートを含めました。これは、最も洗練されたソリューションではありません。表示されたURLを使用して同じページにアクセスできることを確認するというフェイルセーフなしで、実行していることを実行することもお勧めしません。免責事項はさておき...あなたの問題は1行のjsとdoctypeの変更(HTML5を使用していない場合)で解決されます。

あなたは貧しいol'htaccessのむち打ちを止めて、あなたのプロジェクトに取り掛かることができます:)

于 2012-12-01T12:02:12.063 に答える
1

RewriteEngineをオンにした直後にRewriteBaseを配置するリダイレクトを開始する前に、リライトエンジンが正しくセットアップされます

于 2012-11-26T12:30:37.860 に答える
1

これが機能するかどうかわかりますか?

RewriteEngine On
RewriteBase /DIRECTORY/AID/
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
^news/([A-Za-z0-9_]+)$ news.php?id=$1 [QSA,L]

編集:正規表現の文字クラスの定義を修正しました。

于 2012-12-05T08:18:02.353 に答える
1

.htaccessファイルが意図したとおりに機能していないと思われる場合、これはサーバー構成の問題でありAllowOverride、Apache構成のディレクティブに関係している可能性があります。

http.confファイルで、次のように見えるセクションを見つけます。

<Directory>
    Options FollowSymLinks
    AllowOverride None
</Directory>

AllowOverrideディレクティブを許可するように変更しますAll

<Directory>
    Options FollowSymLinks
    AllowOverride All
</Directory>

次に、mod_rewriteモジュールがXAMPPインストールで有効になっていることを確認します。次の行を検索します。

#LoadModule rewrite_module modules/mod_rewrite.so

#次のように表示されるように削除します。

LoadModule rewrite_module modules/mod_rewrite.so

すべての変更を保存した後、Apacheサービスを再起動します。

また、次のように、構成でRewriteBaseディレクティブを使用していることを確認してください。.htaccess

RewriteEngine On
RewriteBase /DIRECTORY/AID/
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
^news/([A-Za-z0-9_]+)(/)?$ news.php?title=$1 [QSA,L]

次のことは、リンクがリライトURLを指していることを確認することです。エコーラインは次のようになります。

echo "<a href=\"news/" . $row['title'] . "\">  " . substr($row['title'], 0, 26) . "...</a><br />";

このURL書き換えメソッドでのみタイトルを取得できるため、タイトルに基づいてコンテンツを取得するようにPHPスクリプトを適切に構成する必要があります。それでもレコードの取得にのみ「id」を使用する場合は、リライトURLに何らかの形式で「id」が含まれている必要があります。このフォームの典型的な例は次のとおりです。

  • news/the_news_title_123
  • news/123_the_news_title
  • news/123/the_news_title
于 2012-12-06T05:35:09.610 に答える
1

これは、URL書き換えおよび文字列からIDへのアルゴリズムに関する問題です。

何よりも、リライトモジュールによってURLが変更されても、ブラウザバーのURLには常にidやstring(ニュースについて)などの投稿パラメータが含まれていることに注意してください。

さて、質問に移りましょう。私たちの目的は、URLを書き直すことです。

http://localhost/DIRECTORY/AID/news/this_is_article_title

に:

http://localhost/DIRECTORY/AID/news.php?a_id=24

リライトモジュールでは、次のようにしかリライトできません。

http://localhost/DIRECTORY/AID/news.php?title=this_is_article_title

これがhtaccessの部分で、 htaccess-online-testerで実際にテストされています

RewriteRule ^DIRECTORY/AID/news/([A-Za-z0-9_]+)$ DIRECTORY/AID/news.php?title=$1 [QSA,L]

残りの作業は、タイトルをニュースにマッピングするためのアルゴリズムを構築することです。これは、書き換えモジュールでは役に立ちません(特に、URLを1つずつ手動で書き換えます)。以下のphpコードを使用できます。

<?php

//write url reflect to news title.
function build_news_url_by_title(){
    $query = "SELECT * FROM news ORDER BY id DESC LIMIT 5";
    $result = mysql_query($query) or die(mysql_error());
    while($row = mysql_fetch_array($result)){
        echo "<a href=\"news/".strtr(substr($row['title'], 0,26), " ", "_")."\">".substr($row['title'], 0,26)."</a>";
    }   
}

function get_news_by_title($title){
    $real_title = strtr($title, "_", " ");
    $query = "SELECT * FROM news WHERE title LIKE %".$real_title."% LIMIT 1";
    return mysql_query($query) or die(mysql_error());
}

$title = $_POST['title'];

$news = get_news_by_title($title);

//some code return the news
...

したがって、URL:

http://localhost/DIRECTORY/AID/news/this_is_article_title

私たちにもニュースを与えることができます。

最後に、上記の手順から、urlと入力すると

http://localhost/DIRECTORY/AID/news/this_is_article_title

ブラウザバーでは、ニュースを提供することもできます。そして、それは愚かなIDについて何の忙しさもありません。上記のコードにはバグがあるかもしれませんが、製品サーバーに配置しないでください。

于 2012-12-05T06:39:18.927 に答える
1

URLのタイトルがありません。それをURLに表示したい場合は、次のようにリンクにも含める必要があります。

<a href="news.php?news_id=$id&title=$url_tile">
于 2012-12-05T08:24:40.373 に答える
1

どこが本当に間違っているのかわからないので、これは複雑な問題のようです。

やりたいことを小さな部分に分けて、それぞれを正しく機能させることをお勧めします。例えば:

 1. Make sure .htaccess file is readable and can do some simple thing, preventing directory indexing for instance.
 2. Make sure you can redirect something with simple html code.
 3. Make sure you can run Felipe's example code successfully. From here you can get good picture of what is going on. 

そして補足として:

次のように書き直すのがより一般的です。

http://localhost/DIRECTORY/AID/news.php?a_id=24 TO -->
http://localhost/DIRECTORY/AID/news/24_this_is_article_title 

ID24がまだ書き換えられたURLに引き継がれていることに注意してください。これにより、パターンマッチングが簡単になり、タイトルの重複の不要な処理が回避されます。

于 2012-12-05T15:02:11.123 に答える
1

リンクを変更します。

echo "<a href=\"news.php?news=$row[id]\"> ". substr($row['title'], 0,26)."</a>

echo "<a href=\"news/$row['title']\">".$row['title']."</a>"

そうすれば、リンクはのnews/$row['title']代わりにになりnews.php?id=...ます。そして今、ページで、それが数字またはDIRECOTORY/AID/news.phpテキストであるかどうかを取得して確認する必要があります。テキストの場合は、と一致させてから、それに応じてページをロードします。id$row['title']

ノート:

  1. これは、$row['title']が他のすべての行で一意であることを前提としています。
  2. タイトルにHTML以外のコンテンツが含まれていない場合は、それらの文字をURLエスケープする必要があります。

タイトルが一意にならない場合は、おそらくそれを実行しnews/{id}/{title}てから書き換えてDIRECTORY/AID/news.php?id={id}&title={title}、タイトルの代わりにIDに基づいて作成する必要があります。

お役に立てば幸いです。

于 2012-12-05T18:44:57.237 に答える
0

コメントできないので答えなければなりません。

すべての答えとあなたの質問を読んで、あなたが何を望んでいるかは明確ではありません。少なくとも私にとっては。たとえば、次のように言います。

http://localhost/DIRECTORY/AID/article.php?a_id=24

http://localhost/DIRECTORY/AID/article/this_is_article_title

しかし、あなたが望まない限り、それは完全には正しくないと思います

http://localhost/DIRECTORY/AID/article.php?a_id=24

ブラウザのアドレスバーに入力されたURLになる場合、リダイレクトの目的は何ですか?最後に、訪問者は、入力したくないものを正確に入力する必要があります。

私の推測では、わかりやすいURLを入力する必要があります。

http://localhost/DIRECTORY/AID/article/this_is_article_title、したがって、質問は逆になります。

http://localhost/DIRECTORY/AID/article/this_is_article_title

http://localhost/DIRECTORY/AID/article.php?a_id=24

次にはっきりしないように見えるのは、ブラウザバーに何が表示されているかです。唯一の答えは次のとおりです。入力されたURL。何も違うことを示すことはできません。

つまり、http:// localhost / DIRECTORY / AID / article / this_is_article_titleをアドレスバーに表示する場合は、それを入力する必要があります。実際のURLであるSUBSTITUTION(http:// localhost / DIRECTORY / AID / article.php?a_id = 24)は表示されず、入力もされません。それがリダイレクトの目的です。

一方、news.phpによって提供されるID番号がarticle/this_is_article_titleのような文字列にどのように変換されるかも明確ではありません。¿これらの文字列はどこにありますか、ID番号はいくつありますか、その変換を実現するためにどのようなアルゴリズムまたは式を使用する必要がありますか、コメントで述べたように、これらのIDのどれが「ルート」であり、どのように識別できますか?これは即興であり、以前のコメントと矛盾しているように見えるため、この点についてさらに詳しく説明する必要があります。

もちろん、私は間違っているかもしれません。私はあなたの質問を手伝おうと思っているだけです。

どうか、天才、この答えに反対票を投じないで、読んでください。私はその質問に答えようとはしていませんし、天才になるにはほど遠いです。

于 2012-11-28T23:58:54.017 に答える
-2

「news.php」の前のスラッシュを忘れたようです。

于 2012-11-26T02:03:07.937 に答える