URL Friendly Username in PHP?

21,457

Solution 1

function Slug($string)
{
    return strtolower(trim(preg_replace('~[^0-9a-z]+~i', '-', html_entity_decode(preg_replace('~&([a-z]{1,2})(?:acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);~i', '$1', htmlentities($string, ENT_QUOTES, 'UTF-8')), ENT_QUOTES, 'UTF-8')), '-'));
}

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

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

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

Solution 2

In other words... you need to create a username slug. Doctrine (ORM for PHP) has a nice function to do it. Doctrine_Inflector::urlize()

EDIT: You should also keep username slug in database, as a Unique Key column. Then every search operation should be done based on that column, not original username.

Share:
21,457

Related videos on Youtube

JasonDavis
Author by

JasonDavis

PHP/MySQL is my flavor of choice however more recently JavaScript is really becoming something I enjoy developing with! Writing code since 2000' Currently working heavily with SugarCRM + Launching my Web Dev company ApolloWebStudio.com "Premature optimization is not the root of all evil, lack of proper planning is the root of all evil." Twitter: @JasonDavisFL Work: Apollo Web Studio - https://www.apollowebstudio.com Some of my Web Dev skills, self rated... +------------+--------+------+--------------+ | Skill | Expert | Good | Intermediate | +------------+--------+------+--------------+ | PHP | X | | | +------------+--------+------+--------------+ | MySQL | X | | | +------------+--------+------+--------------+ | Javascript | X | | +------------+--------+------+--------------+ | jQuery | X | | +------------+--------+------+--------------+ | CSS+CSS3 | X | | +------------+--------+------+--------------+ | HTML+HTML5 | X | | | +------------+--------+------+--------------+ | Photoshop | | X | | +------------+--------+------+--------------+ | Web Dev | X | | | +------------+--------+------+--------------+ | SugarCRM | X | | | +------------+--------+------+--------------+ | Magento | | X | | +------------+--------+------+--------------+ | WordPress | X | | | +------------+--------+------+--------------+ | SEO | X | | | +------------+--------+------+--------------+ | Marketing | X | | | +------------+--------+------+--------------+ |Social Media| X | | | +------------+--------+------+--------------+

Updated on July 09, 2022

Comments

  • JasonDavis
    JasonDavis almost 2 years

    On my PHP site, currently users login with an email address and a password. I would like to add a username as well, this username they g\set will be unique and they cannot change it. I am wondering how I can make this name have no spaces in it and work in a URL so I can use there username to link to there profiles and other stuff. If there is a space in there username then it should add an underscore jason_davis. I am not sure the best way to do this?

    • Gumbo
      Gumbo over 14 years
      There are plenty questions like this. Didn’t you get an answer with searching?
    • JasonDavis
      JasonDavis over 14 years
      @Gumbo I searched SO, not google. Possibly not the correct term but I did search for "URL friendly username" with not much luck. I didn't know it was called a slug before this.
    • Gumbo
      Gumbo over 14 years
      Maybe not everyone is trying to convert usernames. But searching for “URL friendly string” is returning usable results.
    • GG.
      GG. over 12 years
    • ausi
      ausi over 6 years
      Nowadays, you can use libraries like github.com/cocur/slugify or github.com/ausi/slug-generator to achieve that.
  • John Feminella
    John Feminella over 14 years
    This is dangerous! Multiple unique user names can map to the same URL. That's not what you want, is it? Consider, e.g., AB and ab, which are unique strings but map to the same slug string. You should store the slug as the identifier.
  • Pekka
    Pekka over 14 years
    @John Feminella: He would obviously have to check for duplicates at some point before storing the slug.
  • JasonDavis
    JasonDavis over 14 years
    perfect, thank you. BTW what does this part look for acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml ?
  • Pekka
    Pekka over 14 years
    @jasondavis: För stüff lıkë thîs!
  • Alix Axel
    Alix Axel over 14 years
    @Pekka: Thanks! =) @jasondavid: It removes accents, instead of having a huge lookup table we convert to html entities and fetch the unaccented char.
  • Frank Farmer
    Frank Farmer over 14 years
    As a slight improvement, using iconv() to convert to ASCII//TRANSLIT would probably catch a lot more chars.
  • Alix Axel
    Alix Axel over 14 years
    @Frank Farmer: iconv('UTF-8', 'ASCII//TRANSLIT', 'Álix Ãxel') returns 'Alix ~Axel. Using PHP 5.3.0 and .php file encoded as UTF-8 no BOM.
  • John Conde
    John Conde over 14 years
    Anyone know why Á and à would cause no output or error to occur when using this function?
  • John Conde
    John Conde over 14 years
    I'll answer my own question: remove the "'UTF-8'" parameter from htmlentities. That did the trick.
  • Alix Axel
    Alix Axel over 14 years
    @John Conde: I though you're talking about the iconv() function! You shouldn't remove the UTF-8 from htmlentities, instead you should save all your .php files encoded as UTF-8 no BOM.
  • John Conde
    John Conde over 14 years
    Alex, thanks for the info. I reutnred the "UTF-8" parameter and saved the file as UTF-8 and it worked like a charm.
  • Alix Axel
    Alix Axel over 14 years
    @John Conde: No problem! ;) You should always save your files UTF-8 encoded.
  • s3m3n
    s3m3n almost 12 years
    This function does not convert Polish chars "ąćęłńóśźż" => "acelnoszz", because they have no names in html entities (only numeric representation). You still need to replace those with table. Paste below code before return in function: $string = strtr(mb_strtolower($string), array('ą'=>'a','ć'=>'c','ę'=>'e','ł'=>'l','ń'=>'n','ó'=>'o',‌​'ś'=>'s','ź'=>'z','ż‌​'=>'z'));
  • Alix Axel
    Alix Axel almost 12 years
    @s3men: Indeed, not only Polish characters but others as well (Chinese, Japanese, Turkish, Arabic, ...).
  • s3m3n
    s3m3n almost 12 years
    After few more tests iconv made the trick, as someone wrote above. setlocale(LC_ALL, "en_US.utf8"); $string = iconv("UTF-8", "ascii//TRANSLIT", '>ĄĘŁŹÓżół<'); gives me >AELZOzol<
  • Jared Farrish
    Jared Farrish over 11 years
    codepad demo of the Slug() function, with a second identical but spaced out nSlug() function (for the eyeball impaired): codepad.org/rJNSQmGJ