RewriteRule .htaccess is forwarding PHP Variable - php

I am trying to forward old posts on my site using .htaccess RewriteRule to new addresses.
First rule is
RewriteCond %{QUERY_STRING} id=16
RewriteRule ^current_article\.php$ /article/basics-of-electrosurgery [L,R=301]
which rewrites http://www.megadyne.com/current_article.php?id=16
to http://www.megadyne.com/article/basics-of-electrosurgery
Second rule is
RewriteRule ^article/([A-Za-z0-9-]+)/?$ articles.php?id=$1 [NC]
which rewrites http://www.megadyne.com/article/basics-of-electrosurgery to http://www.megadyne.com/articles.php?id=basics-of-electrosurgery
All works fine except the final result is http://www.megadyne.com/article/basics-of-electrosurgery?id=16 and I don't want it to append the final variable "?id=16" to the address.

You need a ? at the end of your first rule, and should probably add some boundaries to the query string match:
RewriteCond %{QUERY_STRING} (^|&)id=16($|&)
RewriteRule ^current_article\.php$ /article/basics-of-electrosurgery? [L,R=301]
When there's a query string in the request, it automatically gets appended to the end of the rule's target unless you are creating a query string in the target. So here, you're creating an empty query string, and without the QSA flag, the existing query string won't get appended.

Related

PHP GET after htaccsess rewrite

I am trying to get the variable from my url but having problems.
the default URL is http://localhost/category.php?category_slug=gaming
With my htaccsess file
RewriteRule ^category/([\w\d-]+)$ /category.php?category_slug=$1 [L]
RewriteCond %{QUERY_STRING} category_slug=([\w\d-]+)
RewriteRule ^category$ %1 [R,L]
I get my desired URL http://localhost/category/gaming
but now I am needing to get the page variable from the url http://localhost/category/gaming?page=2
in category.php i have $page=$_GET['page'];
but when I echo it out i get Warning: Undefined array key "page" in F:\Server\htdocs\category.php on line 5
The closest i can get is with the following code
RewriteRule ^category/([\w\d-]+)$ /category.php?category_slug=$1&page=$2 [L]
RewriteCond %{QUERY_STRING} category_slug=([\w\d-]+)
RewriteRule ^category$ %1 [R,L]
I get no errors but the data isnt showing
The desired URL would be either
http://localhost/category/gaming?page=2 or http://localhost/category/gaming/page2/
im pretty sure my lack of knowledge of editing my htaccsess file is to blame. and need someone to point me in the right direction please
RewriteRule ^category/([\w\d-]+)$ /category.php?category_slug=$1 [L]
You need to add the QSA (Query String Append) flag to the first rule that rewrites the request. This appends/merges the query string on the request (ie. page=2) with the query string you are including in the substitution string (ie. category_slug), otherwise the query string in the substitution replaces the query string on the request.
(If, however, you are not including a query string in the substitution string then the original query string on the request is passed through by default - no need for the QSA flag in this case.)
Minor point, but the \w shorthand class already includes digits, so the \d is superfluous.
You should also make sure that MultiViews is disabled, otherwise all query string parameters will be lost.
For example:
Options -MultiViews
RewriteRule ^category/([\w-]+)$ /category.php?category_slug=$1 [QSA,L]
This then handles both /category/gaming and /category/gaming?page=2.
Aside:
RewriteCond %{QUERY_STRING} category_slug=([\w\d-]+)
RewriteRule ^category$ %1 [R,L]
Your second rule isn't actually doing anything, unless this is related to something else. This would likely result in a malformed redirect if it did anything at all?
This rule would redirect a URL of the form /category?category_slug=gaming to gaming (only) - which is dependent on you having a RewriteBase defined. Is that the intention?

Redirect rule to php query but remove any query string in the requested url

My url is being redirected using .htaccess as follows:
RewriteRule ^b/([^/]+)/([^/]+)? b/view.php?id=$2&name=$1
Friendly url -> translates to php url
domain.com/b/hello/2 -> b/view.php?id=2&name=hello
BUT when someone comes to the site as follows:
domain.com/b/hello/2?query=xyz
I don't know how to get rid of the ?query=xyz
I have tried everything including [QSD] and I can't seem to get it to work.
Update
I have managed to get it to work with the following but it does two 301 redirects instead of one:
RewriteCond %{THE_REQUEST} \?[^\ ]+
RewriteRule ^b/(.*)$ /x/$1? [R=301,L]
RewriteRule ^b/([^/]+)/([^/]+)/([^/]+)?$ b/view.php?id=$2&&name=$1
Check if adding the question mark at the end of the rule will cancel appending query string from left side
RewriteRule ^b/([^/]+)/([^/]+)? b/view.php?id=$2&name=$1? [QSD,L]
You can use an additional Rule to catch for GET parameters and strip them off.
RewriteCond %{QUERY_STRING} .+
RewriteRule ^(.*)$ /$1? [R=301,L]
RewriteRule ^b/([^/]+)/([^/]+)? b/view.php?id=$2&name=$1
To make it only work on the /b/ subfolder, use this:
RewriteCond %{QUERY_STRING} .+
RewriteRule ^b/(.*)$ b/$1? [R=301,L]
RewriteRule ^b/([^/]+)/([^/]+)? b/view.php?id=$2&name=$1
The first rule will redirect everything that matches your rule to the URL without any GET parameters (note the ? at the end of the rewrite rule, it will strip off the parameters).
The second rule will match in the case the first rule cannot be applied, i.e., when there are no paramaters

Mod rewrite issue redirect with post

In fact I am working on a small php script, and now I am struggling with doing redirect using mod-rewrite.
What i want is to redirect
www.xx.com/motivational/api.php?latest=1
to
www.xx.com/api.php?latest=1&app=motivational
I tried this but it doesn't work:
RewriteRule ^/motivational/api\.php$ /api.php?latest=&%{QUERY_STRING}
%{QUERY_STRING} represents the entire query string, in your case latest=1. So when you append it to ...?latest= in your substitution string the result is ...?latest=latest=1 which is not what you want.
Change your rule to
RewriteRule ^/motivational/api\.php$ /api.php?%{QUERY_STRING}&app=motivational
and you should be fine.
Or you could do:
RewriteRule ^/motivational/api\.php$ /api.php?app=motivational [QSA]
The QSA flag means to append the new query string to the old, rather than to replace it, so your latest variable will not be lost.
You can not match against query strings in a RewriteRule, You will need a RewriteCond to match query strings in url :
RewriteEngine on
RewriteCond %{THE_REQUEST} /([^/]+)/api\.php\?latest=1 [NC]
RewriteRule ^ /api.php?latest=1&app=%1 [NC,L,R]
%1 is part of the regex "([^/]+)" in RewriteCond, it contains dynmically captured path in the request line.

Mod Rewrite - WP url &preview_nonce=(.*)

I would like to change any url containing the query string &preview_nonce= with any value passed to preview_nonce.
I understand that I have to rewrite based on the condition:
RewriteCond %{QUERY_STRING} ^preview_nonce=(.*)$
But I'm getting caught up only removing that from the query string and leaving everything else, including query strings.
Example URLs:
about-us/history/commitment/?preview=true&preview_id=9999&preview_nonce=9x323k1
stories/companies/?preview=true&preview_id=8888&preview_nonce=c448s88
The desired results:
about-us/history/commitment/?preview=true&preview_id=9999
stories/companies/?preview=true&preview_id=8888
You can use this rule for query string removal:
RewriteCond %{QUERY_STRING} ^(.+?&)?preview_nonce=[^&]*(?:&(.*))?$ [NC]
RewriteRule ^ %{REQUEST_URI}?%1%2 [L,NC,R=302]
Make sure this rule is placed before other WP rules.

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