I want to 'catch' an URL with .htaccess rewriterule. How can I add backslashes to the rewriterule?
For example:
http://www.example.com/page1 -> index.php?page=page1
http://www.example.com/page1/subpage1 -> index.php?page=page1/subpage1
As you can see, I want the backslash between 'page1' and 'subpage1' IN the rewriterule, because the path can be variable (more subpages).
I tried this:
RewriteRule ^(.*)$ /index.php?page=$1 [NC,L,QSA]
But then I get an Internal Server Error.
Thanks in advance!
You get an Internal Server Error because your rule introduces an infinite redirect loop.
Here is what you want
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /index.php?page=$1 [NC,L,QSA]
It checks if the url is not a physical folder/file before rewriting it internally
Related
I am trying to use Apache mod_rewrite. The first thing I did was to rewrite my url to an index.php file which was working fine. But I thought I should remove the trailing slash(es) too because I would prefer this to be handled by Apache instead of my PHP router.
Here's the whole content of my .htaccess file:
RewriteEngine on
# one of the attempts to remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.*)/+$
RewriteRule ^(.*)/+$ $1 [R=301,L]
# This is the rewriting to my index.php (working)
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?/$1 [L]
The issue:
I read several questions about trailing slash removal but I could not find a working answer for me:
For every answer I tried, I was able to reach my PHP router index.php (located in Phunder\public\) without trailing slash:
// Requested URL | No redirection
http://localhost/projects/Phunder/public/home | http://localhost/projects/Phunder/public/home
But when requesting the same page with a trailing slash I get redirected with the absolute path included:
// Requested URL | Wrong redirection
http://localhost/projects/Phunder/public/home/ | http://localhost/C:/xampp/htdocs/projects/Phunder/public/home
Other informations:
I always clear my cache while testing
Changing my last RewriteRule to RewriteRule ^(.*)/?$ index.php?/$1 [L] results in a 404 Error with URL having a trailing slash.
The actual wrong redirection results in a 403 Error
I'm a beginner with mod_rewrite I'm not always understanding what I try (sadly). Is there something I missed or misused ? What should I do to get the expected behaviour ?
Redirect rules need either absolute URL or a RewriteBase. You can extract full URI from %{REQUEST_URI} as well like this:
RewriteEngine on
# one of the attempts to remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^(.+)/+$
RewriteRule ^ %1 [R=301,NE,L]
# This is the rewriting to my index.php (working)
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?/$1 [L,QSA]
Im trying to both remove .php extensions. So for example "http://localhost/timetable/login" instead of "http://localhost/timetable/login.php"
But also have
"http://localhost/timetable/38/" instead of
"http://localhost/timetable/index.php?week=38"
Im able to get one or the other working but not both at the same time. Im assuming its because there is a conflict between them but Im not advanced enough to find it.
Here is my .htaccess file:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ $1.php [NC,L]
RewriteRule ^([0-9]+)$ index.php?week=$2
RewriteRule ^([0-9]+)/$ index.php?week=$2
If in the address bar I type "http://localhost/timetable/38" it brings me to "http://localhost/38/" and an Object not Found error.
Does anyone know what the problem is ?
UPDATE: I can now go to the page but
echo $_GET['week'];
Is returning empty result, so its ignroing the 40 in "http://localhost/timetable/40"
Instead of using separate rewrite rule for each input, you should consider routing all of them as a single string to some php file.
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?page=$1 [L,QSA]
In you php file, you can then separate the string as input and use them as required.
<?php
$inputs = explode('/', $_GET['page']);
You only have one capture group when you try to get the week. So it should be $1 instead of $2.
According to this test tool, the following should work:
RewriteRule ([0-9]+)/?$ index.php?week=$1
I would do something like this:
# rewrite if url ends with a number and possibly a slash
RewriteRule ([0-9]+)/?$ index.php?week=$1 [QSA,L]
# do not append .php if it already ends with .php, other add .php
RewriteCond %{REQUEST_URI} !\.php$
RewriteRule ^(.*)$ $1.php [QSA,L]
Using mod_rewrite, I want to look for all requested files in an assets directory, and otherwise fallback to index.php for API calls. This is my .htaccess.
RewriteEngine on
RewriteRule ^.+\.[^/]+$ assets/$1 [L]
RewriteRule .* index.php
Asset files are determined by whether the last last url segment has a file extension, which means a dot without following slashes. I already tested the regex at regexpal and it seems to work fine.
Unfortunately, all request result in a 500 Internal Server Error using these rewrite rules. I know that mod_rewrite is set up correctly, since omitting the second line works as expected.
Try these rules:
RewriteEngine on
# rewrite to assets/file if file exists in assets dir
RewriteCond %{DOCUMENT_ROOT}/assets/$1 -f
RewriteRule ^(.+?\.[^/]+)/?$ assets/$1 [L]
# otherwise rewrite to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule !^assets/ index.php [NC,L]
You need to add a condition to prevent the rewrite engine from looping:
RewriteEngine on
RewriteCond %{REQUEST_URI} !index\.php
RewriteRule ^.+\.[^/]+$ assets/$1 [L]
RewriteCond %{REQUEST_URI} !index\.php
RewriteRule .* index.php
The rewrite engine loops until the URI stops changing, and since .* matches index.php as well, it'll continue to loop through that rule until the internal recursion limit is reached you get a 500 error.
Additionally, you can add conditions that won't reroute existing files or directories:
RewriteEngine on
RewriteCond %{REQUEST_URI} !index\.php
RewriteRule ^.+\.[^/]+$ assets/$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php
I need to create rewrite in nginx as is done in my .htaccess and there are some lines which I don't completely understand.
DirectoryIndex index.php
RewriteEngine on
RewriteCond % !-f
RewriteRule ^(.*)/$ ?path=$1 [QSA,L]
Can someone explain it to me?
RewriteCond % !-f seems incorrect rule condition and is always evaluating to true.
This rule:
RewriteRule ^(.*)/$ ?path=$1 [QSA,L]
Is matching any URI with trailing slash and internally rewriting to /?path=uri-without-slash
So for ex: an URI /foo/ will be rewritten to /?path=foo
QSA - Query String Append
L = Last rule
Reference: Apache mod_rewrite Introduction
UPDATE: Change that incorrect condition to:
# request is not for a file
RewriteCond %{REQUEST_FILENAME} !-f
# request is not for a directory
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ ?path=$1 [QSA,L]
It means if the request isn't to a file, then rewrite everything before a trailing / into index.php?path= followed by what was previously matched.
It should be the last rule (L) and it should append the query string (QSA), as opposed to discarding it because of the replacement's query string.
I never want index.php to show up in my URL, even if the user inputs it. Is this possible?
This is variation whatever after several tries. I've come close a few times but this is where it's at for now.
RewriteEngine On
RewriteBase /sub-dir/
RewriteCond %{REQUEST_URI} index\.php$ //If URL ends in index.php
RewriteRule (.*)index\.php $1 //Somehow remove index.php from the url
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
Currently I have permalink set up where if the user enters domain.com/sub-dir/my-perma-lin/ it generates a string on the page based on my-perma-link to look like My Perma Link. What I'd like is if the user submits any URL ending in index.php it just removes that from the URL but leaves everything else as is.
domain.com/sub-dir/index.php --> domain.com/sub-dir/
domain.com/sub-dir/my-perma-link/index.php --> domain.com/sub-dir/my-perma-link
I've written quite a few rules in http://htaccess.madewithlove.be/ that work perfectly but when I upload it (to Dreamhost) nothing works.
This for example should work according to the the tester
RewriteEngine On
RewriteBase /sub-dir/
RewriteCond %{REQUEST_URI} \.php //Not needed but thought it would/should help
RewriteRule (.*)(index\.php)+ $1 [L,R=301,NC]
But it just removes everything after /sub-dir/
I'm either missing something super obvious or it's not possible ...
You need to add some flags to your rule:
RewriteEngine On
RewriteBase /sub-dir/
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(.*)index\.php(\?|\ )
RewriteRule ^ /%1 [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
You can ditch the RewriteCond %{REQUEST_URI} index\.php$ condition, as that's being checked by the regex in the RewriteRule. You need to include a $ at the end of the regex, and include the flags L to stop rewriting and R=301 to redirect.