3

I've been searching all day for a solution to replace .php in the URL with a / using .htaccess. Most of the solutions didn't work for me at all (didn't rewrite the URL, even just to remove .php) until I found this beautiful solution on SO.

https://stackoverflow.com/a/11084526/1724376

Now my issue is that it only removes the .php but does not replace it with a "/". I've tried many things with no luck but I don't know much about htaccess and rewrite conditions, etc. I'm really hoping someone here can help me.

Just so I don't get down-voted for not having tried anything, here's one that I tried but it didn't rewrite the URL at all.

RewriteCond /%{REQUEST_FILENAME}.php -f
RewriteRule ^([a-zA-Z0-9_-\s]+)/$ /$1.php

Help will be truly appreciated.

EDIT: To clarify, I want www.mysite.com/contact.php to show up as www.mysite.com/contact/

Community
  • 1
  • 1
Predator
  • 469
  • 2
  • 6
  • 20
  • A lot of people miss the fact that there are two basic types of rule you can set with mod_rewrite; often, you want both. One type takes a pretty URL typed into a browser, and calculates the ugly version that should be served instead, *but is completely invisible to the browser*; the other type takes an old ugly URL, and *tells the browser* to go to a pretty URL instead. The second type is only useful if you have the first type working. The rule you post here is the first type - if you go to a URL ending in `/` it will try to serve a PHP file, but it will *not* redirect the browser in any way. – IMSoP Jun 21 '14 at 23:51
  • Thanks, yes that makes sense. I'm guessing the ones with [R=301] do a 301 redirect. This led me to try RewriteRule (.*)\.php$ $1/ [R=301] but of course that didn't work since example.com/test/ doesn't exist when I try to access example.com/test.php. Still looking for a solution, but at least this sparked some more ideas :) – Predator Jun 21 '14 at 23:58
  • Yep, `[R=301]` means a 301 HTTP redirect; without an `[R]` flag the rewrite is internal, and you'll often see `[L]`, meaning "last", to stop both rules firing at once (they're processed in order, so the other option is to be careful how you list them). You say "of course ... example.com/test/ doesn't exist" - that's the point of the rule you've pasted here, to make that URL exist. My advice: get the "pretty" URLs working if you link to them directly first, *then* worry about redirecting people's browsers if they access the "legacy"/"ugly" URLs instead. – IMSoP Jun 22 '14 at 00:04
  • Making the URLs exist is exactly what I'm trying to avoid though. That's a solid few days of work and then retesting the entire site to make sure everything works. I was hoping htaccess would be the solution here. All I need to do is have example.com/test.php be accessible as example.com/test/ for two reasons - 1) Pretty URLs, and 2) Security by obfuscation (which I know isn't good but it can't hurt). – Predator Jun 22 '14 at 00:09
  • I'm confused: "Making the URLs exist" and "have example.com/test.php be accessible as example.com/test/" are the same thing! If you can access `example.com/test/`, it exists (as far as the browser is concerned). Then you can do whatever you like to tell the browser to load that page (e.g. put in place 301 redirects from "old" URLs). – IMSoP Jun 22 '14 at 00:16
  • Also, "Security by obfuscation (which I know isn't good but it can't hurt)." - a) clearly, it can hurt, if it's causing you this much hassle already; b) it won't be particularly well obscured if you're leaving the `.php` URLs in all the HTML and relying on 301 redirects to take it away; c) there's probably much more telling things someone could look for than the filenames in your URLs. – IMSoP Jun 22 '14 at 00:19
  • Thanks IMSoP. I appreciate your patience with me. I think I've terribly misunderstood htaccess. I was trying to do something like what Wordpress does with prettified URLs. example.com/test/ doesn't exist on my site but example.com/test.php does. With Wordpress I had a similar URL and /test/ was not a folder but it was still accessible. Also, hassle isn't really always a bad thing. At least I'm learning something about htaccess. As I said though, I'm not worried nor am relying on this being a be all end all security measure. I still see no harm in having it, if I can get it working. – Predator Jun 22 '14 at 00:26
  • Well, I have to go to bed now, so I shall wish you good luck. But just to reiterate one more time: the rule you have posted here should mean that when you type `example.com/test/` into your browser, Apache will act as though you had typed in `example.com/test.php`. Forget about folders and files, and what "exists" - it's all just the browser asking for a URL, and Apache responding with some content. Start simple: `RewriteRule ^test/$ /test.php` – IMSoP Jun 22 '14 at 00:40
  • Thanks IMSoP. I appreciate your guidance. I'll play around with this a bit more. – Predator Jun 22 '14 at 00:45

1 Answers1

1

Have your rule like this:

RewriteEngine On

RewriteCond %{THE_REQUEST} \s/+(?:index)?(.*?)\.php[\s?] [NC]
RewriteRule ^ /%1/ [R=302,L,NE]

RewriteCond %{DOCUMENT_ROOT}/$1\.php -f [NC]
RewriteRule ^(.+?)/?$ /$1.php [L]
anubhava
  • 761,203
  • 64
  • 569
  • 643
  • Hi Anubhava. Thanks for the reply. I tried it and it still only removes the .php from the URL but doesn't append the slash. I'm wondering if there's something different about my server configuration. – Predator Jun 22 '14 at 13:34
  • It does place the slash in the end, you need to test this in a new browser to avoid 301 caching problem. Also are you sure you don't have any other rule removing trailing slash? – anubhava Jun 22 '14 at 13:40
  • My entire htaccess is just what you have up there so nothing else is removing the training slash. I tried it again, cleared cache and temporary internet files and tried IE instead of Chrome, same result :( you can see it in action at depts (d0t) org – Predator Jun 22 '14 at 13:48
  • When I sent a request for `http://depts.org/news.php` it became `http://depts.org/news/` with trailing slash in the end. – anubhava Jun 22 '14 at 13:56
  • Same thing happened for `http://depts.org/contact.php` that became `http://depts.org/contact/` in my browser. – anubhava Jun 22 '14 at 14:00
  • You're right, now it seems to work :) I wonder if there was some server-side caching. Thanks! – Predator Jun 22 '14 at 14:02
  • Glad it worked but one thing to remember is to use absolute paths in your css, js, images files rather than a relative one. Which means you have to make sure path of these files start either with `http://` or a slash `/`. – anubhava Jun 22 '14 at 14:04
  • 1
    Thanks, yes that's a good point. This is a development environment so I was avoiding it but will be updating that next using PHP variables to make it easy to update. – Predator Jun 22 '14 at 14:26