
Pretty URLs are good to have. People like pretty. There are various ways to accomplish this, but I will go over a simple way that I’ve personally never heard before. That means I invented it, even though many other people have already invented it, but never told me.
The easiest and ugliest ways to have your URLs is to pass GET variables to pages, so they come out something like index.php?var1=xx&var2=yy. Having question marks, equal operators and & signs is a dead giveaway to search engines that you are passing variables and that the page will probably change a lot, and it might not be worth it to bookmark.
The most difficult (because I haven’t gotten my head around it yet, you can call it “professional”) way is to use a framework such as cakePHP. CakePHP still passes variables and even operations and functions in the URL, but hides them in the URL. In this case you could end up with something like index.php/add/post/new/ or index.php/view/posts/123. This is probably a very good method because I’ve heard professionals tell me that it is, but I like my way (and I’m kind of proud of thinking it up).
My way can be done quite cleverly if you put your mind to it and it’s not very difficult. You make files and directories! I haven’t had the time to redo my entire webpage, but I know now how to make it so that I can have a URL like ralphvandenberg.com/ramblings/title_of_the_rambling. I can take the title of the post that I or one of my users submit, turn it all to lowercase, and exchange the spaces for underscores. This is all simple PHP; ask me if you need help with this. Next you create the folder (mkdir()) using the name that you’ve made safe, and store that URL in the database. In that folder you have PHP create an index.php file for you, using the simple open file (w), and you put as content of that new index file the ID to the post, and an include call to a masterfile that uses the ID to call the information out of the database.
Now when you want to link to them, you just use the URL that you’ve stored in the database. You can omit /index.php, just call the folder. I haven’t tested this on a live site yet, there might be some permissions that you have to change, but I think this is a pretty good way to get pretty URLs. Try it out!
Ralph van den Berg
RalphvandenBerg.com
Comments
Part 2 of this story is out
I've decided to take most of the information from the comments here and create a follow up story. Check it out:
Pretty URLs (How to) part 2
---Ralph van den Berg
visit RalphvandenBerg.com
Dynamically Static!
Nice post! And an innovative solution...
Your approach is dynamically creating static pages - rather than delivering the page from the database when its requested, you create the page from the start - so do you need the database anymore?
My concern with the approach would be security. As you are essentially letting me create directories and files on your webserver, I could write some malicious script. I would have to play around with it to be sure (or perhaps one of our other readers has an idea?). If you try it on a live server, I suspect you might run into troubles with PHP Safe Mode - as I understand it only 'root' would have write permissions to the mkdir() created directory.
Anyone else?
Chiang Mai Plan
Thai Tan Thai
Laos Plan
In development
This idea is still in development, but I believe it has great potential. The reason for still keeping the database is so that you can keep changing and updating information. Remember, the new page only keeps the id and an include to a master file.
// create the safe url
// This needs more error catching for weird symbols
$url = strtolower($newrambling); // make lowercase
$url = str_replace(' ','_',$url); // put underscores instead of spaces
mkdir($url) or die ("Could not make directory"); // make the directory
// somewhere here, or earlier, you store the url in the database, along with more information about the rambling
$index = $url . '/index.php'; // $url is the safe name of your new url
$fh = fopen($index, 'w') or die("file couldn't be opened");
$content = "<?php \$ramblings_id = " . $ramblingsid . "; include('../masterfiles/ramblings.php'); ?>"; // content of index.php
fwrite($fh, $content);
fclose($fh); // close the file
In the masterfile you make the call to the database based on the $ramblings_id and you get all the contents. This way you can change the look and style of all the generated pages without having to rewrite anything.
I would still love to hear more developments and implementations from anybody who has tried this before or is trying it now.
---Ralph van den Berg
visit RalphvandenBerg.com
Good idea, wrong way!
From what i understood security is not a problem, because not the complete content is written to the file, but just the id, reffering to the database...
"using the simple open file (w), and you put as content of that new index file the ID to the post"
So, there would be no danger, because you can't corrupt the files content. But it's a total waste to create directories and files for every entry just to store the id in it. Think about huge blogs with 1xxxxxx entries...
Your approach would work, but that's not the way to go. Plus the files and directories are static which is more unflexible, if you want to change anything.
If you want to achieve an url like that "ralphvandenberg.com/ramblings/title_of_the_rambling" - without having the id in the url - the elegant way is using the last part "title_of_the_rambling" as an unique identifier.
But watch out, it has to be unique. So what to do?
- add a new field to your blog entry table, i.e "identifier varchar 255"
- set an unique index to that field
So before storing an identifier, you make sure, it doesnt exist yet and if so, use an offset to make it unique, like:
title_of_the_rambling
title_of_the_rambling-2
title_of_the_rambling-3
If someone enters "ralphvandenberg.com/ramblings/title_of_the_rambling" and because this directory structure does not exist, you have to use apache's mod rewrite to actually call another file, which will use the identifier to get the right information from the db.
So internally (not visible to your visitor or search engines ;-) your webserver will call a request like the following:
ralphvandenberg.com/ramblings/get_db_entry.php?identifier=title_of_the_rambling
In get_db_entry.php you do your sql stuff and print out the result. Thats it.
Check out:
http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html
http://www.webforgers.net/mod-rewrite/mod-rewrite-syntax.php (this one is easier to understand)
Try to do the mod rewrite by yourself... It's only ONE line of code...
Sven
I like it
Yeah, I've followed your links, and I like what I'm reading. I'm now thinking that I'll do both. For the sake of organization, I would still like to "dynamically" create a few folders, but after that, the mod rewrites are not out of the question. Thanks for the tip, Sven!
---Ralph van den Berg
visit RalphvandenBerg.com
the mod rewrite emulates the
the mod rewrite emulates the directories... so there is no need to create them, at all. this would be just a waste of space and an overhead in your code.
another point is your way of creating url safe directories:
"$url = str_replace(' ','_',$url); // put underscores instead of spaces"
removing the whitespaces wont be enough... what about all other special characters?
an easy example would be someone writing a thai headline... this would already break your code.
the perm url has to be encoding safe - also for the mod rewrite version.
you could use preg_replace instead:
http://th.php.net/preg_replace
preg_replace("/[^a-z0-9_-]+/i","_",$yourstring);
replaces everything with an understore, besides of the characters, defined within the square brackets.
How about multilevel directories?
Will this work for multiple levels of "fake" directories?
For example: ralphvandenberg.com/var1/var2/var3
Returning: ralphvandenberg.com/index.php?variable1=var1&variable2=var2&variable3=var3
---Ralph van den Berg
visit RalphvandenBerg.com
sure...
that wont be a problem.
Apache's mod rewrite works with regular expressions. It's up to you how you define your pattern.
Off course you could have multiple directories.
But keep it simple, thats the reason of pretty urls, right?
If you need several variables/ identifiers:
"ralphvandenberg.com/var1/var2/var3"
better for seo matters would be:
"ralphvandenberg.com/var1_var2_var3"
but for your example with the blog something like:
ralphvandenberg.com/entry_identifier.html
would do the trick already...