rewritecond if file does not exist - .htaccess

I have the following code in my .htaccess file:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(\w+)$ /pages.php?link=$1
My understanding is that it should check if the file does not exist, check if the directory does not exist and then perform the rule if those are true.
For some reason though it is giving me an error when I go to:
http://localhost/1.php
The error message that pops up is:
script 'C:/xampp/htdocs/1.php' not found or unable to stat
Strangely though, when I go to:
http://localhost/1
it acts as it should (redirects accordingly).

I believe your problem is your regex. You are using the \w to match a word. Well . is not matched in that. Change your rule to this.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /pages.php?link=$1

Related

.htaccess Rewrite for State Abbreviations, Ignore Otherwise

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} AL|AK|AZ|AR|CA|CO|CT|DC|DE|FL|GA|HI|ID|IL|IN|IA|KS|KY|LA|ME|MD|MA|MI|MN|MS|MO|MT|NE|NV|NH|NJ|NM|NY|NC|ND|OH|OK|OR|PA|RI|SC|SD|TN|TX|UT|VT|VA|WA|WV|WI|WY [NC]
RewriteRule ^([^/]+) index.php?state=$1 [QSA,L]
I currently have this as my code in my .htaccess file. What I want to happen is domain.com/{state} to plug whatever state into the state parameter and load its specifics. However, I also want other paths in the domain to work such as domain.com/img/flamingo.jpg. However, the way the code is currently since flamingo has fl in it, it'll interpret that as the state of Florida and cause a 404 error and not load the resource. How can I do the conditions so that it checks for the state abbreviations only, and then ignores the rewrite in all other cases?
You can use regex directly in RewriteRule but more importantly use anchors to disallow anything other than state code:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(A[LKRZ]|C[AOT]|D[EC]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])/?$ index.php?state=$1 [QSA,NC,L]

htaccess with multiple levels

I saw htaccess guides here but i think im doing it wrong. Here's my sample code.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/$ page.php?p=$1&c=$2&gc=$3
The issue i am facing here is, there are 3 levels of page that have links to each level. I usually get "Not Found" if i am going to the first parameter, even the 2nd parameter. It shows correct only the 3rd parameter.
What i would like to know here is, how can i configure my htaccess to get the certain page without having the link ended-up to "Not Found".
Your rule only matches if the path contains 3 parts. You need to create 2 more rules for the case where the path contains 2 parts and where the path contains 1 part:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]+)/$ page.php?p=$1&c=$2 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/$ page.php?p=$1 [L]
I also advice to use the [L] flag on the rule you already have. This will speed up things a little bit and might also prevent weird behaviour, especially when you are using redirects.

htaccess get filename without path

I'm trying to get the requested filename without the path with htaccess for a RewriteCond.
REQUEST_FILENAME returns the full absolute path, but I only need the filename like test.php
I've been searching for this a lot but couldn't find anything that helped me out.
Thanks for any responses in advance!
Edit:
Im trying to do something like this:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond _%{REQUEST_FILENAME}.php -f
RewriteRule ^([^/]*)$ _$1.php [L]
The URL typed in the browser looks like this: http://example.org/test
The File that will be requestested by the RewriteRule is: http://example.org/_test.php
With RewriteCond _%{REQUEST_FILENAME}.php -f i tried to check if the file exists first
Basically I want to do this:
URI: /test/blah
Check if _test.php exists (with underscore!)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/_$1.php -f
RewriteRule ^([^/]+)$ _$1.php [L]
I changed * to + so requests for e.g. example.com/ will not redirect to _.php

What does this .htaccess code mean?

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* ./index.php
I think it means if the url doesn't match a file or directory on the server go to /index.php?
Can anybody confirm?
Yes is the short answer. But usually ./index.php has an [L,QSA] suffix/qualifier, so the query part of a URI request is also passed on to it.
What this is doing:
RewriteCond %{REQUEST_FILENAME} !-d
If it can't find a directory with the name
RewriteCond %{REQUEST_FILENAME} !-f
If it can't find a file with the name
RewriteRule .* ./index.php
Load the index.php next to the .htaccess file.
To answer Anthony's question regarding what would happen if it where removed1 2,
It would try and access the directory or file. If it fails, instead of defaulting to the index.php it would simply give the default web servers 404 error.
Right now, it allows the application to either show the default page, or handle the request through it in some fashion.

Htaccess help, $1 being used before its set??? what?

I have this snippet
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !^(index\.php|images|img|css|js|robots\.txt)
RewriteRule (.*) index.php?/$1 [L]
It won't allow me to access a file at website.com/js/main.php
but it will let me access index.php
According to my webhost, $1 is being called before it is set. Any solutions?
I'll accept answers when i get back tomorrow. Thank you!
I'm assuming you want the rewrite to ignore the things which your condition currently specifies. In that case...
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond !^(index\.php|images|img|css|js|robots\.txt)
RewriteRule (.*) index.php?/$1 [L,QSA]
...should work fine. You'll probably want the QSA on there so that if there's a query string, it's properly handled.
Your web host is wrong. The order of ruleset processing is:
pattern in RewriteRule is tested (that will populate the $N references with values)
associated RewriteCond conditions are tested (if present)
Only if the pattern matches the current URL path and the associated condition is fulfilled, the pattern is applied.
So in your case the pattern (.*) is tested on the current URL path js/main.php (without local prefix /). It matches ($0=js/main.php, $1=js/main.php) so the three associated conditions are tested in the order they appear:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !^(index\.php|images|img|css|js|robots\.txt)
Assuming that the requested URL path /js/main.php does not refer to an existing file or directory, the first conditions are both true. But the third one will evaluate to false as $1=js/main.php and the pattern ^(index\.php|images|img|css|js|robots\.txt) matches (^js branch) js/main.php. So the condition is not fulfilled and the rule is not applied.

Resources