Regex - mod_rewrite - Match string after characters and run as get vars - php

I'm looking to find and capture the url by "/-" and run the resulting find as a single get var on the preceding page:
http://domain.com/about-us/contact/-foo/-bar
would run as:
http://domain.com/about-us/contact/?get=/-foo/-bar
I'm able to find the match with:
RewriteCond %{REQUEST_URI} (\/-.*)
RewriteRule ^(.*)$ ?get=$1 [L]
But have been unsuccessful returning the proper get var. This yields:
http://domain.com/?get=about-us/contact/-foo/-bar
Any help would be much appreciated!

You're matching the whole URL in the RewriteRule, instead break it up into the base and the rest since you already predetermined the URL format with RewriteCond:
RewriteCond %{REQUEST_URI} (\/-.*)
RewriteRule ^(.*?)(\/-.*)$ $1?get=$2 [L]
Note: There are other ways to do this without RewriteRule. However, this is most like your current code.

Ok, I found the issue to the redirect vs. rewrite I was having. Basically I need to make sure and put the file in index.php.
RewriteCond %{REQUEST_URI} (\/-.*)
RewriteRule ^(.*?)(\/-.*)$ $1/index.php?get=$2 [L]
Thanks, Jason for your help!

Related

Unable to remove query strings from URL using .htaccess

My URLs look like http://example.com/?n=x. I want the URL to show as http://example.com/. I have used to approaches so far and none of them works.
First one is based on this question:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^n=1$
RewriteRule (.*) $1? [R=permanent]
After the answer below I modified the .htaccess file:
```RewriteEngine On
RewriteCond %{QUERY_STRING} ^n=(.*)$
RewriteRule (.*) $1? [R=permanent]```
but it still did not work. Here is the debugging info:
RewriteCond %{QUERY_STRING} ^n=(.*)$
This condition was met.
RewriteRule (.*) $1? [R=permanent]
The new url is http://example.com/blog/cat/??
Test are stopped, a redirect will be made with status code permanent
Second approach is:
RewriteEngine On
RewriteCond %{QUERY_STRING} !^$
RewriteRule ^(.*)$ $1 [QSD]
None of them seem to work.
I have a few more questions:
Does rewriting only work if the URL is not typed manually?
Can I still access the values of query strings in PHP?
What happens when a user copies the rewritten URL?
The first approach is correct if you go to http://example.com/?n=1, if I am correct you should change ^n=1$ to ^n=(.*)$.
And the other questions:
It works for all kind. It doesn't matter if it was a robot or a human writing it, when you access a page, .htaccess will be read.
Yes you can. Use $_SERVER["QUERY_STRING"]. If you use the htaccess redirection before explained, you will lose them because you are redirecting.
What do you mean ?

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

Should be a simple mod_rewrite rule

This rule does not seem to be functioning, however I cannot determine why, it looks fine to me:
RewriteRule ^shop_en/proddetail.php?prod=(.+)$ /shop/product/$1 [L,NC,NE,R=301]
Its like it does not get processed at all, I simply get my sites error message stating it cannot find 'proddetail.php'.
Which is weird too, because on a quick test I tried the following:
RewriteRule ^shop_en/proddetail.php$ /shop/product [L,NC,R=301]
Which worked fine. So what is going on?
Edit: The product ID's that I am working with can contain letters, numbers and dashes.
In the simplest terms, with the most convenient definitions:
I want to route anyone trying access:
www.domain.com/shop_en/proddetail.php?prod=333
To the following URL:
www.domain.com/shop/product/333
how can I do this?
Try this
RewriteRule ^/?shop/product/([a-zA-Z0-9\-]+)$ shop_en/proddetail.php?prod=$1 [L,NC,NE,R=301]
It is not working because you're trying to match QUERY_STRING in RewriteRule. You will need a RewriteCond to match QUERY_STRING.
You can use:
RewriteCond %{THE_REQUEST} \s/+shop_en/proddetail\.php\?prod=([^&\s]+) [NC]
RewriteRule ^ /shop/product/%1? [L,NE,R=301]
RewriteRule ^shop/product/([^/]+)$ /shop_en/proddetail\.php\?prod=$1 [L,QSA,NC]

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]

URL Mod Rewriting

I am using codeigniter for my website, and before theres always that index.php? on my every url or links, for example
mysite.com/index.php?/about
Google has indexed all of my urls with that index.php? and I want to remove it and redirect it without that. I am having a problem rewriting the URL and redirect it to mysite.com/about and this what i have tried so far
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+index\.php\?(/[^\s\?]+)? [NC]
RewriteRule ^ %1/ [QSA,L,R=301]
what happened is, it only removed the index.php,
for example mysite.com/index.php?/about will turn to mysite.com/?/about I don't know how to remove that question mark,
I'm not good on mod_rewrite thanks in advance for the help.
I think you can improve the rules slightly.
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} index\.php?\?.+
RewriteRule .*$ %{QUERY_STRING}? [R=301,L]
Essentially, you don't have to worry about the entire request line in %{THE_REQUEST}, which removes all the complicated regex. Also, the rule redirects to whatever is listed in %{QUERY_STRING}, and removes the query string.
I am not sure why you used QSA in the first place. I think that was part of the problem earlier. Just for an exercise, you can try removing QSA and see what happens.
You should try this one.
RewriteCond %{QUERY_STRING} ^/[a-z]+$ [NC]
RewriteRule ^/index.php$ %{QUERY_STRING} [NC,L,R=301]

Categories