Clean URLs in MVC

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

matthijs
DevNet Master
Posts: 3360
Joined: Thu Oct 06, 2005 3:57 pm

Clean URLs in MVC

Post by matthijs »

We all know clean url's like mysite.com/articles/duckies/eating-habits are better then something like mysite.com/index.php?category=duckies&articleid=2635

For a project I'm using Arborint's (simplified) frontcontroller class (seen here). Using this class, one gets urls like
index.php?action=page

Now I would like to tackle the clean url issue before I go on. One option is to use mod_rewrite to rewrite them. However, I have a feeling there should be other ways.

Do I need to rewrite the frontcontroller class to deal with the url's?

For example, I found this function here:

Code: Select all

function url_parse() {
        $url = $_SERVER[‘REQUEST_URI’];
 
        // strip off get vars and anchor tags
        if (strpos($url, ‘?’))
                $url = substr($url, 0, strpos($url, ‘?’));
        if (strpos($url, ‘#’))
                $url = substr($url, 0, strpos($url, ‘#’));
 
        //remove leading slash and possible trailing slash, store in $url
        if (substr($url, 0, 1) == ‘/’)
                $url = substr($url, 1);
        if (substr($url, -1) == ‘/’)
                $url = substr($url, 0, -1);
        if ($url == ‘/’)
                $url = ‘’;
        $url = explode(‘/’, $url);
        
        return($url);
}
 
$actions = Array(
    “” => “front_page.php”,
    “mail” => “mail.php”,
    “member” => “profile.php”,
    “messageboard” => “boards.php”,
);
 
url_parse();
$action = array_shift($url);
if (array_key_exists($action, $actions)) {
    require($actions[$action]);
} else {
    require(“404.php”);
}
The thing is that I will use URL's with more then 1 item in them. So something like /action/subaction/somename/etc

So that will make thing even more complicated. Any hints for directions I should look into?
santosj
Forum Contributor
Posts: 157
Joined: Sat Apr 29, 2006 7:06 pm

Post by santosj »

I use the follow method without mod rewrite

index.php?/page/action

If you use $_SERVER['QUERY_STRING'], then you need to have the '?' or you won't get anything. However, I suspect using the URI would be better, but harder method. However, using the Query String allows you to switch over to mod rewrite instantly.
matthijs
DevNet Master
Posts: 3360
Joined: Thu Oct 06, 2005 3:57 pm

Post by matthijs »

I'm afraid I can't follow you.

I understand how I can use URL's like this:
index.php?page=somepage&action=view
to extract the page and action variables.

But the thing is, I want to do it the other way around. So when a page is requested:
mysite.com/somepage/view/
in fact page somepage is called and action view.

I know how to do this with mod_rewrite. Something like:

Code: Select all

RewriteRule ^/([A-Za-z0-9-]+)/([0-9]+)/?$ ?page=$1&action=$2 [L]
However, if there are other ways then mod_rewrite, I would like to look into those as I think a pure php solution would be cleaner and easier to change.
User avatar
Nathaniel
Forum Contributor
Posts: 396
Joined: Wed Aug 31, 2005 5:58 pm
Location: Arkansas, USA

Post by Nathaniel »

No, there is not.
matthijs
DevNet Master
Posts: 3360
Joined: Thu Oct 06, 2005 3:57 pm

Post by matthijs »

No, there is not
That's a clear answer :)

But, I wonder how for example wordpress does it then. If you look at the htaccess file:

Code: Select all

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress
There are no rules for all the urls in there. While wordpress does produce url's like /archive/category/year/month/day/title

I did take a brief look at the source of some files, but couldn't figure it out (yet).

Anyway, thanks for the help so far.
User avatar
MrPotatoes
Forum Regular
Posts: 617
Joined: Wed May 24, 2006 6:42 am

Post by MrPotatoes »

taht's pretty sweet. once i figure out this forum code i'm going to put that into my framework. i've been dying to know how to do that without mod rewrite. i'd still use mod-rewrtite to remove the index.php tho. *i'm excited about this*
matthijs
DevNet Master
Posts: 3360
Joined: Thu Oct 06, 2005 3:57 pm

Post by matthijs »

MrPotatoes, I share your excitement. But I cannot find the solution in the x.000 lines of wordpress code yet. So if you find out how to manage this, please let me know.
User avatar
Nathaniel
Forum Contributor
Posts: 396
Joined: Wed Aug 31, 2005 5:58 pm
Location: Arkansas, USA

Post by Nathaniel »

Oh, ok. I see what you are going after now.

You can use the htaccess file that you quoted there. Then, I think you'll want to do an explode('/', $_SERVER['REQUEST_URI']) // (something like that) in your PHP file. Fool around with it, I gave you a minimal solution :)

- Nathaniel
User avatar
MrPotatoes
Forum Regular
Posts: 617
Joined: Wed May 24, 2006 6:42 am

Post by MrPotatoes »

matthijs wrote:MrPotatoes, I share your excitement. But I cannot find the solution in the x.000 lines of wordpress code yet. So if you find out how to manage this, please let me know.
i'm knee deep in forum code trying to get it to display the front page corrently. i won't get on that until i finish the forum completely. :(
matthijs
DevNet Master
Posts: 3360
Joined: Thu Oct 06, 2005 3:57 pm

Post by matthijs »

Nathaniel wrote:You can use the htaccess file that you quoted there. Then, I think you'll want to do an explode('/', $_SERVER['REQUEST_URI']) // (something like that) in your PHP file. Fool around with it, I gave you a minimal solution
You are correct. I'll start playing with that and see what I can find out. Thanks for the help.
User avatar
MrPotatoes
Forum Regular
Posts: 617
Joined: Wed May 24, 2006 6:42 am

Post by MrPotatoes »

ake sure to post whatever you find here ok?
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Clean URLs in MVC

Post by Christopher »

matthijs wrote:For a project I'm using Arborint's (simplified) frontcontroller class (seen here). Using this class, one gets urls like
index.php?action=page
...
So that will make thing even more complicated. Any hints for directions I should look into?
Since I was mentioned -- you can get the "less simplified" version here that has an example using a class to map PATH_INFO values onto the Request. I think there is a .htaccess file included with the example. You an even do Rails style routes by providing your own map. And because the mapping is done on the Request object -- not inside the Front Controller -- you can mix both style URLs.
(#10850)
matthijs
DevNet Master
Posts: 3360
Joined: Thu Oct 06, 2005 3:57 pm

Post by matthijs »

Thanks for pointing that out Christopher. The examples look pretty good. Development has not stand still I see, very cool.

I'll study your "less simplified" examples but also start experimenting with my own solution for educational purposes. To bump into the same problems you guys solved already :)
Yossarian
Forum Contributor
Posts: 101
Joined: Fri Jun 30, 2006 4:43 am

Post by Yossarian »

I have been assessing code Igniter and that somehow generates and handles urls just/like/23

where 'just' is the model etc.

I don't have time to pick it apart, but offer the idea as a possible key to your solution.

http://www.codeigniter.com/user_guide/general/urls.html
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Post by Christopher »

matthijs wrote:I'll study your "less simplified" examples but also start experimenting with my own solution for educational purposes. To bump into the same problems you guys solved already :)
Sounds like fun. That is kind of code that you really need to get inside of to understand the issues. Show us some code when you get something working.

Also I have been thinking about adding some Ruby on Rails style route adding methods and RoR style features to that code. It would be nice to be able to have default values in the map -- for example. And maybe a simple method like this to add routes to the map (rather than passing an array):

Code: Select all

$mapper->addRoute('/date/:year/:month/:day/");
What do you think?
(#10850)
Post Reply