homepage Welcome to WebmasterWorld Guest from 54.145.183.126
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member

Home / Forums Index / Code, Content, and Presentation / Apache Web Server
Forum Library, Charter, Moderators: Ocean10000 & incrediBILL & phranque

Apache Web Server Forum

    
Rewrite rule
kambiz marta



 
Msg#: 4557767 posted 1:18 pm on Mar 23, 2013 (gmt 0)

Hi,
I'm new in this world. I've created an .htaccess file for friendly url and it works.


RewriteRule ^pecatscapitals$ pecatscapitals.php [L]
RewriteRule ^meninaton$ meninaton.php [L]
RewriteRule ^novetats$ novetats.php [L]
RewriteRule ^entreoberts$ entreoberts.php [L]


But I think that should also work this, but it doesn't:

RewriteRule ^(.*)$ $1.php [L]

Can sombody tell me what's wrong?
Thanks very much

 

g1smd

WebmasterWorld Senior Member g1smd us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 4557767 posted 1:44 pm on Mar 23, 2013 (gmt 0)

Once the extra rule rewrites the "
/something" URL request to fetch the /something.php file, the htaccess file is checked again and /something.php matches the (.*) pattern and is rewritten to /something.php.php and the htaccess file is checked again and /something.php.php matches the (.*) pattern and is rewritten to /something.php.php.php and the htaccess file is checked again and /something.php.php.php matches the (.*) pattern and is rewritten to /something.php.php.php.php and this continues until the server traps the error and returns HTTP "Error 500 - Internal Server Error" status.

Using
(.*) is almost always bad, because you're effectively asking your PHP script to deal with requests for robots.txt, css and js files, images and WMT and analytics verification files.

Rather than use
(.*) as the pattern, use a more specific pattern. For best results use extensionless URLs and limit the pattern to match only requests without extensions.

A more specific pattern could be as simple as
^([^.]+)$ or ^([^/.]+)$ or ^(([^/]+/)*[^/.]+)$ or ^([a-z0-9-]+)$ or ^(([a-z0-9-]+/)*[a-z0-9-]+)$ depending on exactly what you do want to match.

[edited by: g1smd at 1:57 pm (utc) on Mar 23, 2013]

kambiz marta



 
Msg#: 4557767 posted 1:51 pm on Mar 23, 2013 (gmt 0)

Thanks very much for you detailed answer.
But what do you mean when you say "For best results use extensionless URLs and limit the pattern to match only requests without extensions"

phranque

WebmasterWorld Administrator phranque us a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month



 
Msg#: 4557767 posted 2:27 pm on Mar 23, 2013 (gmt 0)

"use extensionless urls" means link internally to urls without the .php and externally redirect (with a 301 status code) any request for /example.php to /example

"limit the pattern to match only requests without extensions" means that once you have internally rewritten the request for /example to /example.php the make sure you don't subsequently reuse that internal rewrite for requests with a dot in the path.
thus you avoid rewriting robots.txt to robots.txt.php or example.php to example.php.php or ...

kambiz marta



 
Msg#: 4557767 posted 5:15 pm on Mar 23, 2013 (gmt 0)

Hi again and thanks. I've been looking at internet about extensionsless urls. This code works for me:


RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_fileNAME} !-d
RewriteCond %{REQUEST_fileNAME} !\.html$
RewriteRule ^(.*)$ $1.php [L]


But it uses the pattern (.*) that you have said is not good. But I don't know for what pattern replace it, whatever request_filename plus .php will be found in the folder.

g1smd

WebmasterWorld Senior Member g1smd us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 4557767 posted 5:49 pm on Mar 23, 2013 (gmt 0)

The -f and -d patterns are HUGELY inefficient requiring two calls to the server filesystem for every request received.

Avoid this method by using a more specific pattern, one that matches only extensionless URLs in place of the (.*) pattern.

You also need a slash before the $1 otherwise you leave your server open to path-injection attacks.

kambiz marta



 
Msg#: 4557767 posted 6:07 pm on Mar 23, 2013 (gmt 0)

Hi again.
I've removed all and only write this rule:


RewriteRule ^([^/]+)/$ \$1.php [L]


Is it ok?

Thanks very much

g1smd

WebmasterWorld Senior Member g1smd us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 4557767 posted 6:46 pm on Mar 23, 2013 (gmt 0)

URLs ending with a slash are reserved for folders or the index page of a folder. Try one of the patterns I suggested in the earlier post.

Additionally, the \ should be / in the rule target.

kambiz marta



 
Msg#: 4557767 posted 8:12 pm on Mar 23, 2013 (gmt 0)

Hi,
You say I should replace \ for /.
And also, I should try one of the patterns you have suggested.
Ok. I've tested all, and onyone goes. I'm lost

#RewriteRule ^([^.]+)$ /$1.php [L]
#RewriteRule ^([^/.]+)$ /$1.php [L]
#RewriteRule ^(([^/]+/)*[^/.]+)$ /$1.php [L]
#RewriteRule ^([a-z0-9-]+)$ /$1.php [L]
#RewriteRule ^(([a-z0-9-]+/)*[a-z0-9-]+)$ /$1.php [L]

lucy24

WebmasterWorld Senior Member lucy24 us a WebmasterWorld Top Contributor of All Time Top Contributors Of The Month



 
Msg#: 4557767 posted 9:00 pm on Mar 23, 2013 (gmt 0)

In your first post, all your examples were single words without subdirectories. If that's really your naming structure, then you are almost there. Instead of [^.]+ say [^./]+ and be sure to keep anchors on both sides.

This version
RewriteRule ^(([a-z0-9-]+/)*[a-z0-9-]+)$ /$1.php [L]
will work if all your URLs are lower-case. You cannot use the [NC] flag in any rule that involves rewrites. (Redirect is OK). But you should be able to reduce it to [a-z\d-]+ or even [\w-]+. I'm told that some servers don't like \w although it is standard RegEx so they really have no excuse.

You only need to include the - character if it actually occurs in your URLs. Unlike most things in grouping brackets, it has an extra meaning, so handle with care.

The slash / is a directory slash. In mod_rewrite it has no other meaning. The backslash \ is the RegEx "escape" slash. It has no other meaning.

kambiz marta



 
Msg#: 4557767 posted 9:17 pm on Mar 23, 2013 (gmt 0)

Hi,
Perhaps there is another problem, but
RewriteRule ^(([a-z0-9-]+/)*[a-z0-9-]+)$ /$1.php [L]
neither
RewriteRule ^([^./]+)$ /$1.php [L]
works for me.

All my URLs are lower-case, without numbers, just letters.
Thanks

g1smd

WebmasterWorld Senior Member g1smd us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 4557767 posted 11:16 pm on Mar 23, 2013 (gmt 0)

If all the URL is effectively in the root, then this should work:
RewriteRule ^([a-z]+)$ /$1.php [L]

Request
example.com/something and the /something.php file will be invoked to deal with the request.
kambiz marta



 
Msg#: 4557767 posted 11:32 pm on Mar 23, 2013 (gmt 0)

Hi,
Thanks. I still have problem.

My .htacces files is:

#php_value max_execution_time 500
Options +SymLinksIfOwnerMatch
RewriteEngine On
RewriteRule ^([a-z]+)$ /$1.php [L]


Thanks very much

[edited by: Ocean10000 at 4:30 pm (utc) on Mar 24, 2013]
[edit reason] Removed links [/edit]

lucy24

WebmasterWorld Senior Member lucy24 us a WebmasterWorld Top Contributor of All Time Top Contributors Of The Month



 
Msg#: 4557767 posted 11:34 pm on Mar 23, 2013 (gmt 0)

Perhaps there is another problem, but
RewriteRule ^(([a-z0-9-]+/)*[a-z0-9-]+)$ /$1.php [L]
neither
RewriteRule ^([^./]+)$ /$1.php [L]
works for me.

:: shuffling papers ::

Phooey. I thought I had some boilerplate on the "doesn't work" phrase but I can't find it.

You need to explain exactly what you tried, and what happened when you tried it. You've shown the rule already. Now, what URLs did you try requesting?

Testing rewrites is tricky. Sometimes you can temporarily change them into redirects for testing purposes, so you can look at your browser's address bar and see where the code thinks it is going. But in your case that would lead to going around in circles.

You're in htaccess, so changing your RewriteLog level (2.4 only) is not an option :(

kambiz marta



 
Msg#: 4557767 posted 11:52 pm on Mar 23, 2013 (gmt 0)

Lucy24,
If I've understood well your answer, in my first post is clear what I want and when I say that some rules don't work for me, is just answering the suggestions that g1smd has given to me.

g1smd

WebmasterWorld Senior Member g1smd us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 4557767 posted 12:33 am on Mar 24, 2013 (gmt 0)

If you request
example.com/entreoberts the entreoberts.php file should do its thing.
kambiz marta



 
Msg#: 4557767 posted 12:40 am on Mar 24, 2013 (gmt 0)

Hi,
My request is
http://localhost:8887/francana/entreoberts

and the folder where are all the files is localhost:8887/francana

and I promise I've got error 404

Thanks

[edited by: bill at 2:32 am (utc) on Mar 24, 2013]
[edit reason] unlink example URL [/edit]

lucy24

WebmasterWorld Senior Member lucy24 us a WebmasterWorld Top Contributor of All Time Top Contributors Of The Month



 
Msg#: 4557767 posted 2:01 am on Mar 24, 2013 (gmt 0)

I was typing my previous post while other discussions were going on, so I was really responding to your post from two hours earlier :( g1 asked the same question I did, and you answered it while I was typing. php/bb3 added a splendid fix for this common problem. I am envious.

and the folder where are all the files is localhost:8887/francana

Oh, now, wait. You didn't say anything about localhost earlier, and that makes a big difference.

What kind of server are you using? The first post said htaccess, so I have to assume the localhost is only for testing, and you are really on shared hosting. 8887 can mean absolutely anything; I was hoping for 8888.

More importantly: Is all of this happening within a subdirectory?

Given a request for "/francana/entreoberts",

RewriteRule ^([^.]+)$ $1.php [L]

may lead to either

www.example.com/entreoberts.php

or

www.example.com/francana/entreoberts.php

or ... well, several other possibilities. It depends on where the htaccess rule is located and what you've set as your RewriteBase. You can avoid half of the problem by never using a RewriteBase at all; spell out the full path beginning from the root /

kambiz marta



 
Msg#: 4557767 posted 9:47 am on Mar 24, 2013 (gmt 0)

Hi everybody,
Today seems things are going better.

This rule works fine for me
RewriteRule ^([^.]+)$ $1.php [L]

But know I've noticed that I have to add a parameter

Now the rule is this:
RewriteRule ^([^.]+)/([^.]+)$ $1.php?idioma=$2 [L]

The problem that I have is that it changes my root folder.
The real root folder is:
[localhost:8887...]

the friendly url is:
[localhost:8887...]

and then all relatives address are:
[127.0.0.1:8887...]
instead of
[127.0.0.1:8887...]

To solve it I've added
<base href="http://localhost:8887/francana/" target="_blank">
to the web. But my question is: is there another way to do it without adding this line to every web?

Thanks very much

lucy24

WebmasterWorld Senior Member lucy24 us a WebmasterWorld Top Contributor of All Time Top Contributors Of The Month



 
Msg#: 4557767 posted 11:35 am on Mar 24, 2013 (gmt 0)

Let's try that again. A simple space should do.
The problem that I have is that it changes my root folder.
The real root folder is:
http:/ /localhost:8887/francana

Er, no, it isn't. The real root is
http:/ /localhost:8887/
or
http://www.example.com/
as the case may be. Than /francana/ is a directory inside that.
the friendly url is:
http:/ /localhost:8887/francana/pecatscapitals/ca

Friendlier than what? Or do you just mean that's the form the URL is supposed to have. I haven't seen any unfriendly URLs around.

and then all relatives address are:
http:/ /127.0.0.1:8887/francana/pecatscapitals/....
instead of
http:/ /127.0.0.1:8887/francana/....


Oh, dear. You may be getting less confused but I am becoming more confused. What are your intended URLs? The ones you want your human visitors to see and use. How is /pecatscapitals/ getting into all the URLs? Or was that a typo and it's the /francana/ part you don't want?

To solve it I've added
<base href="http://localhost:8887/francana/" target="_blank">
to the web.

Uh... To what web? You mean the live pages? But they're not on localhost:8887. They're on your real domain.

Relative links should make no difference, because those are based on where the browser "thinks" it is, not where the files really are. So if it doesn't know about /francana/ it will never ask for it. But it's better to use site-absolute links beginning in / everywhere. These will behave the same on a pseudo-server at home, and on your real live site.

Did you ever explain where 8887 comes from?

g1smd

WebmasterWorld Senior Member g1smd us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 4557767 posted 11:48 am on Mar 24, 2013 (gmt 0)

Make sure the links on your page are of the form
href="/something" or href="/folder/something" beginning with a leading slash.

In your original examples, you implied a URL like
www.example.com/entreoberts
but now you're saying it's more like
www.example.com/francana/entreoberts

Be aware that you need a different RegEx patttern when there's a folder in the requested URL.

RewriteRule ^([^.]+)/([^.]+)$ $1.php?idioma=$2 [L]
The above code has at least two errors.
You MUST add a leading slash before $1.
If you omit omit it, you leave your server open to path injection hacks.

Additionally, you need to change the exclusion in the first group:
RewriteRule ^([^/]+)/([^.]+)$ /$1.php?idioma=$2 [L]
or perhaps
RewriteRule ^([^/]+)/([^.]+)$ /folder/$1.php?idioma=$2 [L]
if this rule is in the root htaccess file.

Logically,
([^.]+)/ says "Keep on parsing characters that are not a dot. Stop when you find a dot. Match that character (the dot) to see if it is a slash." The rule will always fail and the regEx parser will have to perform multiple "back off and retry" trial matches to see what you actually meant.

What you want is
([^/]+)/ which says "Keep on parsing characters that are not a slash. Stop when you find a slash. Check the slash is a slash, then ([^.]+)$ parse all characters that are not a dot - until the end."
kambiz marta



 
Msg#: 4557767 posted 4:39 pm on Mar 24, 2013 (gmt 0)

Hi all,
Perhaps all the problem is that my english is very bad, but I can't understand how difficult is to convert an original url to friendly url.
In fact, the only thing I want is this. If got the follow link (it works perfect)
entreoberts.php?idioma=fr

And I want to convert this url to a friendly url like this
entreoberts/fr
Anything more

I'm reading through Internet, I'm bothering you with question, but I think this should be easier or am I wrong?

g1smd

WebmasterWorld Senior Member g1smd us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 4557767 posted 5:16 pm on Mar 24, 2013 (gmt 0)

Link to the URL you want users to "see" and "use". That link will be like: href="/entreoberts/fr"

Set up a rewrite to detect the ^entreoberts/fr$ request and rewrite to activate the /file.php?query=value file or /folder/file.php?query=value file that will respond to the request.

Set up a redirect from example.com/entreoberts.php?idioma=fr or example.com/folder/entreoberts.php?idioma=fr to www.example.com/entreoberts/fr

Each piece of code is very simple. You need a redirect and a rewrite. Both will use RewriteRules. The redirect will also need a preceding RewriteCond to test THE_REQUEST contained a request for a URL with query string. This prevents an infinite redirect - rewrite loop.

On the left of each RewriteRule is the pattern to match the path part of the requested URL. On the right is the target which is an internal file for a rewrite or an external URL with protocol and hostname for a redirect.

Place all the code in the htaccess file in the root of the site. From the web this would be at example.com/.htaccess

#Redirect to friendly URL
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([a-z]+)\.php\?id=([a-z]+)\ HTTP/
RewriteRule ^([a-z]+)\.php http://www.example.com/$1/%2 [R=301,L]

#Redirect to canonical hostname
RewriteCond %{HTTP_HOST} !^(www\.example\.com)?$
RewriteRule (.*) http://www.example.com/$1 [R=301,L]

#Rewrite internal
RewriteRule ^([^/]+)/([^.]+)$ /$1.php?id=$2 [L]



The first ruleset might need to be:

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /folder/([a-z]+)\.php\?id=([a-z]+)\ HTTP/
RewriteRule ^folder/([a-z]+)\.php http://www.example.com/$1/%2 [R=301,L]


The final ruleset might need to be:

RewriteRule ^([^/]+)/([^.]+)$ /folder/$1.php?id=$2 [L]

I am still unsure if the PHP file is in a folder or not.

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / Apache Web Server
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved