Friendly URL for MVC framework

Discuss practical ways rearrange URLs using mod_rewrite.

Friendly URL for MVC framework

Postby phynv » Wed Feb 04, 2009 6:26 am

Hi guys,

first of all: hi to the forum :)

I have a kinda weird problem. I'd like to rewrite URLs for a MVC (Model View Controller) based framework and cannot solve this.

The url looks like http://www.domain.tld/controller/action/id and shall be rewritten to http://www.domain.tld/controller.php?a=action&i=id

Additionally all the other possibilities have to work too:
http://www.domain.tld/controller => http://www.domain.tld/controller.php

http://www.domain.tld/controller/ => http://www.domain.tld/controller.php

http://www.domain.tld/controller/action => http://www.domain.tld/controller.php?a=action

http://www.domain.tld/controller/action/ => http://www.domain.tld/controller.php?a=action


What I tried is the following

Code: Select all
RewriteRule ^([a-zA-Z0-9]+)$ $1.php [L,QSA]
RewriteRule ^([a-zA-Z0-9]+)/$ $1.php [L,QSA]
RewriteRule ^([a-zA-Z0-9]+)/([a-zA-Z0-9._]+)$ $1.php?action=$2 [L,QSA]
RewriteRule ^([a-zA-Z0-9]+)/([a-zA-Z0-9._]+)/$ $1.php?action=$2 [L,QSA]
RewriteRule ^([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)$ $1.php?action=$2&id=$3 [L,QSA]
RewriteRule ^([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/$ $1.php?action=$2&id=$3 [L,QSA]


This works as long as the URL keeps with this pattern.

Is there a possibility to get these rules in only one rule and how can I exclude some folders (like CSS, Javascript) from being rewritten? Do I need a RewriteCondition before every rule?

Hope you can help me.

Thanks a lot.
phynv
 
Posts: 8
Joined: Wed Feb 04, 2009 6:11 am

Postby richardk » Wed Feb 04, 2009 11:51 am

Is there a possibility to get these rules in only one rule

/? will make the / optional.
(?:something)? will make the something optional (but not create a new backreference ($n)). These can be nested.

Code: Select all
Options +FollowSymLinks

RewriteEngine On

RewriteRule ^([a-z0-9]+)(?:/([a-z0-9]+)(?:/([a-z0-9]+))?)?/?$ /$1.php?action=$2&id=$3 [NC,QSA,L]


how can I exclude some folders (like CSS, Javascript) from being rewritten?

Do they follow a pattern? Are they in a certain directory or directories?

Do I need a RewriteCond before every rule?

They can be excluded on a per rule basis
Code: Select all
RewriteCond %{REQUEST_URI} !^something$ [NC]

or they can be matched and mod_rewrite can be told to ignore them
Code: Select all
RewriteRule ^something$ - [L]
richardk
 
Posts: 8800
Joined: Wed Dec 21, 2005 7:50 am

Postby phynv » Wed Feb 04, 2009 11:23 pm

Hi richardk,

thank you very much for your reply. I tested your code and it works. I only had to remove the / infront of $1.php

Well, when I put a condition like
Code: Select all
RewriteCond %{REQUEST_URI} !^css$ [NC]

infront of your suggested rule, CSS is correctly interpreted for the following URL:
Code: Select all
http://www.domain.tld/controller

But when I have a / after the controller like
Code: Select all
http://www.domain.tld/controller/

or any other URL like
Code: Select all
http://www.domain.tld/controller/action

CSS is not longer interpreted.

My aim is to have CSS-folders and other folders (e.g. css/, javascript/, images/) excluded from the rule for the URL rewriting.


Thank you in advance for your help!



=====UPDATE=====
I found something interesting...

I linked to all stylesheets files like this:
Code: Select all
<link rel="stylesheet" type="text/css" href="css/reset.css" media="screen" />

but when I change the link into
Code: Select all
<link rel="stylesheet" type="text/css" href="http://www.domain.tld/css/reset.css" media="screen" />

CSS is set correctly everywhere. Any idea?



=====UPDATE2=====
For some reason hidden field values are being rewritten too... is that correct?
I use hidden-fields for transporting data via POST (e.g. through a form). If I use the rules that I posted in my first post a hidden-field like
Code: Select all
<input type="hidden" name="action" id="action" value="update">

is used correctly. With the rule that you posted the hidden-field is not being recognized or whatever.
Thanks again for your help!
phynv
 
Posts: 8
Joined: Wed Feb 04, 2009 6:11 am

Postby richardk » Thu Feb 05, 2009 2:17 am

My aim is to have CSS-folders and other folders (e.g. css/, javascript/, images/) excluded from the rule for the URL rewriting.

Try
Code: Select all
Options +FollowSymLinks

RewriteEngine On

RewriteCond %{REQUEST_URI} !^/(css|images|javascript)(/.*)?$ [NC]
RewriteRule ^([a-z0-9]+)(?:/([a-z0-9]+)(?:/([a-z0-9]+))?)?/?$ ./$1.php?action=$2&id=$3 [NC,QSA,L]


CSS is set correctly everywhere. Any idea?

FAQ: Relative paths to images, JavaScript, CSS and other external/linked files are broken.

For some reason hidden field values are being rewritten too... is that correct?
I use hidden-fields for transporting data via POST (e.g. through a form). If I use the rules that I posted in my first post a hidden-field like
Code: Select all
<input type="hidden" name="action" id="action" value="update">

is used correctly. With the rule that you posted the hidden-field is not being recognized or whatever.

POST variables should not be changed unless there is a redirect. Any redirect causes POST variables to be lost. Are there any redirects?
richardk
 
Posts: 8800
Joined: Wed Dec 21, 2005 7:50 am

Postby phynv » Thu Feb 05, 2009 2:53 am

Hi and thank you :-)

No, there is no redirection... at least not in the htaccess. The PHP redirection (header redirection) comes after saving the post data to the object. That's actually the point: when I use the rule you suggested POST data never reaches the object...

My whole htaccess looks like
Code: Select all
Options +FollowSymLinks
RewriteEngine on

RewriteCond %{REQUEST_URI} !^/(css|images|javascript)(/.*)?$ [NC]
RewriteRule ^([a-z0-9_]+)(?:/([a-z0-9_]+)(?:/([a-z0-9_]+))?)?/?$ ./$1.php?action=$2&id=$3 [NC,QSA,L]


However, when I use the following rules:
Code: Select all
RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/?$ $1.php?action=$2&id=$3 [L,QSA]
RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/?$ $1.php?action=$2 [L,QSA]
RewriteRule ^([a-zA-Z0-9_]+)/?$ $1.php [L,QSA]

POST data comes through as expected...
phynv
 
Posts: 8
Joined: Wed Feb 04, 2009 6:11 am

Postby richardk » Thu Feb 05, 2009 3:20 am

Edit:
The GET variable could be overwriting the POST variable. What is the form action?
richardk
 
Posts: 8800
Joined: Wed Dec 21, 2005 7:50 am

Postby phynv » Thu Feb 05, 2009 3:32 am

Form tag looks like
Code: Select all
<form action="http://www.domain.tld/controller/" method="post" enctype="multipart/form-data">


In this case, the controller is named "property", ergo
Code: Select all
<form action="http://www.domain.tld/property/" method="post" enctype="multipart/form-data">


And there is this hidden field
Code: Select all
<input type="hidden" name="action" id="action" value="update">

and of course some more fields / values that are expected to be transported through POST.
phynv
 
Posts: 8
Joined: Wed Feb 04, 2009 6:11 am

Postby richardk » Thu Feb 05, 2009 4:47 am

And there is this hidden field
Code: Select all
<input type="hidden" name="action" id="action" value="update">

and of course some more fields / values that are expected to be transported through POST.

Are you using $_POST or $_REQUEST? Have you print_r()ed the $_GET, $_POST and $_REQUEST arrays to see what they contain?
richardk
 
Posts: 8800
Joined: Wed Dec 21, 2005 7:50 am

Postby phynv » Thu Feb 05, 2009 5:44 am

Richard, you are the greatest! Honestly!

I only debugged selected vars but never one of the whole arrays. However, you were right: the GET array was overwriting the POST array with empty values. I changed the code to use the REQUEST array instead and made a successful test.

Thanks a thousand times :-)
phynv
 
Posts: 8
Joined: Wed Feb 04, 2009 6:11 am

Postby phynv » Mon Feb 16, 2009 4:14 am

Hi Richard (again) :-)

could it be that the rule you gave me does not work for Apache 1.3.3? I have one server running on this version but always get a 500 internal server error.

Any idea?

Many thanks in advance..
phynv
 
Posts: 8
Joined: Wed Feb 04, 2009 6:11 am

Next

Return to Friendly URLs with Mod_Rewrite

Who is online

Users browsing this forum: No registered users and 26 guests

cron