50

I want a mod_rewrite rule set, so I can refer to a page without the .php extension, but have that rewritten to include the .php extension. This will be running on a 1&1 server.

Are there any good references so I can learn more myself?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
James
  • 1,764
  • 5
  • 31
  • 49
  • possible duplicate of [Making a rewriterule remove .php extension?](http://stackoverflow.com/questions/781738/making-a-rewriterule-remove-php-extension) – Sebastian Paaske Tørholm Feb 05 '11 at 16:48
  • 4
    Please keep in mind that you're creating a permanent resource for the rest of the web when you ask a question and get others' answers. Use a meaningful question title and don't write the body as if it's a personal letter. – Dan Grossman Feb 05 '11 at 16:49
  • possible duplicate of [How to remove file extension from website address? (sample photos attached)](http://stackoverflow.com/questions/6534904/how-to-remove-file-extension-from-website-address-sample-photos-attached) – Dave Jarvis Apr 08 '12 at 00:03

9 Answers9

74
RewriteEngine On
RewriteRule something something.php [L]

http://example.com/something will be handled as if it was a request for something.php

To redirect all requests that are not a physical file to the same name but with .php:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule (.*) $1.php [L]
Bryan Downing
  • 15,194
  • 3
  • 39
  • 60
Dan Grossman
  • 51,866
  • 10
  • 112
  • 101
  • That's great, I can confirm that works, but how do I do this generally for all pages? It would also be nice if contact.php was redirected to just "contact". – James Feb 21 '11 at 00:21
  • Well, you need to identify and codify the mapping between URIs and physical files. I've edited my answer to give you an example. If you want contact.php to redirect to contact, then `RewriteRule contact.php contact [R=301,L]`. To redirect all requests ending in .php, `RewriteRule (.*)\.php $1 [R=301,L]`. Note the use of R=301 to force an HTTP 301 Permanently Moved redirect, which causes the browser to send a fresh HTTP request for the new URL, which in turn will trigger your rule mapping the URL back to the .php file that actually handles it. – Dan Grossman Feb 21 '11 at 02:16
  • I'm doing exactly this: `RewriteRule (.*)\.php /$1 [R=301,L]` `RewriteCond %{REQUEST_FILENAME} !-d` `RewriteCond %{REQUEST_FILENAME} !-f` `RewriteRule ^([A-Za-z0-9-]*)$ $1.php [L]` And ending in a redirect loop. – Mauro Jul 11 '12 at 18:14
  • 26
    Sorry to comment on such an old answer, but for those who find this later on: I found that while Dan's second example (redirecting all requests) works great, it prevents any 404 Not Found errors on invalid URLs (if there is no `something.php`, `http://example.com/something` will not return a 404, it will return a 500 Internal Server Error). To fix this, I added a third RewriteCond: `RewriteCond %{REQUEST_FILENAME}.php -f`, which will only allow the rewrite if there is in fact a matching php file. – Mike Turley Dec 21 '12 at 21:01
  • 6
    This might be a late comment, but I've seen links to this answer frequently and in my opinion the answer is not completely right. ¿What happens when the incoming URl is `http://example.com/something/`? with a trailing slash. The substitution URL would be `http://example.com/something/.php`, which doesn't work. The error is in this regex group (.*) that is passing everything, including the slash. – Felipe Alameda A Feb 04 '13 at 15:22
  • 1
    What happens when the incoming URI is `/i/hate/you!`? Well, it's going to 404 because that doesn't exist, and that's fine since we won't generate any links to `/i/hate/you!` and if someone wants to type that, they're free to receive the error. If you actually wanted to correct what you perceived as an error, the answer is not to simply change the capture group to account for slashes, but to check if a PHP file matching the URI with `.php` appended exists to rewrite the request to. Another `RewriteCond`, that is. – Dan Grossman Feb 05 '13 at 01:14
  • 2
    Filipe's comment is an important one and the answer doesn't handle that case correctly. It causes Apache to recurse undesirably trying to send the request to /something/.php.php.php.php.php.php.php.php.php.php.php and stopping with "Request exceeded the limit of 10 internal redirects due to probable configuration error." Waste of computing resources. – Ted Henry May 02 '19 at 02:25
  • 1
    For anyone looking to also have http://example.com/something.php redirect to a 404 page, you can add the following: `RewriteCond %{THE_REQUEST} "^[^ ]* .*?\.php[? ].*$"` `RewriteRule .* - [L,R=404]` https://www.php.net/manual/en/security.hiding.php – Josh Bernfeld Dec 30 '19 at 07:43
  • 1
    Is it possible to remove the .php extension without using a redirect? – Freedo Apr 03 '20 at 07:55
22

The accepted answer above does not remove the .php extension from urls it just allows you to visit .php files without extension. To remove the .php extension completely from urls , you can use the following Rules in root/.htaccess :

RewriteEngine on

#1)externally redirect "/file.php" to "/file"   
RewriteCond %{THE_REQUEST} /([^.]+)\.php [NC]
RewriteRule ^ /%1 [NC,L,R]
#2)Internally map "/file" back to "/file.php"
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*?)/?$ /$1.php [NC,L]
Amit Verma
  • 40,709
  • 21
  • 93
  • 115
  • Is there a way to handle these redirects in a single 301 hop? This is the ouput I currently get from redirecting /file.htm to /file https://pastebin.com/4Px79Qw1. And this is the .htaccess https://pastebin.com/wvWPH4BZ – Matthew S Sep 10 '19 at 14:02
4

Probably what you really want is just a way to not have the suffix at all. The best way I've found of doing this is to use the Files directive in .htaccess or in apache configuration files:

<Files myscript>
   SetHandler cgi-script
</Files>

This avoids some of the downsides of rewrites, e.g., direct access of the .php file.

Poor Yorick
  • 229
  • 1
  • 4
  • 4
4

.htaccess file: add the following lines:

Options +MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]

https://alexcican.com/post/how-to-remove-php-html-htm-extensions-with-htaccess/

Now you would have to check for the AllowOverride condition in apache2.log file: set options AllowOverRide All in your web root directory:

Options Indexes FollowSymLinks  
AllowOverride All  
Require all granted

If you try to access your webpage without the .php extension, you may run into the following error in your apache error.log file: /var/www/html/web/.htaccess: Invalid command 'RewriteEngine', perhaps misspelled or defined by a module not included in the server configuration

To fix this: You don't have the mod_rewrite module installed, To install it: Run the following command: ln -s /etc/apache2/mods-available/rewrite.load /etc/apache2/mods-enabled/rewrite.load

.htaccess: Invalid command 'RewriteEngine', perhaps misspelled or defined by a module not included in the server configuration

Again, after refreshing the webpage, you might get the folloowing error in error.log file:

[negotiation:error] [pid 4650] [client 127.0.0.1:46461] AH00687: Negotiation: discovered file(s) matching request: /var/www/html/web/test (None could be negotiated). (I was trying to access localhost/web/test.php using the url: localhost/web/test)

To fix it you would have to add the following lines in apache2.conf:

<IfModule mod_mime.c>
    AddType application/x-httpd-php .php
    AddType application/x-httpd-php .phtml
    AddType application/x-httpd-php .php3
    AddType application/x-httpd-php .php4
    AddType application/x-httpd-php .html
    AddType application/x-httpd-php-source .phps
</IfModule>

https://forums.digitalpoint.com/threads/htaccess-addtype-application-x-httpd-php-php-htm-html-and-maybe-a-fix.7584/#post-2491687

Now, I can access the test.php file using just the filename: test

dgreene
  • 215
  • 3
  • 7
user3683297
  • 156
  • 1
  • 8
2

For some reason I wasn't able to get any other solution working properly. I put this in an .htaccess file at the root of my site. Hopefully this will work for you.

RewriteEngine on #only use this once per .htaccess
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteCond %{REQUEST_FILENAME}\.php -f 
RewriteRule ^(.*)$ $1.php 

It's important to keep in mind that if your header or URL contains the .php extension it won't be removed. You'll need to remove the extension.

Use this...

header 'location: /login';

rather than this...

header 'location: /login.php';
EternalHour
  • 8,308
  • 6
  • 38
  • 57
1

This Option will make clean SEO friendly URL's. Removing.php extensions from the visible URL, and ensuring that URL's accessed without the .php will still display the .php file. I was unable to find another answer that achieved this on multiple threads.

Remember to enable mod rewrite. On Debian or Unbuntu linux the following will work

sudo a2enmod rewrite

and

sudo service apache2 restart

Modify the corresponding section of your apache2.conf file to the following.

<Directory /var/www/>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
        RewriteEngine On
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteRule (.*) $1.php [L]
        RewriteCond %{THE_REQUEST} /([^.]+)\.php [NC]
        RewriteRule ^ /%1 [NC,L,R]
</Directory>

If using .htaccess to re-write ensure that the apache2.conf at least has these options enabled.

<Directory /var/www/>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
        RewriteEngine On
</Directory>

Finally on some Apache install you may need to also set AllowOveride All in a .conf file in /etc/apache2/sites-available or /etc/apache2/sites-enabled.
Rewriting from apache2.conf file as opposed to .htaccess is rumored to be faster.

Greggory Wiley
  • 660
  • 6
  • 16
0

To get http://example.com/test linking http://example.com/test.php use:

RewriteEngine on
RewriteRule ^([^\.]+)$ /folder/$1.php [NC,L] 
Zon
  • 18,610
  • 7
  • 91
  • 99
0

For directing a few single files it might be easier to avoid the RewriteEngine.

I've used this:

<Files $filename>
   SetHandler application/x-httpd-php
</Files>

That's less powerful and flexible than rewrite but probably faster and seems like the way to go if you wish to just have a few specific files handled as PHP.

John
  • 7,507
  • 3
  • 52
  • 52
0
RewriteEngine On

# Redirect sites with no extension to .php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{REQUEST_URI} !/$
RewriteRule .* %{REQUEST_URI}.php

This is what I came up with. This is based off of the accepted answer and its comments.

Denis5161
  • 1
  • 2