Forum Moderators: phranque

Message Too Old, No Replies

mod rewrite: /foo.php -> /index.php?page=foo

Wrapping all pages in the same template

         

Jesdisciple

9:41 pm on Jun 10, 2009 (gmt 0)

10+ Year Member



In case I'm doing this the long way, here's the problem I'm trying to solve. I want to catch all uncaught exceptions on all pages and hide them until the user asks for them. That means I need to wrap the entire page in a try-catch, but each page is composed of three files, and PHP's advanced escaping [us.php.net] doesn't work across files. So I can't settle for placing my 'try' in top.php and 'catch' in bottom.php; I must wrap the page at the topmost level, above all the inclusions. I don't want to do this for every individual page, so I'm resorting to a template that will manage every page. I'd rather keep my pretty URLs, and that's where mod_rewrite comes in.

Whew. Now, here's my .htaccess, which doesn't work:

RewriteEngine on
RewriteRule ^/([^/]+)\.php(\?(.*))?$ /index.php?page=$1&$3

It should rewrite /page.php?foo=bar to /index.php?page=page&foo=bar but it doesn't do anything at all. Did I mess my regex up?

Thanks.

jdMorgan

10:22 pm on Jun 10, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



No, you messed up your URL vs. query string handling and syntax, and created an 'infinite' loop as well. You've read the Apache mod_rewrite documentation at apache.org through-and-through several times by now, right? :)

Save yourself lots of time... Do it now.


RewriteEngine on
#
RewriteCond $1 !=index
RewriteRule ^(.+)\.php$ /index.php?page=$1 [QSA,L]

Jim

Jesdisciple

2:53 am on Jun 11, 2009 (gmt 0)

10+ Year Member



Oh, thanks! I don't suppose you would know how to "canonicalize" that by doing the reverse in a redirect rule? I can't find a way to grab the page name from the query string.

EDIT: Here's my failed attempt:

RewriteCond %{QUERY_STRING} page=([^&;]*)
RewriteRule =index.php %1 [R]

Re RTFM: Nah, I just went through what looked relevant to my situation. I don't think I could ever cram a whole manual in my brain without trying anything and probably asking a question. Although I have pounced for that myself before, and had I used Ctrl+F I might not have had such a big question.

[edited by: Jesdisciple at 3:15 am (utc) on June 11, 2009]

jdMorgan

5:22 pm on Jun 11, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Time spent studying this module is a wise investment since -- as the corrections below will demonstrate, a single typo can break your rule, take down your server immediately (if you are lucky), or (if you are not so lucky) quietly erode your search rankings over time, and possibly put you out of business. Don't forget that this is server configuration code and its correctness is fundamental to the proper operation and success of your site... It is indeed a 'fine' manual. :)

RewriteCond %{THE_REQUEST} ^[A-Z]+\ /index\.php\?([^&]*&)*page=([^&]+)(&[^\ ]*)*\ HTTP/
RewriteRule ^index\.php$ http://www.example.com/%2.php [R=301,L]

It is necessary to check THE_REQUEST to be sure that only direct client requests for the script-path-plus-query URL will redirected, and that no redirect will be invoked if that path is internally requested (as a filepath) as a result of your current internal rewrite rule. If this is not done, the two rules will countermand each other, resulting in an 'infinite' rewrite/redirect loop (and taking down your server).

Note that the variable THE_REQUEST contains the exact client request line as seen (in quotes) in your raw server access log file.

Jim

Jesdisciple

11:59 pm on Jun 12, 2009 (gmt 0)

10+ Year Member



Alright, now that I squashed that PHP bug...

Thanks much for the rules. Since I'm going through this whole URL-beautification, I decided to try taking the .php off the end in a redirect. But I ran into trouble with the feature that interprets foo the same as foo.php; is there any way to turn that off? Thanks again.

Regarding my semi-informed experimentation, note that I'm doing all this on my localhost. Hopefully I won't deploy any broken rules.

encyclo

12:26 am on Jun 13, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



the feature that interprets foo the same as foo.php; is there any way to turn that off?

The feature is called MultiViews [httpd.apache.org], and you can turn it off in .htaccess or httpd.conf with the appropriate

Options
directive. Unless you are actually using content negotiation, then it is best to turn off the feature as it can interfere with rewrites and opens you up to unnecessary duplicate-content issues.