I am new to htaccess files, and I understand how to do basic rewrites of URLs such as removing index.php, extensions, etc. I am also able to use $_SERVER["PATH_INFO"] to work with anything trailing the file.
What I struggle with is how it would be possible to do this with a trailing faux-directory structure on another file other than the (not-shown) index.php. Lets say I have
domain.com/render.php/this
and I want it to read
domain.com/render/this
My workaround is currently to do all my logic in my index.php file, but I would like to break it up into several files, so that I would have index.php doing my home-page stuff, and render.php something completely different.
Thank you for you time.
It depends on your overall directory structure. Take a look at Apache .htaccess to hide both .php and .html extentions, for example.
If you already have /render/this configured to go to /render.php/this, and all you have to do is perform redirection the other way, then try this:
RewriteEngine On
RewriteCond %{REQUEST_URI} \b\.php\b
RewriteRule ^([^/.])\.php/(.*)$ $1/$2 [R]
(The \b part matches at a word boundary, as per pcrepattern(3), which is from the pcre library that both Apache httpd as well as nginx use in support of regular expressions.)
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
i am newbie of php
How to create simple remove .php extension with .htaccess page?
My aims is type this url http://site/Test
it can visit hello.php content, anyone know how to do that?? thx
I have one folder that call "Test", there are two file on "Test" Folder
Test/
-hello.php
-.htaccess
hello.php
<?php echo "Hello World"; ?>
.htaccess
RewriteEngine on
RewriteRule ^(.*)$ $1.php
finally, it is not successful
it display the following error message
**Internal Server Error**
The server encountered an internal error or misconfiguration and was unable to complete your request.
anyidea to solve this??? Thank you very much
My aims is type this url http://site/Test it can visit hello.php content, anyone know how to do that?
This isn't simply "file extension removal". If it was then /Test would serve the content from /Test.php. In your example, you are wanting to serve the contents of an entirely different file.
Rewriting the request with mod_rewrite
Since you are requesting a directory (/Test/) and wanting to serve a file from within that directory and the .htaccess file itself is actually located in that directory, you would need to write your RewriteRule like this:
RewriteRule ^$ hello.php [L]
In .htaccess (directory context), the RewriteRule pattern matches the URL-path relative to the location of the .htaccess file. So, in this case the URL-path we are matching against is simply an empty string, ie. ^$, since we are wanting to match /Test/<nothing>.
Likewise, when the susbtitution string (ie. hello.php) is relative (as it is here), it is relative to the location of the .htaccess file. So, in this case it effectively rewrites the request to /Test/hello.php (it's actually the absolute filesystem path, eg. /var/www/user/public_html/Test/hello.php - after the directory-prefix is added back).
Additional issues with this example
Since you are rewriting a request that would otherwise map to a physical directory there are a couple of potential issues you need to be aware of...
You should request the directory with a trailing slash, ie. /Test/, not /Test (as you stated in your initial example), otherwise mod_dir will issue a 301 redirect to append the slash before your rewrite is successful.
(There are ways to avoid the trailing slash, but this does increase the complexity and requires further manual rewrites.)
An additional complication occurs if there is a DirectoryIndex document in this subdirectory. eg. /Test/index.php. In this case mod_dir issues an internal subrequest to the DirectoryIndex document (eg. index.php) and this takes priority over your internal rewrite. (Your rewrite does still occur, but mod_dir "wins".) If this is the case then you can rewrite the DirectoryIndex document instead of an empty URL-path. For example:
RewriteRule ^index\.php$ hello.php [L]
This is perhaps counter-intuitive, as we are now rewriting the internal subrequest that mod_dir has issued in a later pass through the file.
You could handle both scenarios and make index.php optional. For example:
RewriteRule ^(index\.php)?$ hello.php [L]
RewriteRule ^(.*)$ $1.php
Your example would result in an internal rewrite loop (500 Internal Server Error response) since the pattern ^(.*)$ also matches the rewritten URL and it gets stuck in an endless loop. (The rewriting process doesn't just consist of a single pass through the file. The process repeats until the URL passes through unchanged.)
(Incidentally, this IS an extensionless URL type of rewrite, but it doesn't help you achieve what you stated in your example.)
There are various ways to prevent this "endless loop":
Use a more specific regex, that won't also match the rewritten URL. eg. a regex that excludes a dot such as ^([^.]+)$.
Use a RewriteCond (condition) directive that prevents the rule being triggered on the rewritten URL. eg. Exclude .php files or check that the request does not map to a file, etc.
Use the END flag on the RewriteRule to stop all further processing by the rewrite engine.
Alternative - change the DirectoryIndex
Instead of using mod_rewrite, as explained above, to internally rewrite the request, we could instead change the DirectoryIndex document.
This only works in this particular case where you are requesting a directory and wanting to serve a file from that directory (although strictly speaking the file could be anywhere).
The DirectoryIndex is the document that mod_dir will look for when requesting a directory (eg. /test/). By default, it looks for index.html (and often index.php) and possibly others. If a DirectoryIndex document is not found, you get a 403 Forbidden when requesting that directory (assuming auto-directory indexes are disabled).
For example, you could set the following:
DocumentIndex hello.php
And now when you request /Test/, mod_dir will serve hello.php in that directory.
However, this method (by itself) is limiting and potentially confusing for readers of your code (if changing the DirectoryIndex on a directory by directory basis). It is generally expected that the DirectoryIndex document(s) is consistent throughout your site.
How do I point a URL to a file so when I go to the URL it points to that file but doesn't change the URL. For example:
mydomain.com/orders/create should point to /myfiles/orders-create.php
then when I go to mydomain.com/orders/create it will display all the contents of orders-create.php.
Any ideas?
If you want to do it on the server-side you could edit the .htaccess file similar to this question's answer.
The main changes you're looking at are:
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule (.*)$ $1.php [NC]
This would let you create files without an extension and it would run force run the PHP interpreter.
Here's a good read for pretty URLs to find out more ways you could do this, and it'll explain more about what they actually are.
If you can change create-order.php, then you can make it so that it does not rely on relative paths. One way to do this is to create a bootstrap.php file that has all of the includes and then your "leaf" PHP files only have to find this bootstrap.php file.
Another option is to set the PHP path. If you change the include path to include the root of the directory, then when including files in create-order.php will look in the root and it will find them. You can set the include path in your PHP files or in the PHP configuration.
If you don't want or can't change create-order.php then one way to do this would be via the webserver. For example, in apache, you can use mod_rewrite to do just that, have a public URL actually invoke a specific local file. The rewrite configuration might look like this (example for just this one file):
RewriteEngine on
Options +FollowSymlinks
RewriteRule ^orders/create to create-order.php$ create-order.php [L]
or a catch-all rule with this (untested):
RewriteRule ^orders/(.*)$ $1?%{QUERY_STRING} [L]
I'm making a PHP project, which is online already and it's placed in:
www.mypage.com/dir/project.php
Most likely, it looks like:
www.mypage.com/dir/project.php?s=site&i=1&j=2&k=3
And i'm happy about that. However, now I'd like also to redirect it from
www.mypage.com/index.php
So, if you type:
www.mypage.com/index.php?s=something&i=fee
You will actually see this address, but executed script and its effect will be from:
www.mypage.com/dir/project.php?s=something&i=fee
I've tried so many .htaccess example files and yet no one worked as intended. Do you have any tips for me? Thank you very much.
With mod_rewrite, you translate an incoming request to a resource on the server. First make sure that the mod_rewrite is enabled on your server, and that you have the AllowOverride permission. You might need to restart Apache if you have not already done that.
After that you need to turn on rewriting using:
RewriteEngine on
Your .htaccess file is in your http root, so your rules will be relative to that. RewriteRule's first argument will match anything after the domain+prefix, and before the query string. In http://example.com/asdf?q=1, http://example.com is the domain, / is the prefix, asdf is what will be matched and q=1 can be matched through a condition using %{QUERY_STRING}
In your case we want to match index.php and rewrite it to dir/project.php. Since we don't change the query string, we don't have to do anything with it. The original query string will be appended to the rewritten request. It will look like this:
RewriteRule ^index\.php$ dir/project.php [L]
We escaped the dot in index.php, because it is a regex. A dot in a regex matches any character, and we only want it to match the literal dot. [L] is a flag that tells Apache to stop this round of rewriting. It is more often than not good to have that behind your rule, unless you have a specific rule why you want Apache to continue rewriting.
With that, your rule should now work as expected. More basic information about mod_rewrite can be found in the tag wiki for the mod_rewrite tag, as well as in the official documentation.
I want to map URL in my localhost XAMPP into custom files.
For example:
localhost/index.php --> d:\xampp\htdocs\index.php (default)
localhost/normal/data.php --> d:\xampp\htdocs\normal\data.php (default)
localhost/view/userinfo.php --> d:\xampp\htdocs\view.php?p=userinfo (custom)
localhost/view/welcome.php --> d:\xampp\htdocs\view.php?p=welcome (custom)
So, basically, all URL that goes into inside view path will be mapped to view.php files with the filename.php (minus the .php) as its query parameter. There's actually no physical folder view, and no physical files userinfo.php and welcome.php inside the folder.
The reason that I need to do this is that so I can pass all the pages that viewing data into an "application frame" that will wrap the page with header, menu, and footer, and I don't need to give header, menu, and footer call in each page. I might have the actual files userinfo.php that I can $include_once, or I might not (I can just generate it from within the view.php), but hey, that's one of the power of this kind of framework, right? And, if someday I need to change this structure, I can change it from just within one file (view.php), not all.
Can I do this in PHP and XAMPP? How? I've noticed that some website seems to used this practice (URL which have no actual files or even path at all), but when I try to read tutorial for it, I got confused.
URL mapping in PHP?
The accepted answer listed 3 links to learn about URL rewriting. Mostly they're written for Apache in Linux, and mostly they pull all the possible scenario and configuration that I got confused which one I really need with all those long documents and technical jargon. I need just the practical step of my specific problem, and then, I will be able to start from there to explore myself if I have more advanced needs. Please help.
if you do want to go down the mod rewrite route adding the following to an .htaccess file in the site root should do it. You will need to make sure mod rewrite is on for XAMPP and I can't help you there I'm afraid. As you can see it rewrites the url, not the windows filename - so it would work on any OS.
The ([a-z]*) means it will take any filename.php with lowercase letters and redirect to /view.php?p=$1 where the $1 will be replaced by filename.
the [L,R] (L means last rule so stop processing if any more are reached, and the R means redirect (it will change the url in the browser). Use P instead to reverse Proxy (the user will still see the url they requested but the server will serve the correct file) - This will require mod_proxy as well.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} ^view/
RewriteRule ^view/([a-z]*).php$ /view.php?p=$1 [L,R]
</IfModule>
XAMPP uses apache so the rewrites would work the same in Windows as they do in Linux. You could place a .htaccess in the site root directory with some rewrite rules.
However, using PHP
in d:\xampp\htdocs\view\userinfo.php you could include the line
<?php
header('Location: http://localhost/view.php?p=userinfo');
?>
But this must be before any thing is echoed to the screen (even whitespace).
You can use the Apache module mod_rewrite to edit requests before they hit PHP. You want to put something like the following in a .htaccess file in your htdocs directory.
RewriteEngine on
RewriteCond %{REQUEST_URI} ^view/
RewriteRule ^view/(.*)\.php.*$ view.php?p=$1 [L,QSA]
QSA means Query String Append. This means that if there are any GET parameters set on the original request they will be appended to the end of the new request too.
Note that this assumes that Apache is configured with AllowOverride enabled and the mod_rewrite module loaded.
I had this setup:
images
image1.jpg
image2.jpg
header.html
about
index.php
image3.jpg
But going to MyWebsite.com/About gave it an extra slash on the end. I decided to go with the solution of creating a file called about in my home directory:
images
image1.jpg
image2.jpg
header.html
about
aboutfiles
image3.jpg
The problem is that now this file won't let me use .php:
<?php include('header.html');?>
It's not showing the header file. What can I do to make this work?
Your problem is that your web server does not recognize the filename "about" as a php document. You have three options
Use a ".php" extension on your page document, such as "index.php" which will run your php scripting.
Install a solution such as mod_rewrite that will translate urls such as /about to a file actual like "about.php".
Adjust your servers mime-type for php documents. Learn more about MIME types here. https://developer.mozilla.org/en-US/docs/Properly_Configuring_Server_MIME_Types
The first solution is the simplest and easiest, in any document you use PHP, the extension should be .php
About the mywebsite.com/about issue, it's more an Apache configuration issue. You have to tell Apache that index.php should be an index file.
First, you can configure your Apache (or IIS) to use whatever Extensions to process PHP-Code.
You can define .ThisIsAPHPFile as valid extension, if you want.
However, Directorys are always reflected with a trailing /: www.example.com/dir1/ (Browsers not always showing the trailing /) while files have an extension: www.example.com/dir1/index.html.
So, from what i see, you want to use www.example.com/about but showing the about-FILE ?
Therefore you can use rewrite Engines of your Webserver. Either have a look at mod-rewrite (http://httpd.apache.org/docs/current/en/mod/mod_rewrite.html), when using Apache, or (one possibility) ISAPI-Rewrite (http://www.isapirewrite.com/docs/), when using IIS.
If you edit your virtualhost directive in your apache conf file, you can add the following:
DefaultType application/x-httpd-php
This will tell apache to send web paths that do not end in an extension to render using the php engine.
Therefore, /about would act as if it was about.php. Another potentially more useful approach is to name the file about.php on the server, and allow referencing it without the .php in the url. For this, you would configure it the opposite way.
RewriteEngine on
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^(([^/]+/)*[^.]+)$ /$1.php [L]