Home » Code » How to make vanity URLs using PHP, .htaccess and MySQL

How to make vanity URLs using PHP, .htaccess and MySQL

Posted by on November 16th, 2011

Vanity URL
Vanity URLs have become a staple part of any good online service and are a really good way of helping increase engagement and social sharing of your web app or website. For those of you that don’t know, a vanity URL is usually a direct link to a users profile in the following form – twitter.com/philipbrown.

Here is a quick and easy tutorial for creating vanity URLs for your next project using PHP and .htaccess and an explanation of how those profiles are routed to the correct user in your database using MySQL.

We're going to need a bigger boat

What are we going to need?

Right, to make vanity URLs, you’re going to need the following items in some shape or form.

  • .htaccess
  • profile.php
  • MySQL database

And here is a quick overview of how this process is going to work.

  1. A user will go to your-url.com/username
  2. The .htaccess file will recognise this URL as a vanity URL
  3. The .htaccess file will then pull the profile.php file
  4. The profile.php file will then look up the user based on the URL
  5. The profile.php file will then display the correct user’s profile page

Still with me? Good! Now let’s make what you need.

htaccess

The .htaccess file

Here is the code that you will need to put in your .htaccess file. At this point I should probably explain what an .htaccess file is…

Basically, the .htaccess file in our case is going to be used to detect and redirect URLs. .htaccess files do a lot, much more than the scope of this tutorial, but that’s all you really need to know at the minute. Have a look at The Ultimate Guide to .htaccess files if you want a more detailed explanation of what an .htaccess file is capable of.

So here’s the code you are going to need to put into your .htaccess file. For a full explanation of the mod_rewrite function, click here.

RewriteEngine on
RewriteCond %{REQUEST_FILENAME}.php -f  
RewriteRule ^([^\.]+)$ $1.php [NC]
RewriteCond %{REQUEST_FILENAME} >""
RewriteRule ^([^\.]+)$ profile.php?user=$1 [L]</pre>

And here’s an explanation of what each line does.

RewriteEngine on

Our first line turns on the rewrite engine.

RewriteCond %{REQUEST_FILENAME}.php -f

The line above checks to see if the request is a file

RewriteRule ^([^\.]+)$ $1.php [NC]

This line turns adds the .php extension. So for example if you URL is /friends, the friends.php file would be called.

RewriteCond %{REQUEST_FILENAME} &gt;""
RewriteRule ^([^\.]+)$ profile.php?user=$1 [L]</pre>

The final two lines pick up the url when it is not a file name, for example, your-url.com/philipbrown and routes it to profile.php?user=philipbrown.

Now that we have the URL in the correct form we can use the selected username to pull the right profile information.

profile

The profile.php file

Next we’re going to create the profile.php file. This file will interpret the URL, pick out the name from the URL and find the user that matches that name.

Here is the first bit of code you will need

$getName = explode("/",$_SERVER['REQUEST_URI']);

This returns an array of strings broken up by the “/”.

Next we need to query the database to find the correct user. This step is assuming that you’ve required your user to pick a vanity URL or a username to be used as the vanity URL.

$result = mysql_query("SELECT * FROM user WHERE url='$getName[3]'");	
$num_rows = mysql_num_rows($result);

In the above query, we are simply selecting the user where the URL field matches what was in the URL.

Next we write a little catch to check to make sure a user was found. If people enter your URL then a name that is not a user in your database you will want to send them to your 404 page.

if($num_rows == 0){
  header ("Location: 404");
}

Now that you’ve caught any instances that are not in your database you can use the returned data to populate your profile page.

It’s as simple as that!

And here’s an example of a profile page that is using a vanity URL.
profile-page

If you have an questions, feel free to leave a comment!

Philip Brown

Hey, I'm Philip Brown, a designer and developer from Durham, England. I create websites and web based applications from the ground up. In 2011 I founded a company called Yellow Flag. If you want to find out more about me, you can follow me on Twitter or Google Plus.

Join the Culttt

Become an insider and join the Culttt

  • http://twitter.com/creativenucleus creativenucleus

    Make sure you wrap $getName[3] in a mysql_real_escape_string before you run the query- otherwise you’re opening a way for hackers to inject. A regex check might be a good idea too… Shore those defences!

    • http://phil.ipbrown.com Philip Brown

      Good point! Thank you!

  • Qborreda

    Thanks for the tut, Phillip.
    I had sometimes come to the need of having .htaccess manage several rewrite variables, like a full path, so make some info out of it ..

    Say you would have an url which has something like /state/location/type
    And you would like to connect that to a search to your database, and depending on the different values, you’ll be using a different query .. how would you do that so it would rewrite this on the .htaccess and target .php file?

    Would that only be
    RewriteRule ^([^.]+)$ profile.php?state=$1&location=$2&type=$3 [L] ??

    • http://culttt.com/ Philip Brown

      Hi glad it helped you!

      There are a number of ways you could achieve what I think you’re aiming for. I would perhaps try and accomplish it using only PHP.

      For example,

      $url = $_SERVER['REQUEST_URI'];
      $urlArray = explode(“/”, $url);

      $state = $urlArray[0];
      $location = $urlArray[1];
      $type = $urlArray[2];

      Now you can determine what query you want to run depending on what the url request is.

      Does this help?

  • joe

    hi philip , thanks for the nice tutorial ,
    i have a problem , i did everything you said , and i placed the .htaccess file in the same folder as profile.php , but each time i try to run any php file , i get the same error “Internal Server Error” i dont know what is the problem , but i use localhost:81 , i dont know if this is the problem or what , please help .

    • http://culttt.com/ Philip Brown

      Hi Joe,

      Sounds like you have a problem in your PHP. Check to make sure you’ve included all the ; at the end of each line as it will probably be something small like that.

      Are you using a text editor with highlighting? That should point out where your problem lies.

      • joe

        thanks for your very fast reply,
        well i am using eclipse , and i checked for typos , i tried your code alot of times , but i cant figure out the problem , and i tried other codes they are not working too , could it be the port 81 thing ?

        • http://culttt.com/ Philip Brown

          Ahh I see, sorry I misread your first comment.

          Sounds like you’ve got a problem with a configuration setting. Are you using WAMP or MAMP or something similar? Or are you trying to run it on a server?

          I would do a fresh install of WAMP/MAMP or PHP and Apache.

  • kareem ashraf

    how to secure this code from sql injection

  • Bonnu

    Hi philip,

    I need to ask something about that, and it’s may be the most important part of those kind of redirection. Let’s say I have redirection like http://www.mydomain.com/login
    if user try to have exact same username as “login” how could you handle that request? actually possible solution might be minimum character limitation like minimum 6 chars, but it’s not looking elegant since you loose your chance to use more than 6 chars like “/resetpassword”.

    Probably a “banned words” kind of array control would be a solution but then you need to foresee all kind of possibilities which shouldn’t be used.

    Anyway, if you have any kind of elegant approach to that please let me know :)

    Thanks for the article

    • http://culttt.com/ Philip Brown

      Hi Bonnu

      There is usually many ways to achieve the goal in programming something like this, so the most elegant solution would probably be unique to your code, situation and your website.

      I wouldn’t go down the minimum characters route, because like you said, it’s a bit restrictive and doesn’t really cover all eventualities.

      Having a banned words list is solution because you probably don’t want people to choose the name “login” or “admin” or anything like that.

      You could set rules in htaccess for this to work.

      You could also give precedence to the login page over profile pages.

      There really are many ways you could achieve your goal.

      I would say, find a solution that works. This is the most important thing. Then allow it to evolve as you make it simpler, more elegant or more intuitive to the rest of your website.

      Hope this helps!

      If you want to ask me any specific questions about your code, feel free to ask! :)

    • Mohamad Nasir

      maybe you should define some reserved words

      • http://culttt.com/ Philip Brown

        That’s a great suggestion Mohamad!

  • Codevils

    very helpful. .. thanks Philip Brown

    • http://culttt.com/ Philip Brown

      No problem, glad it helped :)

  • Mohamad Nasir

    this is what im looking for… thx

    • http://culttt.com/ Philip Brown

      That’s great Mohamad!, glad to hear it!

  • Amit

    Hi Philip, instead of using explode GET function works in an efficient way! :)

    • http://culttt.com/ Philip Brown

      Hi Amit, great suggestion! I love how there is always more than one way to solve a problem in programming :) thanks for you suggestion!

  • merci

    This is a good post. I have a question though, say, after a user registers, how will you code it in such a way that his username from the database will be the one used as his vanity url. ex.. user registers with name of myName, then will be directed to his vanity url of http://www.mysite.com/myName

    • http://culttt.com/ Philip Brown

      Hi,

      You would just select which column you want to use in the MySQL statement. So if you wanted to use the user’s username, you would just search for a match on that column.

      • merci

        thanks for the reply.. yeah selecting the username from the database is the easy part, but how do you put it on the url? say $username = ‘mike’. how do you put it http://www.mysite.com/mike... since codeigniter will usually look for a class or function named mike .. it will usually redirect to a 404 error. btw, thank you for helping Philip..

        • http://culttt.com/ Philip Brown

          Ah I see, you are using codeigniter? You will have to set up a wildcard route (http://ellislab.com/codeigniter/user-guide/general/routing.html) which catches anything that doesn’t match a controller and then search for the username. If a username is found, then you call the user controller and pass the username from the url. The the user is not found you would send a 404 response.

          • merci

            thank you so much for the response, yes i’m using codeigniter… Thank you for heading me in the right direction, appreciate it alot!

          • http://culttt.com/ Philip Brown

            No problem, glad I could help. Take a look at Laravel (http://laravel.com/) if you’re just starting out. It’s a really nice, modern PHP framework.

            You’ll also be seeing a lot of Laravel tutorials at Culttt going forward!

  • http://www.krishnatorque.com/ krishnaTORQUE

    Does it work in WAMP server?

    I am getting 500 error.

    only this is working – RewriteRule ^([^/.]+)/?$ /profile.php?user=$1 [L]

    please help. thank you

    • http://culttt.com/ Philip Brown

      Yeah it should do.

      Turn on errors and you will be able to see what’s going wrong, rather than just “500 error”. You have probably just missed off a semi-colon!

      • http://www.krishnatorque.com/ krishnaTORQUE

        how to turn on the error?
        I exactly did what you had write. but still error. :(

        1 more thing is, how to can i make user’s name link I mane – if 2 or more users have same name then there link will be same, so how to verify from server side? when they register?

        • http://culttt.com/ Philip Brown

          In your php.ini file under WAMP, change the value of error_reporting.

          You would need to prevent two people from registering the same name

          • http://www.krishnatorque.com/ krishnaTORQUE

            ; error_reporting
            ; Default Value: E_ALL & ~E_NOTICE
            ; Development Value: E_ALL | E_STRICT
            ; Production Value: E_ALL & ~E_DEPRECATED

            I got this. now what I need to change?

          • http://culttt.com/ Philip Brown

            You need to find where error_reporting is set, and change it to error_reporting = E_ALL

          • http://www.krishnatorque.com/ krishnaTORQUE

            yes, I have found it but I guess I no need to edit it, because it is already like this.

          • http://culttt.com/ Philip Brown

            If it’s not commented out, perhaps you are looking at the wrong php.ini file. There’s often more than one

          • http://www.krishnatorque.com/ krishnaTORQUE

            WAMP > PHP > php.ini
            right?

          • http://culttt.com/ Philip Brown

            Hmm, I’m not sure, I don’t use WAMP. I would probably have a read through the WAMP documentation.

          • http://www.krishnatorque.com/ krishnaTORQUE

            alright. I will check you code after upload my site. thank you man.

  • kay100

    Hi Phil
    How do I get users to input their profile in my website for easy references? Any ideas

    • http://culttt.com/ Philip Brown

      I’m sorry, I’m not sure what you mean?

  • Arsan Gamal

    thanks it helped me alot .. i was asking for another tutorial plz so if i typed http://www.mysite.com/username/info it get the info of the username as it is stored in the database ?? am i clear ?

  • Justinjohn23
  • Justinjohn23

    Heres my Problem

  • Justinjohn23

    I already Solved this problem below Brother..

    My simple question is
    Can i create multiple .htaccess files ? If possible how?
    Do I need to create different folders?
    Thank you so much !

    • http://culttt.com/ Philip Brown

      No you should only have one htaccess file and one point of entry for your application.

      All of your page requests should be routed to the index.php file. You then capture the bit at the end of the request to pull the right page.

      So for example, example.com/about would simply pull the about page. example.com/franz would pull the entry from the database because there would be no franz.php file.

      That is what you are need to do, you don’t need multiple htaccess files.

      If that doesn’t make sense, let me know :)

      • Justinjohn23

        Hi Philipbrown Thanks for answering my question.
        I had a problem with regards of dot (.) in my vanity url
        for example i type on my site mysite/franz.philipp( with dot between inside franz and philipp how can i solve this problem john,

        P.s Thanks Bro

        • http://culttt.com/ Philip Brown

          Hmm, you would have to change the regex to include a dot. I think you would do that by putting a slash in front of the dot because a dot is a special character in regex expressions.

          You are probably better of using a PHP routing package though. This tutorial is pretty old now, I wouldn’t use this technique.

          • Justinjohn23

            do you have any lessons or idea where i can find a better tutorial for same as this? Thanks man for giving a time to answer my question
            You really Good :p

          • http://culttt.com/ Philip Brown

            haha thanks, you should you Slim, it’s really good http://www.slimframework.com/

          • Justinjohn23

            Thanks Man :P

          • http://culttt.com/ Philip Brown

            No problem :)

  • Stephen

    Hello Philiph,

    Thanks for a great tutorial. I however can’t figure out how to make it work for my website http://www.kenyaschoolsdownloads.com A user registers with a username which gets an ID in the database but they choose a NAME to use on their profile page ( This name doesnt go to any database).

    How can I get the links to point to kenyaschoolsdownloads.com/profilename other than to kenyaschoolsdownloads.com/view_profile.php?id=ID Number?

    I can send you the script to look at if that would be ok with you. Thanks

    • http://culttt.com/ Philip Brown

      You would have to store it in the database. There would be no other way really. Why don’t you store the name in the database? How do you persist it between visits?

  • arindambarman

    Why $getName[3]?
    What’s up with [3]

    • http://culttt.com/ Philip Brown

      $getName is an array and you want to get the value at the 3 position.

Supported by