Php 漂亮链接中的撇号和冒号

Php 漂亮链接中的撇号和冒号,php,mysql,apache,.htaccess,mod-rewrite,Php,Mysql,Apache,.htaccess,Mod Rewrite,我希望解决一个有关列出书名的“漂亮链接”或“永久链接”的问题,例如: http://www.example.com/title/The-Catcher-in-the-Rye/ 当我处理常规书名时,例如有简单的单词或空格,没有问题,因为我可以简单地用破折号替换空格-,并通过执行反向stru\u replace在数据库中查找书名 但是,当我的书名中有撇号,或冒号:或两者都有时,问题就出现了,如本例所示: Why Can't I Be You: A Novel 在我的sql数据库中,所有单引号都被

我希望解决一个有关列出书名的“漂亮链接”或“永久链接”的问题,例如:

http://www.example.com/title/The-Catcher-in-the-Rye/
当我处理常规书名时,例如有简单的单词或空格,没有问题,因为我可以简单地用破折号替换空格
-
,并通过执行反向
stru\u replace
在数据库中查找书名

但是,当我的书名中有撇号
或冒号
或两者都有时,问题就出现了,如本例所示:

Why Can't I Be You: A Novel
在我的sql数据库中,所有单引号都被转义,因此数据库中的条目如下所示:

+-----+-------------------------------+
| BID | book_title                    |
+-----+-------------------------------+
|   1 | Why Can\'t I Be You: A Novel  |
+-----+-------------------------------+
<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>
当我列出所有书名时,我再次取消了字符串,因此它只列出如下内容:
为什么我不能成为你:一本小说

My
链接显示了未加修饰的标题,通过用破折号替换空格并省略撇号和冒号创建了漂亮的链接,如下所示:

+-----+-------------------------------+
| BID | book_title                    |
+-----+-------------------------------+
|   1 | Why Can\'t I Be You: A Novel  |
+-----+-------------------------------+
<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>
这样做的目的是获取
title/
后面的“pretty”链接部分,并通过GET发送到
viewbook.php
。例如,对于《麦田里的守望者》一书,以下内容通过GET发送:
麦田里的守望者

没有问题,因为在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
如果找不到撇号,这种方法可以很好地工作,但是,如果标题包含撇号或冒号,则这种方法没有帮助,因为它不会在数据库中找到。我也不想使用像“%$booktitle%”这样的
WHERE book\u标题
,因为
viewbook.php
必须完全匹配

我正在寻找一个优雅或简单的解决方案,它将使我能够通过
重写规则
解决这个问题,而不必向数据库中添加额外的表,例如
slug
permalink
,并且我不希望url中有撇号,例如%27表示单引号。这是一个大型数据库,数据输入在电子表格中完成,导出为CSV并上载到SQL数据库。对于单个条目,没有前端来支持诸如
slug
或类似的内容


我希望我的解释清楚。

首先,在数据库中存储转义字符串的想法看起来很奇怪。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 |
+-----+-----------------------------+----------------------------+
SELECT * FROM books WHERE book_title_url='$booktitle'
UPDATE books SET book_title_url=REPLACE(REPLACE(REPLACE(book_title, " ", "-"), ":", "-"), "'", "-");
您应该按此列索引表,并在
viewbook.php
脚本中使用它,而不是SQL查询中的
book\u title
,如下所示:

+-----+-----------------------------+----------------------------+
| BID | book_title                  | book_title_url             |
+-----+-----------------------------+----------------------------+
|   1 | Why Can't I Be You: A Novel | why-can-t-i-be-you-a-novel |
+-----+-----------------------------+----------------------------+
SELECT * FROM books WHERE book_title_url='$booktitle'
UPDATE books SET book_title_url=REPLACE(REPLACE(REPLACE(book_title, " ", "-"), ":", "-"), "'", "-");
其中
$booktitle
包含通过
$\u GET['booktitle']
接收的图书标题,并正确转义以防止SQL注入

因此,您漂亮的URL看起来像
http://www.example.com/title/why-can-t-i-be-you-a-novel
它们将被Apache重写为类似于
http://www.example.com/viewbook.php?booktitle=why-你可以写一本小说吗

同样,这是实现漂亮URL的常见方式。希望它也能对你有用

对于现有记录,您可以通过以下方式填充
book\u title\u url
列:

+-----+-----------------------------+----------------------------+
| BID | book_title                  | book_title_url             |
+-----+-----------------------------+----------------------------+
|   1 | Why Can't I Be You: A Novel | why-can-t-i-be-you-a-novel |
+-----+-----------------------------+----------------------------+
SELECT * FROM books WHERE book_title_url='$booktitle'
UPDATE books SET book_title_url=REPLACE(REPLACE(REPLACE(book_title, " ", "-"), ":", "-"), "'", "-");

首先,在数据库中存储转义字符串的想法看起来很奇怪。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 |
+-----+-----------------------------+----------------------------+
SELECT * FROM books WHERE book_title_url='$booktitle'
UPDATE books SET book_title_url=REPLACE(REPLACE(REPLACE(book_title, " ", "-"), ":", "-"), "'", "-");
您应该按此列索引表,并在
viewbook.php
脚本中使用它,而不是SQL查询中的
book\u title
,如下所示:

+-----+-----------------------------+----------------------------+
| BID | book_title                  | book_title_url             |
+-----+-----------------------------+----------------------------+
|   1 | Why Can't I Be You: A Novel | why-can-t-i-be-you-a-novel |
+-----+-----------------------------+----------------------------+
SELECT * FROM books WHERE book_title_url='$booktitle'
UPDATE books SET book_title_url=REPLACE(REPLACE(REPLACE(book_title, " ", "-"), ":", "-"), "'", "-");
其中
$booktitle
包含通过
$\u GET['booktitle']
接收的图书标题,并正确转义以防止SQL注入

因此,您漂亮的URL看起来像
http://www.example.com/title/why-can-t-i-be-you-a-novel
它们将被Apache重写为类似于
http://www.example.com/viewbook.php?booktitle=why-你可以写一本小说吗

同样,这是实现漂亮URL的常见方式。希望它也能对你有用

对于现有记录,您可以通过以下方式填充
book\u title\u url
列:

+-----+-----------------------------+----------------------------+
| BID | book_title                  | book_title_url             |
+-----+-----------------------------+----------------------------+
|   1 | Why Can't I Be You: A Novel | why-can-t-i-be-you-a-novel |
+-----+-----------------------------+----------------------------+
SELECT * FROM books WHERE book_title_url='$booktitle'
UPDATE books SET book_title_url=REPLACE(REPLACE(REPLACE(book_title, " ", "-"), ":", "-"), "'", "-");

别忘了按url建立索引,否则它会很慢,请转义来自请求的变量,除非您需要SQL注入:)

如果您可以选择在漂亮的URL中嵌入整数id,那么所有这些问题都可以克服,如下所示: 然后按该id进行查找


无论如何,书名不是主键,因为可能有几本书名相同。

别忘了按url建立索引,否则它会很慢,除非需要SQL注入,否则请转义来自请求的变量:)

如果您可以选择在漂亮的URL中嵌入整数id,那么所有这些问题都可以克服,如下所示: 然后按该id进行查找

无论如何,书名不是主键,因为可以有多本书名相同。

根据,冒号和撇号在路径段中都有效:

segment = *pchar pchar = unreserved / pct-encoded / sub-delims / ":" / "@" sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "=" 段=*pchar pchar=未保留的/pct编码的/sub-delims/”:“/”@