5

How can I make www.mydomain.com/folder/?id=123 ---> www.mydomain.com/folder/xCkLbgGge

I want my DB query page to get it's own URL, like I've seen on twitter etc etc.

user1121487
  • 2,662
  • 8
  • 42
  • 63

3 Answers3

7

This is known as a "slug" wordpress made this term popular. Anyway though.

Ultimately what you need to do is have an .htaccess file that catches all your incoming traffic then reforms it at the server level to work with your PHP in the sense, you will still keep the ?id=123 logic intact, but to the client side '/folder/FHJKD/' will be the viewable result.

here is an example of an .htaccess file I use a similar logic on.. (so does wordpress for that matter).

RewriteEngine On
#strips the www out of the domain if there
RewriteCond %{HTTP_HOST} ^www\.domain\.com$

#applies logic that changes the domain from http://mydomain.com/post/my-article
#to resemble http://mydomain.com/?id=post/my-article
RewriteRule ^(.*)$ http://domain.com/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?id=$1 [QSA,L]

what this will do is take everything after domain.com/ and pass it as a variable to index.php the variable in this example would be 'id' from this you have to device a logic that best suits your sites needs.

example

<?php
 //the URL for the example here: http://mydomain.com/?id=post/my-article
 if($_GET['id'])
 {
   $myParams = explode('/', $_GET['id']);
   echo '<pre>';
   print_r($myParams);
   echo '</pre>';
 }
?>

now the logic for this would have to go much deeper, this is only pure example at a basic level, but overall and especially cause your working with a database I assume, your gonna wanna make sure the $myParams is clean of malicious code, that can inject into your PHP or Database.

The output of the above $myParams via print_r() would be:

Array(
   [0] => post
   [1] => my-article
)

To work with it you would need to do at the very least

echo $myParams[0].'<br />';

or you could do it like this cause most browsers will add a final /

<?php
 //the URL for the example here: http://mydomain.com/?id=post/my-article
 if($_GET['id'])
 {
   //breaks the variable apart, removes any empty array values and reorders the index
   $myParams = array_values(array_filter(explode('/', $_GET['id'])));
   if(count($myParams > 1)
   {
       $sql = "SELECT * FROM post_table WHERE slug = '".mysql_real_escape_string($myParams[1])."'";
       $result = mysql_query($sql);
   }

 }
?>

Now this admitedly is a very crude example, you would want to work some logic in there to prevent mysql injection, and then you will apply the query like you would how you are now in pulling your articles out using just id=123.

Alternatively you could also go a completely different route, and explore the wonders of MVC (Model View Control). Something like CodeIgniter is a nice easy MVC framework to get started on. But thats up to you.

chris
  • 36,115
  • 52
  • 143
  • 252
  • This seem very complicated to get it to work. I need to use it on pages that will be added to the database by users. Is there any working example for this technique? - the only ones I came across describing this, requires changes in the apache server settings. – user1121487 Jun 14 '12 at 17:18
  • Its a little complicated yes, but.. its pretty much the only way to achieve what you want. You need to have the htaccess the way I mentioned, then based on that every incoming request will go through your index.php anything trailing after .com/ will be treated as a variable very similar to a $_GET parameter ie: .com/?id=123. With that you basically build your site the same way you normally would same logic applies to getting the data from the database as it did before you just have to work with the get varaiable a little differently in the initial loading – chris Jun 14 '12 at 17:50
  • unfortunately all around there is no one example after that of which is shown as everyone litterally has a different need. In my example I turn the ID varible into an array using explode so `$myParams[0]` would be your jumping point. Now most people will add an additional column to there database tables at the very least this way they can conform what they have to this concept easily without changing to much. Now this one column would be the slug .com/my-article part in your URL the column would store "my-article" you'd look for that and work with it like you would any other DB pull – chris Jun 14 '12 at 17:53
  • I updated my original post to expand on what I am talking about. However like I said unfortunately because all needs are different, there is no one distinct example to use after what seems like little logic to work with. All in all the only way to achieve that of which you want is to start with the initial htaccess patching that overwrites apaches core behavior for your need, then in doing that everything there after depends on what you do with the PHP or server side scripting language of choice. Your more than welcome to reach out to me if you like and maybe we can get you sorted out. – chris Jun 14 '12 at 18:14
  • Thank you very much! I'll try to get into this, there are still lots of question marks though. I'll start with the basic first and try to grasp this concept. The only alternative solution I can think of is to write a script that's creating an index.php file with the db-code as an include, and put it in a folder with a randomized name. Not as neat though. – user1121487 Jun 14 '12 at 18:39
  • not to mention likely to cause whats known as a bash, eventually random runs out. If your looking to create unique id's like HFhjdkfnva then you can use something like http://kevin.vanzonneveld.net/techblog/article/create_short_ids_with_php_like_youtube_or_tinyurl/ which is something I use from time to time for the same thing – chris Jun 14 '12 at 18:48
  • but also overall best to work with a DB. In the long run having dozens or more folders with all the same stuff and an index.php for the DB stuff will come round and bite you in the ... – chris Jun 14 '12 at 18:50
  • I think I just got the basics to work ! :) I'm a little happy now! How about using the int post_id from the DB as the actual url name? This way the DB could locate the post faster. – user1121487 Jun 14 '12 at 19:13
  • wouldn't make a difference, you'd still have to catch the variable, break it down as needed, then pass it to an sql query, assuming thats that your doing, and you don't want your queries to be based on user input which working with URLs this way it is, its acceptable in a where clause or like clause or similar but using it as the identifier for the column in your table is just a bad idea. – chris Jun 14 '12 at 19:29
3

This can be achieved with mod_rewrite e.g. via the .htaccess file.

Whymarrh
  • 13,139
  • 14
  • 57
  • 108
Valerij
  • 27,090
  • 1
  • 26
  • 42
1

In your .htacess, you need add RewriteEngine on.

After that, you will need to do some regexs to make this little beast work. I'm assuming ?id is folder.php?id=123.

For example the folder piece: RewriteRule ^folder/([a-zA-Z0-9_-]+)/([0-9]+).html$ folder.php?id=$123

Telshin
  • 340
  • 1
  • 5