I use htaccess for make mu URL clean. My original ULR is
http://localhost/bookStore/single_book.php?name=This%20is%20book%20no%204
i use php urlencode() function to make this
http://localhost/bookStore/single_book.php?name=This+is+book+no+4
but now i want to make this like:
http://localhost/bookStore/single_book/This+is+book+no+4
using htaccess
RewriteRule ^single_book/([0-9a-zA-Z_-]+) single_book.php?name=$2 [NC,L]
RewriteRule not working
RewriteCond %{QUERY_STRING} ^name=(.+)
RewriteRule ^(bookStore/single_book)(\.php)$ $1/%1?
This matches if name is in the query string and if the name is the only portion of the query string.
I tested on https://htaccess.madewithlove.be/
And for playing with the regex, i used https://regexr.com/
The trailing ? in the RewriteRule removes the query string.
Related
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
I have written a code in .htaccess file for search engine friendly URL purpose:
RewriteRule ^games/(.*\S)$ helper/Games.php?p=$1 [L]
As you see, anything after games/ rewrites to helper/Games.php?p=
But I don't want $_GET['p'] witch contains ? or /.
For example below URLs should NOT be rewrites by my rule:
example.com/games/Test?Test
example.com/games/Test/Test
Please guide me to find correct Regex.
Thanks.
You need to match against empty QUERY_STRING before rewriting the url:
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^test/([^/]+)$ helper/Gampes.php?p=$1 [L]
You just need to negate the set of values you don't want rather than using the wildcard .. So:
RewriteRule ^games/([^/]*[^\s/])$ helper/Games.php?p=$1 [L]
Since the query string isn't part of the match, you'll want to first:
RewriteCond %{QUERY_STRING} ^$
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.
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
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]