I creating a mod_rewrite rule like this
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME}\.php !-f
RewriteRule ^(.*)$ ./page.php?key=$1
it works! But I want to do this:
www.site.com/var1.var2.var3
(variables are separated by point) separated by - or _ no problems, but if I put the point does not work why?
I assume that you are trying a rule like this
RewriteRule ^(.*).(.*).(.*)$ ./page.php?key=$1&key2=$2&key3=$3
but you should remember to escape the dots which you want to interpret as periods. There are many ways to right this but here is a simple way if you are new to .htaccess files:
RewriteEngine On
RewriteBase /
# Skip existing files or directories
RewriteCond %{SCRIPT_FILENAME} -d [OR]
RewriteCond %{SCRIPT_FILENAME} -f
RewriteRule ^ - [L]
# Add default PHP extension when appropriate
RewriteCond %{SCRIPT_FILENAME}.php -f
RewriteRule ^.* $0.php [L]
# Pick up 1,2 and 3 parameter versions
RewriteRule ^(.*?)\.^(.*?)\.(.*)$ page.php?key=$1&key2=$2&key3=$3 [QSA,L]
RewriteRule ^(.*?)\.(.*?)$ page.php?key=$11&key2=$2 [QSA,L]
RewriteRule ^(.*?)\.$ page.php?key=$1 [QSA,L]
Note:
the first rule uses "^" as a pattern which always matches and the "-" means don't replace it.
the second uses $0 which means the entire match pattern
rule 3-5 match the 3,2,1 parameter options
the [L] (last) flag means skip the rest of the rules
you will need the QSA flag is you use other parameters.
The reason for splitting the existance check in to is that you need to handle files such as CSS and image (PNG/GIF/PNG) files as well as your application syntax.
Related
I'm wondering if there's a way to load text string into my htaccess file. I don't want to manually type it in the file.
Here's what I already have
<IfModule mod_rewrite.c>
RewriteBase /file_name.txt/
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} ^gwcgroup\.co.uk [OR]
RewriteCond %{HTTP_HOST} ^www\.gwcgroup\.co.uk$
RewriteRule .* https://gwcgroup.co.uk%{REQUEST_URI} [R=301,L]
RewriteCond %{HTTPS} =on
RewriteCond %{HTTP_HOST} ^www\.gwcgroup\.co.uk$
RewriteRule .* https://gwcgroup.co.uk%{REQUEST_URI} [R=301,L]
RewriteCond %{REQUEST_URI} ^system.*
RewriteRule ^(.*)$ /index.php?/$1 [L]
RewriteCond %{REQUEST_URI} ^application.*
RewriteRule ^(.*)$ /index.php?/$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]
Any suggestion would be appreciated. thanks in advance
This feels like an X-Y problem.
(Warning... lots of "however"s follow...)
Yes, you can read a text file into a .htaccess file using mod_rewrite and an Apache expression (Apache 2.4). However, you can't read it directly into the RewriteBase directive as you are implying. However, you can read the file and store it in an environment variable and effectively use it in order to simulate what the RewriteBase directive does.
However, in the .htaccess file you've posted you are only making use of RewriteBase in the very last rule (on the very last line). So, you only need to target that one rule (no need for an environment variable).
However, there are other ways to effectively calculate the RewriteBase (or rather calculate the root URL-path and store this in an env var), depending on what you are trying to do. So, you may not need to do this at all.
There are other errors/inconsistencies in the file you posted that also make me question whether this is really what you should be doing.
Anyway, focusing on the last rule (which is the only place in your file that RewriteBase applies)....
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]
To read from the external file file_name.txt (in the document root) and use the contents of this file as the base URL-path in the substitution string in the last RewriteRule directive then you could do something like this:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond expr "file('%{DOCUMENT_ROOT}/file_name.txt') =~ m#^(/.*)#"
RewriteRule (.*) %1index.php?/$1 [L]
The %1 backreference (to the capturing group in the preceding CondPattern) holds the contents of the first line of the text file (since the dot does not match newlines). Although, this regex is rather generic (it matches everything after an initial slash - to the end of the line) - you may want to make this more restrictive, to ensure that it only matches a valid URL-path you are expecting.
If file_name.txt does not exist (or cannot be read) then a non-fatal rewrite:error occurs (check your error log) and the rule simply fails.
And file_name.txt contains a single line of the form:
/path/to/dir/
Thanks, guys. I found a solution. I stored my script in a variable and dynamically create and update the htaccess file each time I need to.
Here's my working code
$htaccess = fopen("./.htaccess", "w") or die("Unable to open file!");
fwrite($htaccess, $ht_input);
fclose($htaccess);
I know this problem is asked before, but i don't find anything
i try to pass 3 variable in htaccess the url change normaly but i cant't get the third variable
this is my htaccess file
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-z]+)\/?$ index.php?r=$1 [NC]
RewriteRule ^([a-z]+)/([a-z]+) index.php?r=$1&s=$2 [L]
RewriteRule ^([a-z]+)/([0-9]+) index.php?r=$1&id=$2 [L]
RewriteRule ^([a-z]+)/([0-9]+)/([a-z]+) index.php?r=$1&id=$2&s=$3 [L]
RewriteRule ^([a-z]+)/([0-9]+) index.php?r=$1&id=$2 [L]
RewriteRule ^([a-z]+)/([0-9]+)/([a-z]+) index.php?r=$1&id=$2&s=$3 [L]
These 2 rules conflict. A URL of the form /abc/123/def is also matched by the first rule, so the second rule is never processed.
You could either:
Include an end-of-string anchor ($) on the first rule pattern, so that it only matches /abc/123 and not /abc/123/def. For example:
RewriteRule ^([a-z]+)/([0-9]+)$ index.php?r=$1&id=$2 [L]
OR, reverse these two directives, so the rule for 3 parameters takes priority:
RewriteRule ^([a-z]+)/([0-9]+)/([a-z]+) index.php?r=$1&id=$2&s=$3 [L]
RewriteRule ^([a-z]+)/([0-9]+) index.php?r=$1&id=$2 [L]
You should probably include end-of-string anchors on all your patterns, otherwise, they are likely to match too much. eg. /abc/123/def/for/bar/baz.jpg is matched by the 3rd and 4th rule without an end-of-string anchor. If you add end-of-string anchors then the filesystem conditions could probably be removed altogether.
As #IMSoP noted in comments, those two conditions (ie. RewriteCond directives) only apply to the first RewriteRule that follows. The first rule is unlikely to match a real file anyway, so the conditions aren't really doing anything currently.
I want to remove %20 on my link to - (dash),
My .htaccess is like that right now,
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ icerik.php?name=$1 [QSA,L]
For example,
site.com/vision-and-mision,
site.com/do-re-mi-fa-so-la-si.
Actually I searched something but the informations were very specific and I'm confused
Thank you.
You can use the following in your /.htaccess file:
RewriteEngine On
# Replace whitespace with hyphens, set the environment variable,
# and restart the rewriting process. This essentially loops
# until all whitespace has been converted.
RewriteRule ^([^\s]*)\s(.*)$ $1-$2 [E=whitespace:yes,N]
# Then, once that is done, check if the whitespace variable has
# been set and, if so, redirect to the new URI. This process ensures
# that the URI is rewritten in a loop *internally* so as to avoid
# multiple browser redirects.
RewriteCond %{ENV:whitespace} yes
RewriteRule (.*) /$1 [R=302,L]
Then add your rules afterwards:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /icerik.php?name=$1 [QSA,L]
If this is working for you, and you would like to make the redirects cached by browsers and search engines, change 302 to 301.
I have the following situation where I want to have nested ReWrite Conditions, and I have come across a situation where I am not able to see a proper documentation for the same.
RewriteCond %{REQUEST_URI} ^(robots.txt|favicon|ico)$ [NC]
RewriteRule . - [S=3]
# Nested ReWrite Condition
RewriteCond %{HTTP_HOST} ^www
RewriteRule .* http://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
RewriteRule .* http://%{SERVER_NAME}%{REQUEST_URI_1} [R=301,L]
RewriteRule .* http://%{SERVER_NAME}%{REQUEST_URI_2} [R=301,L] # and so on
Therefore, the question comes up that whether the number of skip rules will comprise of the nested ReWrite Conditions, that is, in this case, should the number of skipped rewrite rules be 4 or 5(if including the rewrite condition).
RewriteCond %{REQUEST_URI} ^(robots.txt|favicon|ico)$ [NC]
RewriteCond %{HTTP_HOST} !^www
RewriteRule .* - [S=3]
# the following rules are run only if the first 2 conditions don't match
RewriteRule .* http://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
RewriteRule .* http://%{SERVER_NAME}%{REQUEST_URI_1} [R=301,L]
RewriteRule .* http://%{SERVER_NAME}%{REQUEST_URI_2} [R=301,L]
notice the ! negation in the 2nd cond
documentation:
This technique is useful because a RewriteCond only applies to the
RewriteRule immediately following it. Thus, if you want to make a
RewriteCond apply to several RewriteRules, one possible technique is
to negate those conditions and add a RewriteRule with a [Skip] flag.
Okay as you only have posted an example, I show you an example how it works. It's with comments, but if you still don't find it speaking enough, there is a lot more explanation available here.
# Does the file exist?
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Create an if-then-else construct by skipping 3 lines if we meant to
# go to the "else" stanza.
RewriteRule .? - [S=3]
# IF the file exists, then:
RewriteRule (.*\.gif) images.php?$1
RewriteRule (.*\.html) docs.php?$1
# Skip past the "else" stanza.
RewriteRule .? - [S=1]
# ELSE...
Rewri
This should solve your issue. If not, please update your example in the question so it's clear what you're missing.
And yes, it skips Rules and not Conditions.
My website structure has a root /index.php, some files as /directory/index.php and some as /directory/(filename).php
I have the following .htaccess which removes the php extensions and the "index.php" for my URLs, and forces trailing slashes on the first level directories for SEO goodness:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{THE_REQUEST} ^GET\ /[^?\s]+\.php
RewriteRule (.*)\.php$ /$1/ [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*)/$ $1.php [L]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule .*[^/]$ $0/ [L,R=301]
so the following are working (they show the correct page):
/
/directory/
/directory/filename/
The only thing that doesn't work, is if I type in:
/directory/filename
It goes to:
http://(mylocalurl)/Users/(myusername)/Sites/(mysitedirectory)/directory/filename/
My question is: How do I make the second level filename rewrite to force a trailing slash like:
/directory/filename/
Thanks for your help!
DirectorySlash on
will add a trailing slash where appropriate.
Not 100% sure, but it could be that it is triggered by your the second RewriteCond, the RewriteRule is run, not replacing anything, and then you have the [L] that makes it not go to the last RewriteCond.
Maybe changing the order of the two might help?
(Or else, you might want to look into Multiviews directive)
When you're specifying a local relative URL path to perform an external redirection on, that path needs to be prepended with a slash. Since the match to your RewriteRule test pattern will not have a leading slash, be sure to put one in the rewrite:
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule .*[^/]$ /$0/ [L,R=301]
If I've understood your problem correctly, that's the only issue you have. If you needed something else though, let me know.