Forum Moderators: phranque

Message Too Old, No Replies

.htaccess mod rewrite

         

ahmed24

2:43 pm on Dec 3, 2015 (gmt 0)

10+ Year Member



Can anyone kindly help. I would like to get everything after mydomain.com/ and using mod_rewrite call index.php?modname=value_of_everything_after_mydomain.com

lucy24

7:51 pm on Dec 3, 2015 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



What have you tried so far? This is one of the Top Ten mod_rewrite questions, which means it should come up several hundred times in a WebmasterWorld forums search.

Yes, it would have taken me less time to provide a cut-and-paste answer than to type this much. But if you want cut-and-paste, that's what That Other Forum is for.

ahmed24

8:33 pm on Dec 3, 2015 (gmt 0)

10+ Year Member



I've got the following, which seems to work. However, the first part of the code seems to somewhat conflict with the second part. So for example the first part of the code is there to allow mydomain.com/myscript.php to run as mydomain.com/myscript

However, with the second part of the code, if i go to mydomain.com/myscript/myscript it seems to interfer with the myscript.php and i end up getting a result myscript/myscript.php/myscript.

here is my code:


# BLANK FILE EXTENSION TO .PHP
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{REQUEST_URI} !/$
RewriteRule ^(.*)$ $1\.php

# CONVERT URI TO QUERYSTRING
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) module.php?query=$1 [L]

lucy24

10:17 pm on Dec 3, 2015 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Do any of your URLs contain literal periods? It is perfectly legal, but in some cases it saves a world of trouble if they don't, because then you can use the pattern
^[^.]+$
for any and all extensionless URLs. This, in turn, means you can dispense with the server-intensive !-f test on the second rule (because an extensionless file, more or less by definition, doesn't physically exist), and you never have to evaluate conditions on requests for non-page files.

RewriteCond %{REQUEST_URI} !/$
RewriteRule ^(.*)$ $1\.php
Never put something in a RewriteCond that can go in the body of the rule. Ordinarily this applies to positive REQUEST_URI matches-- but here you can avoid the condition by changing the rule itself from * to +
RewriteRule (.+) /$1\.php [L]
or
RewriteRule ^([^.]+)$ /$1\.php [L]
(Uh-oh, did you really forget the [L] flag or was it just lost in posting?) Note that if you're saying [^blahblah] with a negative, the ^ and $ anchors are essential; if you're searching for any and all characters with .* or .+ you don't need anchors. Note also that targets should always start with / for security.

Now, here's what's confusing me:

example.com/blahblah >> example.com/blahblah.php
OR
example.com/blahblah >> example.com/module.php?query=blahblah

Does this mean that if "blahblah.php" exists, then serve that static content, and otherwise proceed to dynamic content with a query string?

ahmed24

12:33 am on Dec 5, 2015 (gmt 0)

10+ Year Member



Thanks for that. Here is what I have so far:


Options -MultiViews

# Custom Error Documents
ErrorDocument 404 /404.php
ErrorDocument 403 "<H1>Access denied</H1>"

RewriteEngine On

# RULE 1 - REQUIRE SSL RULE
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=302]

# RULE 2 - ALLOW BLANK EXTENSION MATCHING .PHP FILE
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+?)/?$ /$1.php?rewrite=true [L,QSA]

# RULE 3 - REQUEST URI TO QUERYSTRING
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^.]+)/?$ /index.php?modname=$1 [L,QSA]


Seems to be working, is there any room for improvement? Few concerns, 1) is the ErrorDocument code in the correct place? or do they go higher up or lower down?

and is it better to run everything from the
RewriteEngine On
inside the following code:


<IfModule mod_rewrite.c>

</IfModule>


Thanks

lucy24

3:01 am on Dec 5, 2015 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



is the ErrorDocument code in the correct place?

Each module is an island. It makes absolutely no difference to the server what order you put different modules' directives in. Most people find it most convenient to put all the simple one-line statements at the beginning of their htaccess, and the more complicated things later. And most people's sanity is best served by grouping together each module's directives. Again, this is purely for human convenience. The server doesn't care.

The only place ordering makes a difference is within any one module, because each module's directives are generally evaluated one after the other. (Partial exception in the case of mod_authzwhatsit and the "Order" directive, but luckily you're not asking about that.) More about this later.

inside the following code:

The <IfModule> envelope is a hallmark of prepackaged htaccess, especially the kind that comes with a CMS. It's to keep the server from throwing fits if you happen not to have some particular module. But once you are on your own site using your own htaccess file, the <IfModule> envelopes aren't needed. Either you have mod_rewrite or you don't.

# RULE 1 - REQUIRE SSL RULE

I mentioned order earlier. This should be the very last of your external redirects, because it only deploys when a request hasn't already met some other rule. It's convenient if the whole site uses SSL because then you can combine it with the domain-name-canonicalization redirect. Here "example.com" represents the preferred form of your domain name.
RewriteCond %{HTTPS} !=on [OR]
RewriteCond %{HTTP_HOST} !^(example\.com)?$
RewriteRule (.*) https://example.com/$1 [L,R=301]

RewriteCond %{REQUEST_FILENAME} !-f

This line is no longer needed, because if you express the pattern as ^[^.]+$ then you already know that the file doesn't physically exist and the server doesn't have to look for it.

RewriteCond %{REQUEST_FILENAME} !-d

Further thought: how many real, physical directories do you have? If it's a small number, it is probably more efficient to express the Condition with specific names, like
RewriteCond %{REQUEST_URI} !^/(realdir|otherrealdir|thirdrealdir)/?$
It is worth going to some effort to save the server from having to look up whether a file exists, because this is about the most labor-intensive thing a server is ever asked to do. (Short of, ahem, the final step of really serving up the files!)

RewriteRule ^([^.]+)/?$

This will not have the intended result. Captures are always greedy, so the / will never be excluded. If you need to say "omit the final / if any" the form has to be
^([^.]+[^./])/?$
Use the same pattern in any rule that calls for a no-final-slash capture.

Drat. Now I can no longer see your post, so I don't know if I answered everything.

ahmed24

10:31 am on Dec 5, 2015 (gmt 0)

10+ Year Member



Many thanks for that detailed reply. The part where you said to remove: RewriteCond %{REQUEST_FILENAME} !-f
Although it works with it, technically a filename can be there without extension (dot) so then keeping it there might be a better option wouldn't it?

lucy24

8:19 pm on Dec 5, 2015 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



technically a filename can be there without extension (dot) so then keeping it there might be a better option wouldn't it?

Sure, it's physically possible. But will you ever actually do it? From the server's point of view it's far more efficient to do the lookup just once, in your own human brain, rather than make the server check every time. Remember, the server can't say "This file was present (or absent) at server startup so I can assume it's still present (or absent) now". It has to check every single time.

<tangent>
If you did have a filename with no extension-- not to be confused with an extensionless file on, say, your personal computer, where what's really happening is that the OS is hiding the extension-- then the server would have to be told what to do with it. The extension takes care of the problem.

I can't remember meeting a situation where someone found that it was more conveient to have extensionless files-- not URLs-- on their server.
</tangent>