PHP: How to generate URLs in your webapps
Sunday, October 31st, 2010With SEO becoming more and important, it is critical that you produce the exact same URL from the same piece of content everywhere. Furthermore, the URL structure is often decided upon only after you’ve started development. Our experiences from the last few years have led me to believe that the ultimate method for generating the proper URLs time and time again is to use a separate function for each different URL in th following pattern:
function my_url($data_object, $context=array()){
return root_url(
"my_url_page/".$context['category']['name']
."/".$data_object['seo_slug']
);
}
This has the following advantages:
- If you decide you need different fields from your data object to generate the URL, you only need to change it in one place
- If you need extra context information, it is easy to search where you call this function
- One place to check if you are properly urlencoding everything
- Avoids generating multiple urls for the same page
Because we also want it to be easy to remember, we put them together into an object:
class My_URL{
function root($str=""){ return "/".$str; }
function my($data_object, $context=array()){
return $this->root(
"my_url_page/".$context['category']['name']
."/".$data_object['seo_slug']
);
}
}
function urls(){ return new My_URL(); }
$myurl = urls()->my($data_object, array('category'=>$category) );
To make it a bit more fancy and less work, you can create a bit of magic for common cases:
class My_URL{
// ... same as above. Plus: ...
function __call($method,$args){
$url = $this->root($method);
if(sizeof($args)>0) $url.="?id=".urlencode($args[0]['id']);
return $url;
}
}
You can make it as fancy as you want, for example in some projects we have one big __call function that uses a configuration file to determine the urls based on the method name and data objects. Furthermore you can use functions to normalize urls like upper/lowercase conversion and anything else that will help you generating better and more consistent URLs.