Welcome to WebmasterWorld Guest from 54.162.96.103

Forum Moderators: Ocean10000 & incrediBILL & phranque

htaccess rules for hiding php extension

....following removal of WordPress

     
9:10 am on Apr 25, 2017 (gmt 0)

Preferred Member

10+ Year Member Top Contributors Of The Month

joined:Aug 16, 2004
posts: 354
votes: 1


Following on from my discussion in the WordPress forum, which has resulted in me now deciding to completely ditch WordPress and upload standalone pages in the same location, I just have a quick question:

What's the best thing to use in htaccess to ensure the new standalone php pages have the same urls: ie: hiding the php extension and ensuring all URLs are directed the same way (with a "/" at the end?)?
8:01 pm on Apr 25, 2017 (gmt 0)

Senior Member from US 

WebmasterWorld Senior Member lucy24 is a WebmasterWorld Top Contributor of All Time 5+ Year Member Top Contributors Of The Month

joined:Apr 9, 2011
posts:13677
votes: 440


What have you tried so far? What have you read? (Moderate snippiness here because rewriting extensionless URLs has got to be one of the top ten htaccess questions. And besides, I have to go to the store, so this buys me some time.)

Have the URLs ever existed in a with-php form, or in any form other than their present one? Not the physical files, just the URLs, because rewriting is about dealing with incoming requests.
8:14 pm on Apr 25, 2017 (gmt 0)

Preferred Member

10+ Year Member Top Contributors Of The Month

joined:Aug 16, 2004
posts: 354
votes: 1


Hi Lucy,

Not tried anything as yet as I've not uninstalled Wordpress. Basically the pages were created with WordPress. Therefore, they all show URLs as www.example.com/examplepost/ However, when I eventually delete WordPress and re-upload the pages as basic standalone pages, they'll end in www.example.com/examplepost.php.

My thinking behind this is then for Search Engine / links purposes, nothing has really changed (other than I manage each page individually rather than via WordPress).
8:59 pm on Apr 25, 2017 (gmt 0)

Administrator from US 

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

joined:Dec 27, 2006
posts:3230
votes: 146


Have you visited the Library here? There's a good older thread there that goes from rewriting TO .html URLs and the rewriting from .html or .php to '/' that looks like it might help: [webmasterworld.com...]


5:01 am on Apr 26, 2017 (gmt 0)

Senior Member from US 

WebmasterWorld Senior Member lucy24 is a WebmasterWorld Top Contributor of All Time 5+ Year Member Top Contributors Of The Month

joined:Apr 9, 2011
posts:13677
votes: 440


I asked about URL format because there's one thing you will need to do.

Since URLs end in / (slash, as if a directory) you will need to explicitly redirect any incoming requests without the trailing slash to the with-slash form. Some robots do this--variously from stupidity or for entrapment purposes--and some human type-ins may do so by accident. This is not an issue with real, physical directories, because mod_dir takes care of it. But here you have to do it manually.
6:22 am on Apr 26, 2017 (gmt 0)

Preferred Member

10+ Year Member Top Contributors Of The Month

joined:Aug 16, 2004
posts: 354
votes: 1


Thanks, Lucy.

Just did a bit of research and I "think" this is what I'm going to need:

<code>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+)/$ $1.php
RewriteRule ^([^/]+)/([^/]+)/$ /$1/$2.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteRule (.*)$ /$1/ [R=301,L]
</code>
12:47 pm on Apr 26, 2017 (gmt 0)

Preferred Member

10+ Year Member Top Contributors Of The Month

joined:Aug 16, 2004
posts: 354
votes: 1


Also (sorry everyone)! Is there any way I can get that above htaccess rule to only apply to a specific folder? I'm not too fussed about other parts of the site having their extension hidden - it's just the new /blog/ folder that I want?
5:33 pm on Apr 26, 2017 (gmt 0)

Senior Member from US 

WebmasterWorld Senior Member lucy24 is a WebmasterWorld Top Contributor of All Time 5+ Year Member Top Contributors Of The Month

joined:Apr 9, 2011
posts:13677
votes: 440


Is there any way I can get that above htaccess rule to only apply to a specific folder?

Well, yes, and you should be doing it already. The Rule pattern (.*) is way too broad. You need to constrain it to URLs that could potentially be affected by the rule, so the server need not waste time evaluating conditions that will end up not being met.

... and that's why you should always leave a blank line between rulesets, because I only now see that you've got three rules there, and they are in the wrong order. External redirects normally go before internal rewrites. And, with rare exceptions, every RewriteRule needs an [L] flag.

I would do it like this, here assuming your URLs never contain literal periods. (It is perfectly legal, witness apache dot org itself, but certain rules are much easier to construct if you can exclude . at the outset.)

#1 redirect requests without trailing slash:

RewriteRule ^([^.]+[^./])$ http://example.com/$1/ [R=301,L]

This rule will apply to any request that contains no . at all, whether for extensionless URLs or for physical files. Honestly there's no point in doing the server-greedy -f or -d checks. Just redirect everyone; time enough for the server to go looking for the file once the request is in its final form. (This is assuming you're not currently afflicted by a robot such as {name suppressed} that can't keep its database straight and hence persists in attaching other sites' URLs to your own filepaths, leading to floods of 404s. Normally this is not a concern.)

#2 rewrite requests with trailing slash, constrained to your chosen directory

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

If the /blog/ directory contains no subdirectories, there is still no reason for the -d check, and again, why bother with the -f check? If the file doesn't exist, you're going to end up serving a 404 either way.
5:46 pm on Apr 26, 2017 (gmt 0)

Preferred Member

10+ Year Member Top Contributors Of The Month

joined:Aug 16, 2004
posts: 354
votes: 1


Thanks, Lucy - you obviously know your stuff (although I'm such a novice at this that a lot goes over my head).

If I only want to change the "/blog" folder's URLs to not show the extension and instead end with a "/" (the rest of the site can remain as it is), am I just going to using Rule #2 in the htaccess folder - that one single line?

Sorry for the multiple questions - as I say, I'm a novice at this!
6:30 am on Apr 27, 2017 (gmt 0)

Senior Member from US 

WebmasterWorld Senior Member lucy24 is a WebmasterWorld Top Contributor of All Time 5+ Year Member Top Contributors Of The Month

joined:Apr 9, 2011
posts:13677
votes: 440


If all of this is only happening in the /blog/ folder, then rule #1 should also be modified to

RewriteRule ^blog/([^.]+[^./])$ http://example.com/blog/$1/ [R=301,L]

(It won't do any particular harm elsewhere, it's just unneeded work for the server.) Even though this rule comes first in your htaccess, it's not very important--it's simply for when the Googlebot requests slashless URLs. (It does do this. Often.)

The important part is rule #2, the internal rewrite.

And then one day the Googlebot will see that you have pages called
/blog/thispage/
and it will request
/blog/thispage/index.html
but that can be dealt with later.
6:39 am on Apr 27, 2017 (gmt 0)

Preferred Member

10+ Year Member Top Contributors Of The Month

joined:Aug 16, 2004
posts: 354
votes: 1


Thanks so much, Lucy. you've been a great help. I'll try and get this implemented over the next day or so and will let you know how I get on.
3:22 pm on Apr 28, 2017 (gmt 0)

Preferred Member

10+ Year Member Top Contributors Of The Month

joined:Aug 16, 2004
posts: 354
votes: 1


Hi Lucy, Tested this out today and it didn't seem to work? Not sure if I'm missing something?

To confirm, I'm using two lines :

RewriteRule ^blog/([^.]+[^./])$ http://example.com/blog/$1/ [R=301,L]

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

However, when I go to http://example.com/blog/example.php it doesn't redirect to http://example.com/blog/examplepost/ as planned?

I'm probably doing something wrong!
6:30 pm on Apr 28, 2017 (gmt 0)

Senior Member from US 

WebmasterWorld Senior Member lucy24 is a WebmasterWorld Top Contributor of All Time 5+ Year Member Top Contributors Of The Month

joined:Apr 9, 2011
posts:13677
votes: 440


No, you need an additional rule. You currently don't have one for redirecting explicit php requests, because if you've never had visible URLs in that form, you'll never get the request. From, ahem, anyone other than yourself testing all possibilities. But if you'd like to cover all bases, you can readily do it by modifying your existing redirect:
RewriteCond %{THE_REQUEST} \.php
RewriteRule ^blog/([^.]+[^./])(\.php)?$ http://example.com/blog/$1/ [R=301,L]
See how that works? A request that is either missing the desired slash, or has .php at the end, gets redirected. But now you also need a Condition, because of course there will be internal requests for the with-php form. THE_REQUEST means “what the human visitor (or non-human robot) originally asked for”, as distinct from whatever physical file the server is currently handing out.

There are other ways to express this redirect; this is just one possibility. Another option--these aren't mutually exclusive--is to put an extra rule at the very beginning of your RewriteRules (in the same section where, for example, you might poke holes for your error documents):

RewriteCond %{THE_REQUEST} !\.php
RewriteRule \.php$ - [L]
which means “if you’re looking for a .php file, but it’s not because the human visitor directly asked for one, stop right here and go on to the next mod”.
6:38 pm on Apr 28, 2017 (gmt 0)

Preferred Member

10+ Year Member Top Contributors Of The Month

joined:Aug 16, 2004
posts: 354
votes: 1


Thanks, Lucy. Doesn't seem to work, either?

I get: The requested URL /blog/examplepost was not found on this server.
6:51 pm on Apr 28, 2017 (gmt 0)

Preferred Member

10+ Year Member Top Contributors Of The Month

joined:Aug 16, 2004
posts: 354
votes: 1


Just to follow up - I don't know what I've changed but it works now 90%. The only thing that doesn't appear to work is the forced "/" - that's when it now says the page doesn't exist?....getting there, lol.

This is now what I get:

Not Found

The requested URL /home/examplesite/public_html/blog/examplepost/ was not found on this server.]


Strangely, this only happens in Chrome!? In IE all the redirects work perfectly!

...and just to confuse things even more - the redirects work fine in IE, all expect "/" redirect in Chrome and not at all in Edge! Very odd?
10:48 pm on Apr 28, 2017 (gmt 0)

Preferred Member

10+ Year Member Top Contributors Of The Month

joined:Aug 16, 2004
posts: 354
votes: 1


OK...you'll be glad to hear (I'm sure...) that I managed to get it working. The code I now have in my htaccess shows:


RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} \.php
RewriteRule ^blog/([^.]+[^./])(\.php)?$ http://www.example.com/blog/$1/ [R=301,L]
RewriteRule ^blog/([^.]+[^./])$ http://www.example.com/blog/$1/ [R=301,L]
RewriteRule ^(blog/[^.]+)/$ /$1.php [L]


Does this all look OK?

If so, my only other question, is:

Am I safe to now go through manually converting all my Wordpress pages to PHP standalone pages with their same URL - in the eyes of a search engine, will everything still be the same?

Thanks so much again for all your help!
1:27 am on Apr 29, 2017 (gmt 0)

Senior Member from US 

WebmasterWorld Senior Member lucy24 is a WebmasterWorld Top Contributor of All Time 5+ Year Member Top Contributors Of The Month

joined:Apr 9, 2011
posts:13677
votes: 440


Strangely, this only happens in Chrome!?

This is always unnerving when it happens--but 99 times out of 100 it's because the browser is caching its received responses and isn't actually sending in the newly revised request. Fire up a different browser, and things work as they ought. (On my test site I've set expiration to Access for precisely this reason: I want the browser to send in a fresh request every time, no matter what.) In any case it never hurts to empty your browser cache. It's one of those generic Fixes For What Ails you, like “clean the sparkplugs” or “replace your tenor”.

You don’t need the rule
RewriteRule ^blog/([^.]+[^./])$ http://www.example.com/blog/$1/ [R=301,L] 
--no, really, you don't--because that was the purpose of the (\.php)? in the immediately preceding rule. A single rule covers two different scenarios.

in the eyes of a search engine, will everything still be the same?

The beauty of an internal rewrite is that absolutely nobody--no, not even the Googlebot--knows what you are doing. It is impossible for anyone to tell what lies behind
example.com/blog/blahblah/
It could be
example.com/blog/blahblah/index.html
(the default and likeliest explanation) or
example.com/blog/blahblah/index.php
or
example.com/blog/blahblah.php
or
example.com/index.php?long-complicated-query-string
or
... et cetera.
7:55 am on Apr 29, 2017 (gmt 0)

Preferred Member

10+ Year Member Top Contributors Of The Month

joined:Aug 16, 2004
posts: 354
votes: 1


Thanks, Lucy.

However, if I remove

RewriteRule ^blog/([^.]+[^./])$ http://www.example.com/blog/$1/ [R=301,L] 


That's what I get the error come up when you type in the address without the "/"
4:46 pm on Apr 29, 2017 (gmt 0)

Preferred Member

10+ Year Member Top Contributors Of The Month

joined:Aug 16, 2004
posts: 354
votes: 1


Been playing around with this all day and can't seem to get all the redirects working without all the following:


RewriteCond %{THE_REQUEST} \.php
RewriteRule ^blog/([^.]+[^./])(\.php)?$ http://www.example.com/blog/$1/ [R=301,L]
RewriteRule ^blog/([^.]+[^./])$ http://www.example.com/blog/$1/ [R=301,L]
RewriteRule ^(blog/[^.]+)/$ /$1.php [L]


If I remove the third line, the redirect when / isn't used doesn't work.

Will it be OK to simply leave it as it is seeing as it works? I did a header check and all seems to be ok:
example.com/blog/page.php - 301 redirects to example.com/blog/page/
example.com/blog/page/ - 301 redirects to example.com/blog/page/
example.com/blog/page/ - 200 OK

and example.com/page.php keeps the extension on the end and returns 200 OK as it should.

As you can see, it all seems to work fine.

I know I've been repeating myself a lot the past day or so, and I really appreciate the help you've given me. I just need to make sure this is 100% correct before I make a start on my WordPress removal project.
7:11 pm on Apr 29, 2017 (gmt 0)

Senior Member from US 

WebmasterWorld Senior Member lucy24 is a WebmasterWorld Top Contributor of All Time 5+ Year Member Top Contributors Of The Month

joined:Apr 9, 2011
posts:13677
votes: 440


Sure, leaving the rule won't do any harm. But do put a blank line after each RewriteRule. That's for your own sake, not the server's: in Apache files, unlike in robots.txt, a blank line has no syntactic meaning. (A blank space within a line does, of course.)

example.com/blog/page/ - 301 redirects to example.com/blog/page/

Typo, I hope :)

If you're keeping all three Rules, you can simplify the first one--the one with the RewriteCond--so the package goes
RewriteCond %{THE_REQUEST} \.php
RewriteRule ^blog/([^.]+)\.php$ http://www.example.com/blog/$1/ [R=301,L]

RewriteRule ^blog/([^.]+[^./])$ http://www.example.com/blog/$1/ [R=301,L]

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

Incidentally ... will there ever be further slashes in the part of the URL after /blog/ other than, of course, the final slash? If not, all occurrences of [^.]+ in all three rules can be expressed as [^./]+ and the capture in Rule #2 becomes ([^./]+)$

But that's another optional extra.
7:38 pm on Apr 29, 2017 (gmt 0)

Preferred Member

10+ Year Member Top Contributors Of The Month

joined:Aug 16, 2004
posts: 354
votes: 1


Thanks as always, Lucy. Have changed htaccess to the above and all works perfectly. Good spot on the type - that line should have shown example.com/blog/page (without forward slash) - 301 redirects to example.com/blog/page/

Now to the fun part! Thanks for putting up with my 101 questions!
8:35 pm on Apr 29, 2017 (gmt 0)

Senior Member

WebmasterWorld Senior Member topr8 is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month

joined:Apr 19, 2002
posts:3288
votes: 24


>>Is there any way I can get that above htaccess rule to only apply to a specific folder?

yes, very easy, put an htaccess file with that rule in that particular folder.

(you can have as many htaccess files as you like ... infact that's why ideally htaccess files should not be used if access to the actual config file, because if htaccess is enabled, ian htaccess file is searched for in each and every folder in the uri path ... not much overhead it is true, but all the same, every little helps.)
4:30 am on Apr 30, 2017 (gmt 0)

Senior Member from US 

WebmasterWorld Senior Member lucy24 is a WebmasterWorld Top Contributor of All Time 5+ Year Member Top Contributors Of The Month

joined:Apr 9, 2011
posts:13677
votes: 440


put an htaccess file with that rule in that particular folder.

Unfortunately the current rules use mod_rewrite, whose inheritance behaves differently from all other mods. Having more than one use of mod_rewrite along the same path should be avoided if at all possible. Fortunately there's a simple alternative, which is to include the directory (here /blog/) as part of the pattern.

Multiple htaccess files are, on the other hand, the only option if selected directories are to have different access-control rules, different Index settings, different headers, different expiration times, custom error documents ... et cetera, et cetera.

<topic drift>
Even if it's your own server so you can easily put everything in config, I would still set aside one directory for testing and allow all Overrides (i.e. htaccess) for that directory only. Then you can do preliminary testing on the fly without having to restart the server.
</td>
8:27 am on Apr 30, 2017 (gmt 0)

Senior Member

WebmasterWorld Senior Member topr8 is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month

joined:Apr 19, 2002
posts:3288
votes: 24


fair enough, although why do you need to restart the server? i think you can just reload the config file if you make changes, but i take your point.
 

Join The Conversation

Moderators and Top Contributors

Hot Threads This Week

Featured Threads

Free SEO Tools

Hire Expert Members