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

6
  • 3
    Try just removing your RewriteCond. Looks like you don't need it. Commented Sep 11, 2012 at 14:33
  • As a side note: site.com/contact.php/about does NOT exist. Maybe I should add a re-direct back to home Commented Sep 11, 2012 at 14:57
  • Does contact.php exist? Why would you create URLs that don't point to any resources? Commented Sep 11, 2012 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. Commented Sep 11, 2012 at 15:12
  • 1
    Broken CSS is because of relative URI links, just add a <base href="/"> to the header of your page(s). Commented Sep 11, 2012 at 15:13

4 Answers 4

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]
Sign up to request clarification or add additional context in comments.

Comments

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

2 Comments

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
just render an error page or redirect it to index or home where ever you want by header('location:index.php'); method
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]

3 Comments

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)
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
see jon lin answer (the part where he speaks about internally rewrite it back )
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/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.