1

私は、次のような本のタイトルをリストする「きれいなリンク」または「パーマリンク」を扱う問題を解決しようとしています。

http://www.example.com/title/The-Catcher-in-the-Rye/

-単純な単語やスペースなどの通常の本のタイトルを扱う場合は、スペースをダッシュ​​に置き換えるだけで、逆の操作を行うことでデータベース内の本のタイトルを見つけることができるため、問題はありませんstr_replace

'ただし、この例のように、アポストロフィまたはコロン:、あるいはその両方を含む本のタイトルがある場合に問題が発生します。

Why Can't I Be You: A Novel

私のSQLデータベースでは、すべての一重引用符がエスケープされているため、データベースのエントリは次のようになります。

+-----+-------------------------------+
| BID | book_title                    |
+-----+-------------------------------+
|   1 | Why Can\'t I Be You: A Novel  |
+-----+-------------------------------+

すべての本のタイトルをリストするとき、文字列を再度エスケープ解除するので、単純に次のようにリストされます。 Why Can't I Be You: A Novel

私の<a>リンクは、次のようにスペースをダッシュ​​に置き換え、アポストロフィとコロンを省略して作成されたきれいなリンクで、エスケープされていないタイトルを示しています。

<a href="http://www.example.com/title/why-cant-i-be-you-a-novel" title="Why Can't I Be You: A Novel">Why Can't I Be You: A Novel</a>

だから、私の問題に取り掛かる。フォーマットされた(エスケープされていない)本のすべてのタイトルを一覧表示し、ハイフン付きの「パーマリンク」/「きれいなリンク」を機能させて、適切なタイトルをGETメソッドに返すことができるようにしたいと思います。

私の.htaccessエントリには、次のものがありますRewriteRule

RewriteRule ^title/(.*[^/])/?$ viewbook.php?booktitle=$1 [NC,L]

これが行うことは、続く「きれいな」リンク部分を取得し、title/それをGET経由でに送信することviewbook.phpです。したがって、たとえば、The Catcher in the Ryeの場合、GETを介して次のように送信されます。The-Catcher-in-the-Rye

この問題を解決するのはphpで簡単なので、問題はありません。

$booktitle = $_GET['booktitle'];
$goodBookTitle = str_replace('-', ' ', $booktitle);

// or we can do it all at once

$booktitle = str_replace('-', ' ', $_GET['booktitle']);

// Send $booktitle to SQL query and find the book

これは、アポストロフィが見つからない場合は正常に機能しますが、タイトルにアポストロフィまたはコロンが含まれている場合は、データベースに見つからないため、この方法は役に立ちません。また、完全に一致する必要があるWHERE book_title LIKE '%$booktitle%'ため、使用したくありません。viewbook.php

私は、aを介してこれを解決し、たとえばまたはRewriteRuleのためにデータベースにテーブルを追加する必要がない、エレガントまたはシンプルなソリューションを探しています。また、URLにシングルの%27などのアポストロフィを含めたくありません。引用。これは、データ入力がスプレッドシートで行われ、CSVにエクスポートされ、SQLデータベースにアップロードされる大規模なデータベースです。のようなものや同等のものを可能にする個々のエントリのフロントエンドはありません。slugpermalinkslug

私の説明が明確であることを願っています。

4

3 に答える 3

2

まず第一に、エスケープされた文字列をデータベースに格納するという考えは奇妙に見えます。MySQLは任意の文字の文字列を保存でき、バイナリシーケンスを安全に保存することもできます。

次に、実際のタイトルからきれいなURLへのマッピングとその逆について説明します。タイトルをURLに適した文字列に変換してから元に戻すというアイデアは、このような変換を元に戻すのが非常に難しいため、問題を解決する一般的な方法ではありません。この問題を解決する通常の方法は、URLに対応するように変更された本のタイトルを含む別の列をデータベースに含めることです。また、この列の値は一意にする必要があります。テーブルは次のようになります。

+-----+-----------------------------+----------------------------+
| BID | book_title                  | book_title_url             |
+-----+-----------------------------+----------------------------+
|   1 | Why Can't I Be You: A Novel | why-can-t-i-be-you-a-novel |
+-----+-----------------------------+----------------------------+

次のように、スクリプトbook_title内のSQLクエリではなく、この列でテーブルにインデックスを付けて使用する必要があります。viewbook.php

SELECT * FROM books WHERE book_title_url='$booktitle'

SQLインジェクションを防ぐために、経由で受信され、適切にエスケープされた$booktitle本のタイトルが含まれています。$_GET['booktitle']

したがって、きれいなURLは次のようにhttp://www.example.com/title/why-can-t-i-be-you-a-novelなり、Apacheによって。のように書き換えられhttp://www.example.com/viewbook.php?booktitle=why-can-t-i-be-you-a-novelます。

繰り返しますが、これは通常、クリーンURLが実装される一般的な方法です。それがあなたにもうまくいくことを願っています。

既存のレコードの場合book_title_url、次のように列にデータを入力できます。

UPDATE books SET book_title_url=REPLACE(REPLACE(REPLACE(book_title, " ", "-"), ":", "-"), "'", "-");
于 2013-03-16T19:53:55.887 に答える
1

URLによるインデックスを作成することを忘れないでください。そうしないと、動作が遅くなり、SQLインジェクションが必要でない限り、リクエストからの変数をエスケープしてください:)

http://www.whaaa.at/title/1/whatever-fancy-%34name%34-you-likeのように、整数IDをきれいなURLに埋め込むオプションがあれば、これらの問題はすべて克服できます 。 次に、そのIDで検索します

とにかく、本のタイトルは主キーではありません。同じタイトルの本が複数ある可能性があるためです。

于 2013-03-16T20:05:18.607 に答える
1

STD 66によると、コロンとアポストロフィの両方がパスセグメントで有効です。

セグメント=*pchar

pchar = unreserved / pct-encoded / sub-delims / ":" / "@"

sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
           / "*" / "+" / "、" / ";" / "="

したがって、この場合、エンコードされていないURIでそれらを使用できます。

<a href="http://www.example.com/title/why-can't-i-be-you:-a-novel"
   title="Why Can't I Be You: A Novel">Why Can't I Be You: A Novel</a>

ウィキペディアのやり方は次のとおりです。例: http: //en.wikipedia.org/wiki/Breakin'_2 : _Electric_Boogaloo(alas StackOverflowは、ハイパーリンクを作成する際にこれらの文字をエンコードしています)。

本当に使用できない文字は、何らかの方法でエンコードするか(標準化されたアプローチはパーセントエンコードを使用することですが、何らかの理由で受け入れられない場合は、アプリケーション固有の処理を実行できます)、または省略します(たとえば、@MikhailVladimirovの回答で説明されているような2番目の列を検索します)。

于 2013-03-16T20:18:08.730 に答える