PHP中的URL友好用户名?

28

在我的PHP网站上,目前用户使用邮箱地址和密码登录。我想添加一个用户名,这个用户名将是唯一的且他们无法更改。我想知道如何让这个名字没有空格,并且可以在URL中使用,以便我可以使用该用户名链接到他们的个人资料和其他内容。如果用户名中有空格,则应该添加一个下划线jason_davis。我不确定最好的方法是什么?

在我的 PHP 网站上,当前用户使用电子邮件地址和密码登录。我想要添加一个用户名,这个用户名将是唯一的且他们无法更改。我想知道如何使用户名中不包含空格,并且能够在 URL 中使用。这样我就可以通过用户名链接到他们的个人资料和其他东西。如果用户名中包含空格,它将被替换为下划线 jason_davis。我不确定最好的实现方式是什么?

2
有很多类似的问题。你没有搜索到答案吗? - Gumbo
@Gumbo 我在 Stack Overflow 上搜索了,而不是 Google。可能没有使用正确的术语,但我搜索了“URL 友好的用户名”,结果不太理想。在这之前我不知道它被称为 slug。 - JasonDavis
1
也许并不是每个人都在尝试转换用户名。但搜索“URL友好字符串”会返回可用的结果。 - Gumbo
类似:https://dev59.com/dW435IYBdhLWcg3woRnG - GG.
现在,您可以使用类库如 https://github.com/cocur/slugify 或 https://github.com/ausi/slug-generator 来实现这一点。 - ausi
2个回答

103
function Slug($string)
{
    // convert to entities
    $string = htmlentities( $string, ENT_QUOTES, 'UTF-8' );
    // regex to convert accented chars into their closest a-z ASCII equivelent
    $string = preg_replace( '~&([a-z]{1,2})(?:acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);~i', '$1', $string );
    // convert back from entities
    $string = html_entity_decode( $string, ENT_QUOTES, 'UTF-8' );
    // any straggling caracters that are not strict alphanumeric are replaced with a dash
    $string = preg_replace( '~[^0-9a-z]+~i', '-', $string );
    // trim / cleanup / all lowercase
    $string = trim( $string, '-' );
    $string = strtolower( $string );
    return $string;
}

$user = 'Alix Axel';
echo Slug($user); // alix-axel

$user = 'Álix Ãxel';
echo Slug($user); // alix-axel

$user = 'Álix----_Ãxel!?!?';
echo Slug($user); // alix-axel

9
这很危险!多个独特的用户名可以映射到相同的URL。这不是你想要的,对吧?比如说,ABab是独特的字符串,但映射到相同的slug字符串。你应该将slug作为标识符存储。 - John Feminella
12
在存储短链接之前,他显然需要检查是否存在重复内容。 - Pekka
1
这个函数不会将波兰字符"ąćęłńóśźż"转换为"acelnoszz",因为它们在 HTML 实体中没有名称(只有数值表示)。 您仍然需要使用表格替换它们。 在函数中的“return”之前粘贴以下代码:$string = strtr(mb_strtolower($string), array('ą'=>'a','ć'=>'c','ę'=>'e','ł'=>'l','ń'=>'n','ó'=>'o','ś'=>'s','ź'=>'z','ż'=>'z')); - s3m3n
1
经过更多的测试,正如某人之前所写的那样,iconv解决了问题。setlocale(LC_ALL, "en_US.utf8"); $string = iconv("UTF-8", "ascii//TRANSLIT", '>ĄĘŁŹÓżół<'); 这段代码让我得到了 >AELZOzol< 的结果。 - s3m3n
3
这是Slug()函数的codepad演示,其中还包括一个完全相同但空格更多的nSlug()函数(适用于视力受损者):http://codepad.org/rJNSQmGJ - Jared Farrish
显示剩余11条评论

3
换句话说,你需要创建一个用户名缩略。Doctrine(用于PHP的ORM)有一个很好的函数可以实现这一点。Doctrine_Inflector::urlize() 编辑:还应该在数据库中保留用户名缩略作为唯一键列。然后每个搜索操作都应该基于该列进行,而不是原始的用户名。

损坏的链接...现在可以在这里找到:https://github.com/doctrine/inflector/blob/2.0.x/lib/Doctrine/Inflector/Inflector.php - squarecandy
值得注意的是,这种方法采用“保持所有要替换字符的全面列表”的方式,比被接受答案的方法更难维护。 - squarecandy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接