PHP GET after htaccsess rewrite - php

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?

Related

htaccess multiple query string not working

I want to get this URL:
example.com/scooter-details/1/vespa-sprint
But the URL I get is:
example.com/scooter-details.php?scooter_id=1&scooter_brand=vespasprint&scooter_model=
The scooter_model "sprint" is in the scooter_brand query, Normally it has to be scooter_brand=vespa&scooter_model=sprint. Hope you can help me with this
Here is the htaccess code
Options +FollowSymLinks -MultiViews
RewriteEngine On
# SEO FRIENDLY URL
# Redirect "/scooter-details.php?service_id=<num>" to "/scooter-details/<num>"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ^scooter_id=(\d+)&scooter_brand=([^/.]+)&scooter_model=([^/.]+)$
RewriteRule ^(scooter-details)\.php$ /$1/%1/$2%2-$3%3? [QSD,L,R=301,N]
# Rewrite "/scooter-details/<num>" back to "scooter-details.php?service_id=<num>"
RewriteRule ^(scooter-details)/(\d+)/([^/]+)$ $1.php?scooter_id=$2&scooter_brand=$3&scooter_model=$4 [L]
You most probably need the NE (noescape) flag on the RewriteRule directive if you are capturing elements of the query string (which is already URL-encoded) and using these to build the URL-path. Otherwise you will end up doubly-URL-encoding parts of the resulting URL-path - which is what this looks like.
%2520 is a doubly URL-encoded space. ie. you would seem to have %20 (ie. a space) in the query string you are capturing from.
However, the rule you have posted does not seem to relate to the example URLs given?

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.

RewriteRule .htaccess is forwarding PHP Variable

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.

Rewrite automatically removes backslash if there's more than one?

I have a very simple url rewriting rules:
RewriteEngine on
RewriteCond %{HTTP_HOST} !script.php
RewriteRule ^test/(.*) script.php?q=$1
The idea is to have this kind of urls: http://mywebsite.com/test/http://example.com
and then send http://example.com to the script.php as a query parameter. The problem is that I'm receiving http:/example.com instead of http://example.com. Also, http:////example.com would be sent as http:/example.com. What causes this behavior ?
Apache mod_rewrite engine converts multiple ///... into single / for pattern matching in RewriteRule directive. However if you match it using RewriteCond then you can match multiple /s.
You can use rule like this:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} ^/+test/+(https?://.+)$ [NC]
RewriteRule ^ script.php?q=%1 [L,QSA]
The browser causes this behaviour. It contracts a sequence of / into 1 /, because it is still essentially a path. ///// does not change the directory we are in, so we could as well use /.
You have two options:
Change your links to use a query string instead. If you rewrite test/?q=something to script.php?q=something everything works as expected. You would do the following:
RewriteRule ^test/?$ script.php [L]
Since you don't alter the query string, the original query string is automatically copied to the new query string.
Don't make an assumption on how many slashes you will encounter. The url might not look correctly in the url bar of the browser, but if it is just a redirect, it will only be visible for a very short period of time.
RewriteRule ^test/(http|https):/+(.*)$ script.php?q=$1://$2

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