mod_rewrite into subdirectory file from folder - php

This could be probably duplicate due to unable to find that original even after checked the similar questions list of stackoverflow. Actually if user type myipaddress/gt then it should redirect to myipaddress/gt/gt.htm
I tried various mod_rewrites but still gets the 'gt' folder contents listed in browser. I gave the last try with below mod_rewrite.
Options +FollowSymlinks
RewriteEngine On
RewriteBase /
RewriteRule ^gt$ gt/gt.htm [NC,L]
But still the browser shows the contents of the 'gt' folder. What am I doing wrong?

You can use this rule in /gt/.htaccess:
Options +FollowSymlinks
RewriteEngine On
RewriteBase /gt/
RewriteRule ^/?$ gt.php [L]

Due to the fact that Apache sees gt as a directory, it treats it as such. However, that doesn't stop all rewriting for that particular path.
This is the basic process:
You navigate to /gt.
Apache sees that as an existing directory, and thus redirects to /gt/.
Your rule is ignored, because it doesn't contain the trailing slash.
This is why you still see the directory listing.
As such, you should change your rule to this:
RewriteRule ^gt/$ gt/gt.php [NC,L]
Alternatively, you can make use of DirectorySlash off and make the trailing slash optional, like so:
Options +FollowSymlinks
DirectorySlash off
RewriteEngine On
RewriteBase /
RewriteRule ^gt/?$ gt/gt.php [NC,L]
Doing either of the above allows you to have multiple rules of a similar nature in a single .htaccess file.

Related

RewriteRule in htaccess fails, but it could be my host

I read that Self Sabotage is Not asking for help so here I am.
So, I have a site...it's working great using WAMP. It's working great on my current host. But I need to switch to a new host and now it's failing. I figured it's a .htaccess issue but now I'm not sure. On my current host I have no .htaccess file and it works great. On my localhost server using WAMP I had the same thing as on my new host but I just disabled the .htaccess file, renaming it to BAD.htaccess, and the site still works great. This is why I think it's a server-side problem and I need some help. On my WAMP server in vhosts I disabled +FollowSymLinks for that "domain". On my current host I had no easy way to do that so it's just whatever they gave me, but it works.
I am currently with Ionos and have switched to GreenGeeks, who use cPanel. So far I haven't found a vhosts file to edit to remove +FollowSymLinks, if that is even the problem.
Maybe it can be accomplished with .htaccess and if so here is what I need to do. First my current .htaccess:
Options +FollowSymLinks
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^poems$ poems.php [R]
#RewriteRule ^poems/$ poems.php
RewriteRule ^collections$ collections/ [R]
RewriteRule ^collections/$ collections.php
RewriteRule ^poem$ poem/ [R]
RewriteRule ^poem/$ poem.php
RewriteRule ^poem/([0-9]+)/([a-zA-Z])$ poem.php?num=$1&poem=$2 [NC,L]
RewriteRule ^collection$ collection/ [R]
RewriteRule ^collection/$ collection.php
# RewriteRule ^poem/([0=9]+)$ indpoem.php?num=$1 [NC,L]
With the first two setups I can go to example.com/poems and it will redirect or rewrite to example.com/poems.php but still look like example.com/poems. Same with collections. On the new host those rewrite rules do rewrite it but the URL or URI shows example.com/poems.php, which I don't want per current SEO standards. Still, I could live with that.
However, when I get to the next level... example.com/poem/#/poem-name it fails on my new host. I do have a file called poem.php which it should rewrite to. In that file I use the following to get the # and name...
$URL = explode("/",$_SERVER['REQUEST_URI']);
So I don't have to do a _GET.
As you can see I tried to do a RewriteRule to change it from the first to example.com/poem?111&name, but that just seems silly because on WAMP I don't have to do anything. I could try rewriting it to the same URL again, but I have a feeling that won't work. And if it does it will probably be poem.php/#/name/
Any thoughts on a server config I'm missing when using cPanel. I even tried doing
Options -FollowSymLinks
in my .htaccess file with no success.
Any help would be appreciated. My WAMP and the new host have all the most recent versions of Apache and PHP.
There are a few issues here...
For the site to work without the .htaccess file at all (on your WAMP dev server and current host) then MultiViews (part of mod_negotiation) must have been enabled. It is MultiViews that "rewrites" /foo to /foo.php.
If MultiViews is enabled then your current .htaccess file is essentially overridden since the MultiViews content-negotiation occurs before your mod_rewrite directives are processed so your RewriteRule patterns fail to match.
MultiViews is disabled by default on Apache, it needs to be "explicitly" enabled. Unfortunately, some shared hosts do enable this in the server config (which causes more problems than it fixes - if you are not expecting it.)
On the new host those rewrite rules do rewrite it but the URL or URI shows example.com/poems.php.
RewriteRule ^poems$ poems.php [R]
Because MultiViews is disabled and your directives externally "redirect" /poems to /poems.php. There is no "rewrite" here. The R (redirect) flag triggers an external redirect.
RewriteRule ^poem$ poem/ [R]
RewriteRule ^poem/$ poem.php
However, for /poem you are redirecting to /poem/ (appending the trailing slash) but you have omitted the L flag so processing continues and the request is further rewritten to /poem.php. But because you have already triggered a Redirect, the request is "redirected" (not rewritten) to /poem.php, again exposing the .php.
Redirects should nearly always include the L flag. In fact, all your rules should include the L flag for optimisation and to prevent accidental conflicts.
Why are you redirecting to append the trailing slash (as if this is the preferred canonical URL)? You make no mention of this in your question text and only one of your examples includes a trailing slash on the URL as far as I can see? So, what is the preferred/canonical URL? What URL are you linking to? Incidentally, MultiViews will not append a trailing slash - so either this redirect is not required, or your site is not actually "working great" on WAMP / current host without the .htaccess file. (?) (Personally, I would not use a trailing slash.)
RewriteRule ^poem/([0-9]+)/([a-zA-Z])$ poem.php?num=$1&poem=$2 [NC,L]
:
$URL = explode("/",$_SERVER['REQUEST_URI']);
Your PHP script parses the requested URL-path (ie. $_SERVER['REQUEST_URI']), it is not referencing the query string. However, the above RewriteRule directive is rewriting to a query string - which would seem to be entirely superfluous ("silly" - as you suggest). Because you are not using the query string in your PHP script, the request still "works" when using MultiViews.
According to your PHP script, you simply need to rewrite the request to poem.php, without a query string. (Which is what MultiViews does. Although, strictly speaking, MultiViews rewrites /poem/123/name to /poem.php/123/name - passing the additional URL-path as path-info to poem.php.)
This regex only matches a single letter in the 3rd (name) path segment so it will fail to match a requested URL of the form /poem/123/name, so the request is not rewritten to poem.php and the request fails (with a 404 I suspect).
This regex also does not match a trailing slash. (So, is the trailing slash really canonical?)
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
These conditions are entirely superfluous where you have put them. RewriteCond directives only apply to the first RewriteRule directive that follows.
Options -FollowSymLinks
You need FollowSymLinks for mod_rewrite to work. Don't try to disable this. FollowSymLinks is actually the default Apache setting, so you only need to explicitly enable it (ie. +FollowSymLinks) in .htaccess if it has been disabled in the server config.
Solution
Personally, I would not use a trailing slash on the canonical URLs. (This is in line with most of your examples and the regex used in your rule.)
So, bringing the above points together:
Options +FollowSymLinks -MultiViews
RewriteEngine on
# Canonical redirect to remove trailing slash (from non-directories)
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*)/$ /$1 [R,L]
# Internal rewrites to ".php"
RewriteRule ^poems$ poems.php [L]
RewriteRule ^collections$ collections.php [L]
RewriteRule ^poem(/\d+/[\w-]+)?$ poem.php [L]
RewriteRule ^collection$ collection.php [L]
On the other hand, if the canonical URL should include a trailing slash then change it accordingly:
Options +FollowSymLinks -MultiViews
RewriteEngine on
# Canonical redirect to append trailing slash to "all" URLs
RewriteRule !/$ ${REQUEST_URI}/ [R,L]
# Internal rewrites to ".php"
RewriteRule ^poems/$ poems.php [L]
RewriteRule ^collections/$ collections.php [L]
RewriteRule ^poem/(\d+/[\w-]+/)?$ poem.php [L]
RewriteRule ^collection/$ collection.php [L]
If you have many such URLs/pages then you can make this entirely "generic" without having to explicitly name each URL/file. ie. "poems", "collections", etc.
Alternatively, you simply enable MultiViews and let mod_negotiation rewrite the URLs. However, you will not be able to canonicalise the trailing slash or validate the request before rewriting and MultiViews applies to everything, not just your .php files, so potentially creates duplicate content. If you need to do any specific rewriting, such are rewriting the query string then MultiViews is likely to conflict.
Options +MultiViews

RewriteRule - discard trailing slash

I have a PHP project with a .htaccess file:
Options FollowSymLinks
RewriteEngine On
RewriteBase "/blog/"
RewriteRule "^([^.?/]+)/?$" "index.php?page=$1" [END,QSA]
I have a very strange problem with url localhost/blog/administration. It's definitely not caused by a PHP file, because happens even with empty source code.
My problem is: when I type localhost/blog/administration, the URL in address bar is changed to localhost/blog/administration/?page=administration. This doesn't happen after typing localhost/blog/administration/ (with trailing slash) in the address bar.
What's stranger - given problem happens only with administration URL but not with, for example, home.
What could be the cause?
DISCLAIMER: Said problem happens even when I use fresh browser (no cache) and index.php with exit; at the beggining...
Trailing slash is added at end of URI if that points to a real directory by Apache's mod_dir module for security reasons otherwise it may result in directory listing of your directory.
It is advisable to have index.php inside your /blog/administration/ directory to prevent this behavior. Otherwise you can have a separate rule to add trailing rule before final rule:
Options FollowSymLinks -Indxes
RewriteEngine On
RewriteBase /blog/
# add a trailing slash to directories
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule [^/]$ %{REQUEST_URI}/ [L,R=301]
RewriteRule ^([^./]+)/?$ index.php?page=$1 [END,QSA]
Also take note of -Indxes in options line above to disable directory listing.

.htaccess Multiple Rewrite Rules with Extensions

So, I'm not very good with Apache config or .htaccess rewrite rules.... And I'm trying to do some modifications to how my localhost server works...
What I'm trying to do is return a 404 error on any request with the extension '.php'. If the uri does not have an extension, then route the request to 'ini.php'. If the uri contains an extension that isn't of '.php', then it should just follow normal procedures in fetching the file.
What I have now:
Rewrite Engine on
DirectorySlash off
RewriteCond $1 (.php)
RewriteRule ^(.*)$ - [L,NC,R=404]
RewriteCond $1 !^(.+)
RewriteRule ^(.*)$ ini.php [L,NC]
My logic is that if it's not a .php, and it doesn't have an extension, then route it to ini.php. Otherwise it should route normally.
Right now it looks like the .php rule is working in returning 404 errors.. However, if a request for a path without an extension is received, it tries to route to ini.php and hits a 404 page. Is it maybe processing like the second rule and then hitting the first rule?
Anyways, can someone help me sort it out and give me some guidance on it? I tried google and a bunch of different solutions, but I couldn't find something that worked for this situation...
UPDATE:
I changed the code to the following and added ini.php to the DirectoryIndex settings in httpd:
RewriteEngine on
RewriteCond %{REQUEST_URI} (\.[php^\\/]+)$
RewriteRule ^(.*)$ - [L,NC,R=404]
RewriteCond %{REQUEST_URI} !(\.[^\\/]+)$
RewriteRule ^.+$ / [L,NC]
Can you check if it looks alright?
I've turned on DirectorySlash again. Thanks.
This will do it:
RewrieEngine on
# 404 any URL ending .php (ignoring any query string)
RewriteRule ^(.+)\.php$ - [R=404,L,NC]
# Rewrite any URL that does not contain a dot (.), and therefore has no extension, to ini.php
RewriteRule ^([^.]*)$ ini.php [END]
I am assuming it will go in a .htaccess file from what you said. It would need changing to go in the main config.
Don't turn DirectorySlash off. It's a security risk to do so (see the link) and it only applies to existing directories anyway so is not causing any problems for you. There is no space in RewriteEngine.

htaccess rewrite ".../pages/about.php" to ".../about"

I've searched and found a lot of questions on this site and elsewhere that are very similar, but I've tried implementing and modifying all the suggestions I've found and none of it works. I realize this is a very basic question an I am extremely frustrated because nothing I'm trying is working.
With that having been said... I am trying to organize my content pages within kurtiskronk.com/pages/... (e.g. kurtiskronk.com/pages/about.php)
What I want to do is make it so that I can simply link to kurtiskronk.com/about ... So how do I go about stripping "pages/" and ".php"? I don't have a ton of content pages, so it's not a big deal if I have to specify for each page, though something dynamic would be handy.
NOTES: I am using Rackspace Cloud hosting, and WordPress is installed in /blog. My phpinfo() can be seen at http://kurtiskronk.com/pages/phpinfo.php
This is my existing .htaccess file (in the root)
php_value register_globals "on"
Options +FollowSymLinks
RewriteEngine On
#301 redirect to domain without 'www.'
RewriteCond %{HTTP_HOST} ^www\.kurtiskronk\.com$ [NC]
RewriteRule ^(.*)$ http://kurtiskronk.com/$1 [R=301,NC]
RewriteBase /
RewriteCond %{ENV:PHP_DOCUMENT_ROOT}/pages/$1 -f
RewriteRule ^(.*)$ pages/$1 [L]
RewriteCond %{ENV:PHP_DOCUMENT_ROOT}/pages/$1.php -f
RewriteRule ^(.*)$ pages/$1.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^blog/ blog/index.php [L]
# PHP - MAIL
php_value mail.force_extra_parameters -kurtis#kurtiskronk.com
I tested and the rewrite works with the line below (/about as URL brings up file /pages/about.php), but then the homepage gives a 500 Internal Server Error:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /pages/$1.php [L]
So I'm still sort of in the same boat as before, and as a follow-up, possibly more difficult question, if you go to http://kurtiskronk.com/weddings I am using SlideShowPro (flash) w/ SSP Director (self-hosted) as the back-end for it. When it pulls up a new image, it adds the following after /weddings ... "#id=album-152&num=content-9698"
There are four sections of the portfolio
# Homepage (kurtiskronk.com) id=album-148 ($id is constant for this section)
# Weddings (/weddings) id=album-152 ($id is constant for this section)
# Portraits (/portraits) id=album-151 ($id is constant for this section)
# Commercial (/commercial) id=album-150 ($id is constant for this section)
Assuming we get kurtiskronk.com/weddings to rewrite successfully without breaking anything, how would we make the total URL something cleaner kurtiskronk.com/weddings/9698 since the $num is the only thing that will change within a given section?
Kurtis, thanks for the extra information. It's a lot easier to give a specific answer to this.
My first comment is that you need to separate out in your thinking URI space -- that is what URIs you want your users to type into their browser -- and filesystem space -- what physical files you want to map to. Some of your mappings are URI->URI and some are URI->FS
For example you want to issue a permanent redirect of www.kurtiskronk.com/* to kurtiskronk.com/*. Assuming that you only server the base and www subdomains from this tree, then this cond/rule pair should come first, so that you can assume that all other rules only refer to kurtiskronk.com.
Next, you need to review the RewiteBase documentation. .htaccess files are processed in what Apache calls a Per-Directory context and this directive tells the rewrite engine what to assume as the URI base which got to this directory and .htaccess file. From what I gather, your blog is installed in docroot/blog (in the filesystem, and that you want to get to directory by typing in http://kurtiskronk.com/blog/ but that this .htaccess file is for the root folder -- that is the base should be (this goes before the www mapping rule)
DirectorySlash On
DirectoryIndex index.php
RewriteBase /
#301 redirect to domain without 'www.'
RewriteCond %{HTTP_HOST} ^www\.kurtiskronk\.com$ [NC]
RewriteRule ^(.*)$ http://kurtiskronk.com/$1 [R=301,NC]
You can add some field dumps look for REDIRECT_* in the Server or Environment table in the phpinfo O/P to see if these are sensible. For example:
RewriteWrite ^(.*)$ - \
[E=TESTDR:%{DOCUMENT_ROOT}/pages/$1.php,E=TESTPDR:%{DOCUMENT_ROOT}/pages/$1.php]
Your next rule is that if the file exists in the subdirectory pages then use it:
RewriteCond %{DOCUMENT_ROOT}/pages/$1 -f
RewriteRule ^(.*)$ pages/$1 [NS,L]
[Note that some shared service sites don't set up DOCUMENT_ROOT properly for the rewrite engine so you may need to run a variableinfo script (<?php phpinfo(INFO_ENVIRONMENT | INFO_VARIABLES); to see if it sets up alternatives. On your site you have to use %{ENV:PHP_DOCUMENT_ROOT} instead.]
Your next rule is that if the file exists, but with the extension .php in the subdirectory pages then use it:
RewriteCond %{DOCUMENT_ROOT}/pages/$1.php -f
RewriteRule ^(.*)$ pages/$1.php [NS,L]
Now redirect any blog references to the blog subdirectory unless the URI maps to a real file (e.g. the blog stylesheets and your uploads.)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^blog/ blog/index.php [L]
A complication here is that WP may be using a poorly documented Apache feature call Path Info that is a script can act as a pseudo directory so http://kurtiskronk.com/blog/tag/downtown/ is redirected to docroot/blog/index.php/tag/downtown/ which is then executed by `docroot/blog/index.php using /tag/downtown/ as the PATH_INFO. But this is one for Wordpress experts to comment on. If this last rule doesn't work then try:
RewriteRule ^blog/(.*) blog/index.php/$1 [L]
PS. I like your site. I wish I was that young again :(
Postscript
When you say "it doesn't work", what doesn't with this .htaccess?
http://kurtiskronk.com/phpinfo,
http://kurtiskronk.com/phpinfo.php,
http://kurtiskronk.comblog/tag/downtown/
It's just that these rules work for these tests (with domain swapped) on mine. (One way is to move or copy the above variableinfo.php to the various subdirectories. If necessary temporarily rename the index.php to index.php.keep, say, and copy the variableinfo.php to the index.php file. You can now enter the various URI test patterns and see what is happening. Look for the REDIRECT_* fields in the phpinfo output, and the SCRIPT_NAME will tell you which is being executed. You can add more {E=...] flags to examine the various pattern results. (Remember that these only get assigned if the rule is a match.
Lastly note the changes above especially the additional NS flags. For some reason mod_rewrite was going directly into a subquery which was resulting in redirect: being dumped into the file pattern. I've had a look at the Apache code and this is a internal botch to flag that further redirection needs to take place (which then replaces this or backs out). However this open bug indicates that this backout can be missed in sub-queries and maybe that's what is happening here. Certainly adding the NS flas cured the problem on my test environment.
PS. Note the added explicit DirectoryIndex directive and also that whilst http://kurtiskronk.com will run the root index.php, the explicit /index.php version will run the one in pages, because that's what your rules say.
Here is a simple solution. You can use it apache conf file(s) or in .htaccess (easier to set up when you're trying).
mod_rewrite has to be enabled.
For example, use .htaccess in your DocumentRoot with:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /pages/$1.php [L]
It will redirect /about to /pages/about.php, and any other page.
The "RewriteCond" part is to authorize access to an existing file (eg: if you had an "about" file at the root of your site, then it will be served, instead of redirecting to /pages/about.php).
Options +FollowSymLinks
RewriteEngine On
RewriteRule /([0-9]+)$ /pages/$1.php [L]
Put something like this in your .htaccess file. I guess that is what you want.
Juest a redirect from a simple url to a longer url.

Placing .htaccess file in var/www folder messes my website up

I am playing with mod_rewrite now, and have successfully enabled it.
However, I need to put a htaccess file inside var/www/ in order to achieve what I want, which is to rename Urls simply...
When I place it my website becomes very strange and nothing basically works...
Is there any code I need to put into the htaccess file in order for things to act normally?
Here is the htaccess file I have so far:
Options +FollowSymLinks
Options +Indexes
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/ad\.php
RewriteRule ^(.*)$ ad.php?ad_id=$1 [L]
My DocumentRoot is also set to var/www/ and my entire website root is there... (index.html etc etc)...
What am I missing about the htaccess?
If you need more input let me know...
I suspect that none of your css files, js or images are loaded. Furthermore, none of your links work either. If so, the problem could be in the RewriteRule cause basically that rule is telling apache to pass all requests to ad.php
You need to fine tune your RewriteRule, so that only the ad links are being affected by the rule.
First, by expanding the RewriteRule like this:
Options +FollowSymLinks
Options +Indexes
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_URI} !^/ad\.php
RewriteRule ^(.*)$ ad.php?ad_id=$1 [L]
These 3 lines that I've added are telling apache to apply the rule only if the requested filename is not a directory, an existing file or a symbolic link - this should take care of the static content, such as the css and images. If your other pages where you're links are pointing at, are also physically on the HDD of the server (plain html or php files), should start working again.
But, as I already said on this question of yours (Little mod_rewrite problem) you need to fine tune that rule, so that only ads are being met by the rule and nothing else.
This isn't a complete answer but it will give your more information that can help you.
You can put options on the same line Options +FollowSymLinks -Indexes
Not all hosts allow .htaccess, or not all .htaccess commands. This can cause problems and pages not to work.
Try commenting out everything (using # sign in front of each line), then, starting at the top, uncomment until you find the problem line.

Categories