我有一个关于php,mysql,apache的mod_rewrite和友好网址的slug函数的问题。
我有一个mysql表与系列。
此表具有auto_increment ID和unique_key字符串,该字符串是系列的名称。
我想做的是:
用户可以写一些类似
series/name-of-a-serie的东西(因为在这种情况下我更喜欢使用唯一的字符串而不是ID),我会得到像
series.php?serieName=name-of-a-serie这样的名字,但是我的名字是数据库是
"name of a serie"
"this - name",因为如果我恢复这个过程,我会得到
"this name"而那个' s不是原来的名字 有什么想法吗?
答案 0 :(得分:2)
您可以随时在数据库中使用第二列来存储系列名称的已清理版本,例如删除所有特殊字符,用短划线替换空格等等。
使用该链接时,您只需检查数据库中的准备文本并获取真实条目。
据我所知,wordpress的确如此。他们存储一个友好的url post_name与您可以使用的每个帖子。 通过脚本(通过.htaccess)传递所有URL,他们可以检查所有这些变体并显示相应的页面。
有关详细信息,请参阅How to rewrite urls in wordpress。
清理标题的一些代码可能是:
// Define all the characters you want to get rid of / replace
$arrBadChars = array('Ä', 'Ö', 'Ü', 'ä', 'ö', 'ü', 'ß', ' ', '_', '~', '-/', chr(10), chr(13));
// define the corresponding characters/texts for the above ones
$arrGoodChars = array ('ae', 'oe', 'ue', 'ae', 'oe', 'ue', 'ss', '-', '', '/', '', '','');
// Replace the bad with the good ones
$strNewTitle = str_replace($arrBadChars, $arrGoodChars, html_entity_decode($strTitle));
// simply paranoia, to remove everything else you might not have thought of above...
$strNewTitle = preg_replace('#[^[:space:]~a-zA-Z0-9_-]#', '', $strNewTitle);
$strNewTitle
是您可以保存并用于您的网址的。{/ p>
答案 1 :(得分:0)
如果你确定你没有 - 在数据库标题中,只需这样做:
$id=str_replace("-"," ",$_GET['id']);
$stm=$db->prepare("SELECT * FROM movie WHERE movie_title=:movie");
$result=$stm->execute(array(":movie"=>$id))->fetchAll();
您还可以使用任何其他替换字符,例如网址中的_。
这样您就可以保留友好的URL,还可以维护您的数据库标题。我有时看到的另一种方法是创建一个存储URL的第二个数据库字段。
答案 2 :(得分:0)
此问题的解决方案是在URL中使用数字标识符。你说这个表已经用这种方式实现了,所以很容易做到。基本概念是从url中提取数字id,然后验证slug是否等于数据库中的slug。如果没有,则重定向到正确的(301)。这是我认识的最流行的模式。
您的网址将如下所示:
http://example.com/12345/name-of-a-serie
但是你得到的ID取决于你,但是mod_rewrite会起作用。
$id = $_GET['id'];
$slug = $_GET['slug'];
// verify the id
$record = getRecord($id);
if(! $record) exit;
if($record->slug != $slug) {
$slug = $record->slug;
// these values are NOT arbitary, because we have validated the record
// against the arbitrary ID first, so we're safe. as long as your
// internal API is using prepared statements.
header("Location: /$id/$slug");
exit;
}
答案 3 :(得分:0)
如果你想从一个带有弹性的弦回复到原始弦,你必须确保击穿功能是双射的,然后写反向功能。
BTW,段塞函数不能是双射的,因为它们将扩展的字符集(您的一种语言)映射到受限制的字符集(在URL中使用的字符集)。希望,如果slug在表中有一个UNIQUE约束,你可以在PHP代码中使用它作为检索项目的键,从而命名它。
答案 4 :(得分:0)
非常感谢。
我现在知道我能做些什么。
每当我在DB中插入一个新的tittle时,我会检查原始名称
如果已有条目,则表示此影片已在DB中,
如果没有,我会插入原始的tittle和被撞的那个。
如果“A serie”和“A-serie”是一个完全不同的系列,但是那个被砸的tittle是相同的
"A serie" -> "A-serie"
"A-serie" -> "A-serie"
然后我只需要改变那些被砸的小东西,例如:
ID | original name | slugged name
----------------------------------------------
201 | A name | a-name
----------------------------------------------
202 | A-name | a-name1
用户将在URL中写入的名称是slugged。
URL将类似于:
series/a-serie
series/a-serie1