I want this example URL:
example.com/folder/phpfile
To redirect to:
example.com/folder/phpfile.php
It works perfectly, but I also want to be able to execute the index.php file of any folder just by this URL
http://example.com/folder
or
http://example.com/folder/
or maybe
example.com/folder/subfolder
But I don't know how, I'm using RewriteCond %{REQUEST_FILENAME}, as I understand this is a condition to know if the requested file name is either a file or a folder. But I can't make it work.
This is my current .htaccess:
Options -Indexes
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([a-zA-Z0-9-_])$ $1.php [NC,L]
You can meet your requirement using this code in root .htaccess:
# by default load index.php from a path
DirectoryIndex index.php
# make sure trailing slash is present for directories
DirectorySlash On
RewriteEngine On
# load /dir/file.php if request is for /dir/file
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1\.php -f [NC]
RewriteRule ^(.+?)/?$ /$1.php [L]
here is one more thing that we can do to further clean our URLs, i.e., hiding the entry script index.php in the URL. This requires us to configure the Web server as well as the urlManager application component.
We first need to configure the Web server so that a URL without the entry script can still be handled by the entry script. For Apache HTTP server, this can be done by turning on the URL rewriting engine and specifying some rewriting rules. We can create the file /wwwroot/blog/.htaccess with the following content. Note that the same content can also be put in the Apache configuration file within the Directory element for /wwwroot/blog.
RewriteEngine on
# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# otherwise forward it to index.php
RewriteRule . index.php
We then configure the showScriptName property of the urlManager component to be false.
Now if we call $this->createUrl('post/read',array('id'=>100)), we would obtain the URL /post/100. More importantly, this URL can be properly recognized by our Web application.
Related
For a website, I want to set up a redirection using .htaccess.
My folder structure is something like
/
/folderA/
/folderB/
/index/
where folderA and B and index contain subfolders and files. Now, I want to rewrite all requests for the root / and for all not existing folders and files to index. It should be masked. It seems to me like an easy task but I cannot get it to work. So far, I tried
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) /index/$1 [L]
The redirection somehow works but it does not work when I call the root http://example.org/ directly.
Is the root also seen as valid directory or excluded in the RewriteCond checks? Any ideas how to realize that?
Yes, the root is also a directory. You will need to add another rule to rewrite the root only. For example:
RewriteRule ^$ /index/ [L]
And since the root is a directory, you might as well exclude this from the first rule. ie. Change (.*) to (.+).
HOWEVER, your existing rule will result in a rewrite-loop (500 error) if the URL you are rewriting to in /index/... does not exist either*1. eg. If you request /foo, it rewrites to /index/foo and if /index/foo does not exist then it rewrites to /index/index/foo to /index/index/index/foo etc.
You will need to add an additional condition (or use a negative lookahead) to prevent requests to /index/... itself being rewritten.
(*1 Unless you have another .htaccess file in the /index subdirectory that contains mod_rewrite directives and you have not enabled mod_rewrite inheritance.)
For example:
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/index/
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.+) /index/$1 [L]
RewriteRule ^$ /index/ [L]
With some modifications is possible to hide extension of the web files like http://www.abc.com/asd/zxc/ against to zxc.php but the thing I wanna do is remove file names completely from the url like http://www.abc.com/asd/ it doesn't matter user where to go in web site but the url should be stay static all the time.
Is it possible to do that with .htaccess?
I already tried this but it didn't work:
RewriteOptions inherit
RewriteEngine On # enables url rewriting
RewriteCond %{REQUEST_FILENAME} !-d # if requested uri is not directory (!-d)
RewriteCond %{REQUEST_FILENAME}\.php -f # and if there is a file named URI+'.php' (-f)
RewriteRule ^(.*)$ $1.php # then if there is any thing in uri then rewrite it as uri+'.php'
I'm not sure, but isn't the problem that you would like to check so the supplied url fragment is not a directory and not a file, and if that's the case, append .php to the fragment?
Something like this might work:
RewriteEngine On # enable mod_rewrite
RewriteBase / # set the 'base' for the rewrite
# you might need to modify this one.
RewriteCond %{REQUEST_FILENAME} !-f # not a file
RewriteCond %{REQUEST_FILENAME} !-d # not a directory
RewriteRule ^(.*)$ /$1\.php [L] # append '.php' to the path
#
If you have the following directory structure, and of course the .htaccess file in the root of the structure:
/code/test.php
/index.php
You should be able to access the test.php and index.php files by using the following urls:
http://example.com/code/test/
and
http://example.com/index/
The example.com needs to be change to a valid domain or ip address.
I have a website running at localhost/pm and the RewriteBase is correctly set to /pm/. There is a link tag in my document: <link ... href="themes/default/css/default.css">.
When the url is localhost/pm or localhost/pm/foo the CSS works all right. When there are more slashes in the URL, however, like localhost/pm/foo/bar the relative URL if the stylesheet changes to foo/themes/default/css/default.css.
How do I get this to work without having to put some sort of PHP path resolution in the link tag?
# invoke rewrite engine
RewriteEngine On
RewriteBase /pm/
# Protect application and system files from being viewed
RewriteRule ^(?:system)\b.* index.php/$0 [L]
# Allow any files or directories that exist to be displayed directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Rewrite all other URLs to index.php/URL
RewriteRule .* index.php/$0 [PT]
EDIT:
Basically what I need now is this:
If request contains folder name /themes/ scrap everything that is before /themes/ and rewrite the rest to /pm/themes/...
I tried it like this: RewriteRule ^.*(/themes/.*)$ /pm/themes/$1 but I get an internal server error. Why?
If I do it like this: RewriteRule ^.*(/themes/.*)$ /pm/themes/ (ie. just remove $1 from the end) and use the URL http://localhost/pm/foo/themes/foo/ the resulting physical location is http://localhost/pm/themes which is what is expected too, which in turn means that at least my regex is correct. What am I missing?
The RewriteRule is almost correct
RewriteRule ^.*(/themes/.*)$ /pm/themes/$1
This rewrites http://localhost/pm/foo/themes/default/css/default.css to http://localhost/pm/themes/themes/default/css/default.css, which is one themes too much. Use this instead
RewriteRule /themes/(.*)$ /pm/themes/$1 [L]
But now you have an endless rewrite loop, because /pm/themes/.. is rewritten again and again. To prevent this, you need a RewriteCond excluding /pm/themes
RewriteCond %{REQUEST_URI} !^/pm/themes/
RewriteRule /themes/(.*)$ /pm/themes/$1 [L]
Now the request is rewritten only once and you're done.
You probably need to add the following lines before your RewriteRule:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
It will only evaluate your rewrite rule if the requested file or directory doesn't exist.
You should post your .htaccess file so we can offer better advice
Situation:
I'm moving a website from a production environment to a test environment.
The test environment url is similar to http://192.168.1.100/~username/
There are thousands of files which use the following within the html
<img src='/images/image.jpg' />
Since the request is going to root http://192.168.1.100/ the files are 404.
Rather than finding and replacing all of html I'd assume that there is an easy way to fix it with mod_rewrite via .htaccess.
I've tried using the following
RewriteCond %{REQUEST_URI} !^/~username/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /~username/$1
But did not work as expected.
Thanks in advance.
UPDATE
The development environment resides within cpanel/whm. So when the username is removed from the requested url, it now belongs to the root users. So, my question now: How do I update the .htaccess file for the root user to mod_rewrite back to the ~username?
If you remove
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
it appears to work as expected, because any request to the right url will not be rewritten.
you might want to add [L] as a flag to signify it's the last rewrite rule, like so:
RewriteCond %{REQUEST_URI} !^/~username/
RewriteRule ^(.*)$ /~username/$1 [L]
I have the following in my .htaccess - the clean url's declaration and the https redirect both work fine individually but put together are causing the continuous redirect error (this server is redirecting in a way which will never complete).
Here is my .htacess:
RewriteEngine on
# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# otherwise forward it to index.php
RewriteRule . index.php
# force to use https
#RewriteCond %{HTTPS} !=on
#RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Any idea how i can resolve this?
Thank you
Hope I am not late as I stumbled through your same problem and figured out the conflict just a day ago.
Write the following in your .htaccess file:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php
The first rule will automatically redirect any HTTP requests to HTTPS and (through the crucial [L] tag) stop other substitutions which will mess up the page (specifically, images and CSS stylesheets would not be served).
The second one is the Yii suggested way to check whether a particular URL corresponds to a real file or directory and, if not, to forward the request to index.php (the bootstrap file for the Web application). (The rules in the application's configuration file should do the rest, then).