htaccess mod rewrite - rewrite rule - regex

I would like to ask for help with the following: I have for example this rule mod_rewrite:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ $1.php [NC,L]
I want to rewrite the URL www.x.cz/word to www.x.cz/word.php
This works, but problem arise in that case, if the URL is for example www.x.cz/word/xxx (shortly after another slash is some other text string). Then there is error 500. How could i solve this problem? (I would like the server to return 404 or do the same as referring to the URL www.x.cz/word.php - as if there was not the another string).
Thank you all for your willingness.

You can tweak your regex like this:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^([^./]+) $1.php [L]
This will rewrite both /word/xxx and /word/ to /word.php

Related

.htaccess url rewrite for a specific url

I have a pattern like,
www.example.com/api.php/1,
how do I remove .php from this url,
currently I have this,
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
But it only works if I put www.example.com/api in browser,
not for www.example.com/api/1
not even for www.example.com/api/
You may use a rule like this:
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^([\w-]+)(/.*)?$ $1.php$2 [L]

htaccess RewriteCond: Why doesn't a server variable match itself?

Perhaps a better question would be, is there any way to use server variables in the matching string?
For example, I can't understand why this fails to match:
RewriteCond %{REQUEST_URI} %{REQUEST_URI}
First, two points.
I know this condition servers no purpose as is.
I know I have poor knowledge of both htaccess and regex.
What I want is to generically turn this URL www.example.com/dir/path/info into www.example.com/dir?foo=/path/info for bootstrapping.
I tried to accomplish this by removing the extra path info from the deepest actual directory in the URL. I was trying this code to test the premise:
RewriteEngine On
Options -Multiviews -Indexes +FollowSymLinks
RewriteBase /
DirectorySlash Off
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} (.+)%{PATH_INFO}
RewriteRule ^(.+?) index.php?dir=%1&path=%2 [L]
No luck. To troubleshoot I reduced it to this:
RewriteCond %{PATH_INFO} (.+)
RewriteRule ^(.+?) index.php?dir=%1 [L]
As expected the query returned foo='/path/info'
So I tried this which I thought would match no matter what:
RewriteCond %{PATH_INFO} %{PATH_INFO}
That failed so as a last attempt, I tried capturing the string:
RewriteCond %{PATH_INFO} (.+)
RewriteCond %{PATH_INFO} %1
That also failed to find a match which has me baffled. %1 should be the complete %{PATH_INFO} string. How could it not match itself???
I don't think it matters but I'm using XAMPP on Windows7 in FastCGI.
Rewrite pattern params only allow regex (tho Condpattern also has special flags for tests and comparisons):
RewriteCond TestString CondPattern
RewriteRule Pattern Substitution
Server variables like %{REQUEST_URI} can only be used in Teststring and Substitution. The following docs outline this usage:
http://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewritecond
http://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewriterule
If this will go in your main .htaccess, perhaps try:
RewriteCond %{REQUEST_URI} !index\.php$
RewriteRule ^([^/]+)/(.+)$ index.php?dir=/$1&path=/$2 [L]
Two more Example:
Sample1
RewriteBase /
RewriteRule ^(.+/)?index.php(/.+) index.php?dir=/$1&path=$2 [R,L]
Sample2
RewriteBase /
RewriteRule ^((.+/)?index.php)(/.+) $1?path=$3 [R,L]
Sample3
RewriteBase /
RewriteRule ^(.+/)?(.+\.php)(/.+) $1$2?foo=$3 [R,L]
these all do external rewrite so you can see result in the browser address. To revert to internal rewrite, just remove [R] flag
Ok, I found a way to accomplish this goal.
Basically I was trying to compare two server variables. htaccess won't do that. I wanted to extract part of a "pretty" url which points to an actual file or folder. The variable ${SCRIPT_URL} should do that, but it is either depreciated or not reliable. The work around is to put both variables in the test string and use a regex back reference to find the point of duplication.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{REQUEST_URI}%{PATH_INFO} (.*?)(/.+)\2$
RewriteRule ^(.*)$ %1.php?strappath=%2 [QSA,END]
In the above example %1 will be the uri of the file and %2 will be the remaining path after the URI, duplicating %{PATH_INFO}.
Follow with this rule for when there is no extra path info
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+?)$ $1.php [QSA,END]
If no .php file is found, I want the index of that directory and add the un-found file name to the pathinfo. This is a bit trickier.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php !-f
RewriteCond %{REQUEST_FILENAME} ^(.*)(/.+)$
RewriteCond %1 -d
RewriteCond %1/index.php -f
RewriteCond %{REQUEST_URI}%{PATH_INFO} ^(.*?)(/.+)\2$ [OR]
RewriteCond %{REQUEST_URI} ^(/.+)(/.+)?$
RewriteCond %1 ^(.*)(/.+)$
RewriteRule ^(.*)$ %1/index.php?strappath=%2%{PATH_INFO} [QSA,END]
The above section fails to catch urls that point directly to an existing folder with an index.php, so to catch those:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{REQUEST_FILENAME}/index.php -f
RewriteCond ^(.+)$ $1/index.php [QSA,END]
I doubt anyone ever finds this useful but I've seen variations of this question asked over and over with no working solution given.

configure htaccess to grab GET and not directory

I have url like this:
www.mydomain.com/index.php?param1=first&param2=second&param3=thirth
and I want to rewrite it to :
www.mydomain.com/first/second/third
.htaccess
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+)/([^/]+)$ index.php?param1=$1&param2=$2&param3=$3 [QSA,L]
Problem is, that I am getting error 404 (I think that server is looking for directory /first/second/third instead of letting index.php in root dir to GET parameters from URL). Am I wrong? Or how to deal with this problem?
Your regex is incorrect actually. You're using 3 back-reference vales in target but only 2 values are being captured.
You can use:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/?$ index.php?param1=$1&param2=$2&param3=$3 [QSA,L]

RewriteRule acting strange

I want URL like this: localhost/dir/images/pic1.jpg
to be rewriten to: localhost/dir/subdir/index.php?folder=images&picture=pic1.jpg
So i put really simple .htaccess file in localhost/dir/:
RewriteEngine On
RewriteRule ^(.*)/(.*)$ subdir/index.php?folder=$1&picture=$2 [L]
and expect to get folder='images' and picture='pic1.jpg' in localhost/dir/subdir/index.php but instead I have folder='subdir' and picture='index.php'
Strange thing is that when i modify .htaccess file to call index.php from the same directory (not from 'subdir') it works well:
RewriteEngine On
RewriteRule ^(.*)/(.*)$ index.php?folder=$1&picture=$2 [L]
I get folder='images' and picture='pic1.jpg' in localhost/dir/index.php script
That is happening because your rewrite rule is looping and matching target string subdir/index.php with the pattern .*/.*.
Use this condition to stop the loop:
RewriteEngine On
# If the request is not for a valid directory
RewriteCond %{REQUEST_FILENAME} !-d
# If the request is not for a valid file
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)/(.*)$ subdir/index.php?folder=$1&picture=$2 [L]

Rewrite URL if page exists in a sub folder

I was wondering if there is a way to achieve this sort of URL rewriting;
RewriteRule ^example-link-1?$ /blog/example-link-1 [NC,L]
RewriteRule ^example-link-2?$ /blog/example-link-2 [NC,L]
RewriteRule ^example-link-3?$ /blog/example-link-3 [NC,L]
RewriteRule ^example-link-4?$ /blog/example-link-4 [NC,L]
where you go directly to a link such as example.com/example-link-1 and you are actually shown content from example.com/blog/example-link-1, but without the need for a new rule per page i add. Is there a dynamic way to do this in the htaccess? ie;
IF exists('blog/'+pageURI)
THEN rewrite to 'blog/'+pageURI but keep the uri without 'blog/' in it.
Yes sure you can do:
RewriteRule ^(example-link-[1234])/?$ /blog/$1 [NC,L]
for above 4 rules. But in general you can do this:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}/blog/$1 -f
RewriteRule ^(.+?)/?$ /blog/$1 [NC,L]
This will rewrite to /blog/something if /blog/something exists while keeping the same URI without /blog/.