Renaming .php files?

In the .htaccess file, how do you get all website address’s that end with .php to strip off that part ie, to take away the .php part

Any help appreciated.

Dez

Why would you want to do that? how would the server read just the file names then? I think maybe you want to display all .php files as .html or vice versa? I’ve done just that before, having .html files behave as if they are .php with .htaccess. Please look on google for “.PHP as .HTML through .htaccess” You will quickly find your answer.

Try something like:

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

It should rewrite anything that doesn’t have an extension and that doesn’t exist.

Another option is to save your files without extensions and parse extensionless files as PHP - though I wouldn’t recommend it.

Your best approach, to be honest, is sending every non-existent request to a PHP controller, which deals with requests from there. For example:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ Controller.php?Path=$1

Controller.php:

$Path = $_GET['Path'];
$PathSplit = explode('/', $Path);
//$PathSplit contains the path in an array. E.g. a request to /page/view/3 would exist as array('page', 'view', 3). Use a switch to figure out the first item, then the second, and handle like that

That would be the beginning of an MVC-style application.

Dez,

That’s YOUR job. Did you read the tutorial linked in the sticky threads OR in my signature. WHY would you even want to have Apache strip off the file extension(s) - as DIDO says, what would Apache use to parse your php files (let alone the others) for your visitors?

Although I abhor the use of the :kaioken: EVERYTHING :kaioken: atom (normally, that’s (.*) but Jake’s is the same thing excluding the dot character and requiring at least one character - BTW, don’t escape the dot character in a range definition) but this is essentially what WordPress (and other CMS systems) use. What his code is doing is

  1. Ensuring that mod_rewrite is not in comment mode

  2. Checking to see whether the {REQUEST_URI} is a file

  3. Checking to see whether the {REQUEST_URI} is a directory

  4. Redirecting everything without a dot character (in the path/filename) to the same thing with a .php extension.

Personally, I would use ([a-zA-Z]+) to specify the character I want mod_rewrite to match (rather than the NOT match anything with a dot) but that runs into problems with accented and “special” characters).

I also agree with Jake that directing Apache to parse extensionless files as PHP is not advised.

As to his “controller” script, that’s again what WP does … with EVERYTHING. WP uses index.php to parse every request (which is not a file, i.e., css, js, jpg, etc) to pull content from a database using modules determined from the parsed request.

Okay, that’s how the watch works, not what time it is but it should give you something to think about.

Regards,

DK

Many, many applications use this kind of method. In fact, in the PHP Application Design forum, anyone who doesn’t appears a little crazy :lol:

The main reason is that, as useful as regular expressions are, they have no intelligence. They can’t tell if a certain module exists, or redirect indefinite categories etc. PHP, however, has more parsing abilities - so requests are sent for PHP to handle. This is the C in MVC - Controller.

So requests such as:

/Content/View/Home

could use the content model, the ‘view’ template and use Home as the identifier.

Whereas a request like:

/Content/View/PHP/OOP/Dependency_Injection

Could use PHP as a category, OOP as a subcategory and dependency_injection as the article identifier.

More possibilities emerge, depending on your imagination. For example:

/Content/View/Home.pdf

could be parsed to render the home content as a PDF file rather than HTML. Of course, you’d need to write the PHP to do it, but it’s possible. Heck, if you’re talented you could even have:

/Content/View/Home.jpg

To generate the home page as an image.

You can also pass processing instructions if you wish.

Possibilities are much more open when parsing with PHP, and this works best when you pass everything to PHP, rather than just sections.

Hi Jake!

Yeah, that’s WP and many other CMS processes, as I said above. It does, however, require mod_rewrite to get any request which does not exist as a file or directory to the “brains of the outfit.”

Regards,

DK

Thanks for the friendly input Jake, it’s appreciated. Just to clarify, I don’t want it to rewrite anything that doesn’t have an extension - the aim is to rewrite anything that does have an extension, so that :

http://www.anydomainname.com/filename.php
becomes :
http://www.anydomainname.com/filename

or :

http://www.anydomainname.com/differentfilename.htm
becomes :
http://www.anydomainname.com/differentfilename

or :

http://www.anydomainname.com/otherfilename.html
becomes :
http://www.anydomainname.com/otherfilename

Any help appreciated.

Dez

You’re thinking about it backwards :slight_smile:

The mod_rewrite doesn’t rewrite differentfilename.htm to differentfilename - it recieves the input and has to generate a valid URL from it.

So, for example, say the URL that the user typed in is /filename, it’s Mod_Rewrite’s job to make the server see that as /filename.php - which is what the above code does :slight_smile:

Thanks Jake, I was sure that I read somewhere that it could be done ? ? :injured:

Cheers.

Dez.

It can!

What I’m saying is that you’re thinking about it backwards. Your initial question stated that you want a request like /contact to be sent to the file /contact.php.

That’s what my code does.

The way you’re currently thinking about it, you want /contact.php to be rewritten to /contact. It works the other way around - it takes a ‘fake’ request (/contact) and processes it into a real request (/contact.php) without the user/browser knowing any difference. All they know is that they went to /contact and it shows the contact form - which, on your server, is physically at /contact.php.

As mentioned originally, the request has always been for the .php part to be stripped off, but ok, bearing all of this in mind, what code are you suggesting for the .htaccess file please ?

Exactly what I gave before. Just try it :wink:

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

Say you have ‘/filename.php’ on the server. Go to /filename in the browser.

Yep, I did try it and it didn’t work as wanted, that’s why I asked again :slight_smile:

Just to clarify again, I don’t want to add any file extensions, I want to take them away, i.e., if there’s a file that says :
/filename.php on the server, it should show in the address bar as /filename in the browser.

:lol: Thats what the code does.

Ok, let me clarify. The code takes a request to /contact, for example, and tells the server to load /contact.php. So the user types in yoursite.com/contact and the server reads it as yoursite.com/contact.php.

This is stripping away the extension. The user doesn’t type the extension in, it is added (invisible to the user) before the request is processed.

The files in your server won’t change, just the way they’re accessed.

So, if you tried my code and went to /contact, it should be as if you had asked for /contact.php.

You say it didn’t work as you wanted - can you clarify?

This is where the confusion is coming in - I’ll copy your post to below, with it amended to show what is really wanted :

The code takes a request to /contact.php for example, and tells the server to load /contact.php. So the user types in yoursite.com/contact.php and the server serves it up as yoursite.com/contact

So the user types in yoursite.com/contact.php

What benefit would you possibly get from the user typing in the extension but there being no extension on the physical file on the server? Think about that carefully.

So, let me get this straight. If a user sees this in their address bar

yoursite.com/contact.php

Then the server loads the physical file

public_html/contact

If that’s actually what you want:

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

A typical request is that when /Contact is put in the URL, /Contact.php is loaded on the server, you seem to be requesting the opposite?

Ok, let’s try again :

You have a file called :

anyfilename.php

the website is :

so, the file is linked to from the site, as :

anydomain.com/anyfilename.php

What is clearly needed, is a way, so that when someone clicks on a link from one of the other pages in the site, to :

anydomain.com/anyfilename.php

it shows in the address bar, as :

anydomain.com/anyfilename

Why would you want to do that ? It’s easy,

anydomain.com/anyfilename

Looks a lot ‘prettier’ than :

anydomain.com/anyfilename.php

Ok, I see what you mean.

The code I gave you parses domain.com/filename and turns it, to the server, into domain.com/filename.php to the server. The browser still sees it as domain.com/filename.

So, using the initial code I gave you, simple link to only domain.com/filename and people will link to that.

If you want any request to domain.com/filename.php to be physically directed to domain.com/filename in the browser, that’s called a 301 redirect. So when a user goes to domain.com/filename.php, their browser will be redirected to domain.com/filename, but then behind the scenes all requests to domain.com/filename will be internally redirected to domain.com/filename.php.

The code I gave you initially does half of this job.

So to complete it, try:

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

Be careful not to create a loop.

Thanks Jake, your perseverance is appreciated and at least we’re making some headway now in the confusion arena :slight_smile:

Have you tried :

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

In your .htaccess file ?

It doesn’t work, it gives the usual ‘Internal Server Error’

Don’t just take my word for it - try it :slight_smile:

Agh, .htaccess isn’t my forte at all, as I’ve found out by trying this out! I’d certainly appreciate an answer from a guru on it!

So, here’s the code we had before:

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

I found that it shouldn’t be [301] but it should be [R=301]:

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

After a bit of playing around, I came up with:

RewriteEngine On
RewriteRule ^(.*)\\.php$ http://localhost/Sitepoint/Redirect/$1 [R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^.]+)$ $1.php [L]

Note that, here, localhost/Sitepoint/Redirect is the project folder. Turns out that you must use the full URL.

So here’s where the problem is. I made Contact.php as a test file, with just some text output to verify that I’m at the right page.

So I tried Contact.php and… infinite loop. I changed the above 301 redirect condition to redirect phps requests rather than php, and all works well! It’s just when the php extension is used, because one clause triggers the next to be true.

This is the last code I tried before giving up:

RewriteEngine On
RewriteRule ^(.*)\\.php$ http://localhost/Sitepoint/Redirect/$1 [R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^.]+)$ $1.php [L]

I thought the L would stop the infinite loop… but it doesn’t.

Does anyone have any ideas? To summarise the OP’s request:

  • If the REQUEST ends with .php, permanent redirect, stripping the extension
  • If the request has no extension, normal redirect to the .php extension, without the above being run.