Redirecting URL with .htaccess - php

I want to redirect URL, using .htaccess. I have the following code:
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)$ index.php?action=$1&id=$2
This is working correctly if I don't use dot in the URL. But if I want to access for example this URL:
load/com.example.unique.id
then I will get error 404. Of course, I can understand why is this: I haven't include the dot in my expression. However if I include it, I will get error 500.
I tried to include dot in the expression like this:
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-\.]+)$ index.php?action=$1&id=$2
Any idea why is this happening? Thanks!

I think the problem is with the '-' in [a-zA-Z0-9_-.], try this:
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_\-.]+)$ index.php?action=$1&id=$2

You can use dot but hyphen needs to be last or at first position in character class to avoid escaping. Correct regex based rule will be like this:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([\w.-]+)/([\w.-]+)/?$ index.php?action=$1&id=$2 [L,QSA]

Related

htaccess rewrite a multi-query string into a path

How would i go about changing the query string
file.php?id=number&string=some-words
into this
file/number/some-words/
I know this has been asked a million times before, but I've looked at a number of solutions on here and they were all single query based (as in just ?something and not ?something&something-else).
Also once rewritten, does the php still read the original page query-string when using $_GET or $_REQUEST etc... even though it now appears as a path?
Any help is appreciated.
Thanks.
RewriteRule takes a regular expression which can be as complicated as you want it followed by the real URL that will load your file. You put parenthesis around the parts you want to capture in the regex and can reference those with $1 for first group, $2 for second group and so on in the URL part. For example:
RewriteRule ^(\w+)/(\d+)/(.*)$ index.php?file=$1&id=$2&words=$3
This would match 3 groups:
letters/numbers up to the first slash
some numbers up to the second slash
anything after that including additional slashes
And those can be referenced by $1, $2, $3 as seen in the second part with index.php.
The only issue with this though is that if you are missing any one part, the pattern in the rule won't match. So you either need to have a separate rule for each variant:
#matches all 3 parts
RewriteRule ^(\w+)/(\d+)/(.*)$ index.php?file=$1&id=$2&words=$3
#matches the first 2 parts
RewriteRule ^(\w+)/(\d+)$ index.php?file=$1&id=$2
#matches just the first part
RewriteRule ^(\w+)$ index.php?file=$1
#matches everything else
RewriteRule ^.*$ index.php
Or you can do what is usually called bootstrapping which is where you use a single RewriteRule to redirect everything to a single php file like so:
RewriteRule ^(.*)$ index.php
And then you can just use php to determine what the different parts are. Inside php there is a built in server variable $_SERVER['REQUEST_URI'] that will give you the URI part of the url which is everything after the domain and first slash including any query string parameters. This is based on the URL that the user requested and not the one rewritten by apache. You can explode('/', $_SERVER['REQUEST_URI']) to get the individual parts and do whatever you want with them.
You can place your code in Apache .htaccess files. This could look something like this:
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^users/(\d+)*$ ./profile.php?id=$1
RewriteRule ^threads/(\d+)*$ ./thread.php?id=$1
RewriteRule ^search/(.*)$ ./search.php?query=$1
Or you can use only htaccess and php:
htaccess
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^.*$ ./index.php
PHP
<?php
#remove the directory path we don't want
$request = str_replace("/envato/pretty/php/", "", $_SERVER['REQUEST_URI']);
#split the path by '/'
$params = split("/", $request);
?>
And it will still read the original page query-string.

.htaccess Pretty URLs title in url

I'm trying to make pretty url but want to put content title in url instead id, then i put content title in url with query string:
index.php?action=content&id=22
changed to:
index.php?action=content&title=stack-over-flow
it's works fine. now i trying to make it pretty but got a problem in htaccess code.
before removing id in url code was:
RewriteRule ^([a-z]+)/([0-9]+)/?$ index.php?action=$1&id=$2 [NC,L,QSA]
then i changed to:
RewriteRule ^([a-z]+)/([a-z]+)/?$ content.php?action=$1&title=$2 [NC,L,QSA]
but it's not working and i will back 300 Multiple Choices page. well, i think it's a httaccess problem, but i'm new in htaccess, need a hand to fix this.
want this:
/content/stack-over-flow
Your regex is only allowing letters. It should also allow hyphen, numbers, upper case letters and underscore. Try this:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([a-z]+)/([^/]+)/?$ content.php?action=$1&title=$2 [NC,L,QSA]

How to Get Parameters from URL using .htaccess in PHP

How can I show following URL using .htaccess re-write rule with a non ? parameter?
Original URL
http://example.com/index.php?store=1
Desired URL
http://example.com/1/
OR
Desired URL
http://example.com/store/1
I am trying following code in .htaccess. What I am missing here?
RewriteEngine On
Options +Followsymlinks
RewriteCond %{REQUEST_FILENAME} !-f
rewriteRule ^store/(.+)\$ index.php?store=$1 [L]
my index.php file has this code
<?php
$storeid = $_GET['store'];
echo $storeid;
?>
What I am missing here?
You are escaping your end-of-string character, causing the expression to look for a literal $ sign so it never matches.
You need something like:
rewriteRule ^store/(.+)$ /index.php?store=$1 [L]
^ no back-slash here
or if you want to make sure you only match numbers:
rewriteRule ^store/(\d+)$ /index.php?store=$1 [L]

Rewrite domain, but still use index.php

Current code to use index.php for all urls :
RewriteRule ^(.*)$ ./index.php
But for one special case, I want to make url
http://domain.com/s/this_changes to call actually
http://domain.com/steps/step/this_changes.
I tried adding :
RewriteRule ^./s/$ ./steps/step/$1, but it gives an error 500.
Try this:
RewriteEngine On
RewriteRule ^s/(.+)$ /steps/step/$1 [L]
Another way you could do it is to route all your URIs through index.php, and create a function for each one.
RewriteRule ^s/this_changes$ steps/step/this_changes
if it is that simple or
RewriteRule ^(.*)/(.*)$ steps/$1/$2
And your specific code would work like this
RewriteRule ^s/(.*)/?$ ./steps/step/$1
The (.*) is referenced in your $1 in the second part of your code.

Mod_rewrite in .htaccess - forward anything that starts with index.php to ____

UPDATE: This works:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{THE_REQUEST} ^[A-Z]+\ ([^\s]+)
RewriteRule (.+) /index.cfm?event=checkuri&uri=%1 [QSA]
Some background...
So we already have a catchall redirect in our .htaccess file which is this:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.+) /index.cfm?event=checkuri&uri=$1
This ties into a database table that checks the URI for a match. so if we just moved a site that used to have this page:
/some-awesome-article.html
Onto our system, and the new address is
/awesome-article/12442
and someone tried to access the old URI, our system would check for this, find a match, and forward them to the new home: /awesome-article/12442
This system works awesome, with one exception. If the URI is something like /index.php?id=123412 then the whole system falls apart. In fact /index.php/whatever won't work either.
Everything else works except for this. We do not use PHP for our web application (although support says its in an admin console on the server somewhere).
So basically what I need is if index.php is detected anywhere it will forward the URI to our
existing system:
How can i modify this to fix it?
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.+) /index.cfm?event=checkuri&uri=$1
Try changing your code to:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.+) /index.cfm?event=checkuri&uri=$1 [L,QSA]
QSA is for Query String Append that will make sure to append existing query parameters with the new ones.
Rewriting with mod_rewrite does not work on the full URL. In fact, the regex in the RewriteRule does only get the path and file, but not the query string. And so the backreference $1 will only contain "index.php" and nothing else.
Additionally, the RewriteRule does change the query string because there is one in the target pattern. Because the flag [QSA] (query string append) is not present, the query string of the original request gets replaced instead of appended. So the query string is gone after this rewriting.
This would be a lot easier if you wouldn't mess with the query string. The easiest way of rewriting any url that is not an existing file would be if the second line would be simply RewriteRule (.+) /index.cfm - you could then get all info about the current request, including query string, path and file, in the script.
So now you'd have to fiddle with the query string. Adding [QSA] will pass the query string to your script and you'd have to detect what's inside. This will work only if you do not expect the query string to contain parameters named "event" and "uri" - these will be overwritten by your rewriting. If you need to add the original query string to the URL, it's a bit more complicated, because the string needs to be url-encoded.
Here's how to do that.
Based on your comments, it sounds like you need to use the Query String Append QSA flag on your rule like this:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /index.cfm?event=checkuri&uri=$1 [QSA,L]
In your example case the rewrite would look like:
/index.cfm?event=checkuri&uri=index.php&id=123412
Sven was very close so I'm giving him the check
This ended up working perfectly:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{THE_REQUEST} ^[A-Z]+\ ([^\s]+)
RewriteRule (.+) /index.cfm?event=checkuri&uri=%1 [QSA]

Categories