1

I am having a little issue forcing the .php file extension to be removed in the URL.

I am successfully able to remove .php file extension if user:

#Remove PHP if original request is /foo/bar.php
RewriteCond %{THE_REQUEST} "^[^ ]* .*?\.php[? ].*$"
RewriteRule ^(.*)\.php(\?.*)?$ $1$2 [R=301,L]

My goal is to get it also to remove the extension if:

# Remove PHP if original request is /foo.php/bar

I ask because right now a user can go to the URL and type http://www.site.com/contact.php/about and it will render my about page. My goal is force the removal of the .php and render: http://www.site.com/contact/about

I was hoping to take the code I have above and add it to but I can not figure it out.

TIA

Jørgen R
  • 10,568
  • 7
  • 42
  • 59
RubyNewbie
  • 547
  • 5
  • 21
  • 3
    Try just removing your RewriteCond. Looks like you don't need it. – Matt S Sep 11 '12 at 14:33
  • As a side note: http://www.site.com/contact.php/about does NOT exist. Maybe I should add a re-direct back to home – RubyNewbie Sep 11 '12 at 14:57
  • Does contact.php exist? Why would you create URLs that don't point to any resources? – Jon Lin Sep 11 '12 at 14:59
  • @Jon Lin: Yes, contact.php does exist. But while looking through our analytics, it displayed that contact-us.php/about-us was being hit for some reason. After running that URL, it will display the contact page but with broken CSS. This is NOT a DB environment. – RubyNewbie Sep 11 '12 at 15:12
  • 1
    Broken CSS is because of relative URI links, just add a `` to the header of your page(s). – Jon Lin Sep 11 '12 at 15:13
  • Thanks Jon! That fixed my CSS issue. – RubyNewbie Sep 11 '12 at 20:54

4 Answers4

2

It looks like you got the removing part, but you're missing the internally rewriting part. What you have attempts to remove the php out of the URL and redirects the client to a URL without it. But your condition isn't matching requests, change it to:

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ .*\.php.*$
RewriteRule ^(.*)\.php(.*)?$ /$1$2 [R=301,L]

Then you need to internally rewrite it back (don't redirect browser). So in the same htaccess file, add:

RewriteCond %{REQUEST_URI} ^/([^/]+)(.*)$
RewriteCond %{DOCUMENT_ROOT}/%1.php -f
RewriteRule ^([^/]+)(.*)$ /$1.php$2 [L]
Jon Lin
  • 142,182
  • 29
  • 220
  • 220
1

the following .htaccess gives me the requested parameters, you can get "page"

AddDefaultCharset utf-8
RewriteEngine On

RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .* - [L]

DirectoryIndex index.php

RewriteRule ^([a-zA-Z0-9_-]{3,20})/([^/]+)/([^/]+)?$ index\.php?page=$1&s=$2&o=$3 [L]

RewriteRule ^([a-zA-Z0-9_-]{3,20})/([^/]+)?$ index\.php?page=$1&s=$2 [L]

RewriteRule ^([a-zA-Z0-9_-]{3,20})/?$ index\.php?page=$1 [L]

RewriteRule ^([a-zA-Z0-9_-]{3,20})?$ index\.php?page=$1 [L]

ErrorDocument 404 /404

Get "page" parameter and then call it like this

include('inc/'.$_REQUEST['page'].'.php');

and remember to remove .php ext from your links

baig772
  • 3,404
  • 11
  • 48
  • 93
  • Since that page does NOT exist and I have no clue how it is rendering, what would a re-direct code look like or maybe I just render an error page – RubyNewbie Sep 11 '12 at 14:58
  • just render an error page or redirect it to index or home where ever you want by `header('location:index.php');` method – baig772 Sep 11 '12 at 15:06
0

Replace your tow lines with this single one : (you have an error in your rule, that's why it is not detecting .php in the middle and you don't need the rewrite condition)

RewriteRule ^(.+)\.php(/.*)?$ /$1$2 [L,R=301]
Oussama Jilal
  • 7,669
  • 2
  • 30
  • 53
  • Using this renders: he document name you requested (/contact-us/about-us) could not be found on this server. However, we found documents with names similar to the one you requested. Available documents: /contact-us.php/about-us (common basename) – RubyNewbie Sep 11 '12 at 14:50
  • The redirection worked, but you will need another rule to do the rewriting from /contact-us/about-us to /contact-us.php/about-us internaly (without changing the browser url) and this withour creating an infinite loop – Oussama Jilal Sep 11 '12 at 15:18
  • see jon lin answer (the part where he speaks about *internally rewrite it back* ) – Oussama Jilal Sep 11 '12 at 15:19
0

My solution for these problems is to basically avoid using complex rewrite rules and do URL routing from the php side, via a simple front controller.

Write the following .htaccess file at the root of your website:

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

Then write an index.php file in the same directory. In the index.php file, you can still get the whole URL information, and choose a PHP file to include based on this.

<?php
// urldecode and get rid of the query string, $_GET is still available
$url = urldecode(preg_replace('/\\?(.*)$/', '', $_SERVER['REQUEST_URI']));

if ($url == '/contact/about') {
    include 'contact.php';
}

That example is extremely basic, and I am probably ignoring subtleties of your website's architecture, but this approach is much more viable in the long run, because you can really map any URL of your liking to PHP scripts without having to endure the complexity of mod_rewrite.

This is the pattern that has been adopted by virtually every existing PHP framework (at least the MVC ones).

An minimalist example of this approach can be found in the Slim micro framework: http://www.slimframework.com/

SirDarius
  • 41,440
  • 8
  • 86
  • 100