Weird rewriterule behaviour - .htaccess

I'm hoping someone can help me here. I'm currently trying to make my site more SEO friendly and having some strange issues with .htaccess.
This is all on my testing server. The designer section was working fine without "homeware-designer/" preceding the designer name "cquoi, etc". All good until I added the last one mage then it all stopped working, relative links were no longer working properly. I removed RewriteRule mage designerdata.php?search=4 and it all started working again. Once I added homeware-designer/etc all works fine again???? Can anyone tell me what might be going on. Also some of the rules won't work without ^foo$, but most will work without the ^$ delimiters and most will not work at all with the ^$ string delimiters. I just need to understand what is going on before I try to put it on the live server.
Options +FollowSymLinks -Indexes
RewriteEngine on
RewriteBase /
RewriteRule designer-homeware index.php
#------------------ Living ---------------
RewriteRule living-room-hallway category.php?collection=1
RewriteRule designer-shelves-storage contentdata.php?collection=1&type=17
RewriteRule designer-cushions-pouffes contentdata.php?collection=1&type=1
rewriterule designer-coat-hat-racks contentdata.php?collection=1&type=19
rewriterule designer-lighting contentdata.php?collection=1&type=25
rewriterule living-room-accessories contentdata.php?collection=1&type=4
#----------------- Eating ----------------
RewriteRule dining-room-eating category.php?collection=2
rewriterule designer-tableware contentdata.php?collection=2&type=5
rewriterule designer-glassware contentdata.php?collection=2&type=6
rewriterule dining-room-accessories contentdata.php?collection=2&type=8
#----------------- Bathing ----------------
RewriteRule ^bathroom$ category.php?collection=5
RewriteRule bathroom-accessories contentdata.php?collection=5&type=11
#----------------- Kids -------------------
RewriteRule ^childrens-decor$ category.php?collection=6
RewriteRule ^designer-childrens-decor$ contentdata.php?collection=6&type=20
#----------------- Garden ------------------
RewriteRule garden category.php?collection=7
RewriteRule garden-accessories contentdata.php?collection=7&type=21
#----------------- Art ---------------------
rewriterule designer-prints contentdata.php?collection=8&type=24
#----------------- Designers --------------
RewriteRule homeware-designers designer.php
RewriteRule homeware-designer/cquoi designerdata.php?search=7
RewriteRule homeware-designer/remember designerdata.php?search=8
RewriteRule homeware-designer/terafue designerdata.php?search=10
RewriteRule homeware-designer/r-bernier designerdata.php?search=11
RewriteRule homeware-designer/c-l-boym designerdata.php?search=21
RewriteRule homeware-designer/andre-klauser designerdata.php?search=22
RewriteRule homeware-designer/shin-azumi designerdata.php?search=23
RewriteRule homeware-designer/alejandro-ruiz designerdata.php?search=24
RewriteRule homeware-designer/tord-boontje designerdata.php?search=25
RewriteRule homeware-designer/sibo-home-concept designerdata.php?search=13
RewriteRule homeware-designer/zafferano designerdata.php?search=14
RewriteRule homeware-designer/klevering designerdata.php?search=15
RewriteRule homeware-designer/dutch-waaren designerdata.php?search=16
RewriteRule homeware-designer/vintage-casa designerdata.php?search=17
RewriteRule homeware-designer/hubsch-denmark designerdata.php?search=18
RewriteRule homeware-designer/serholt-sweden designerdata.php?search=19
RewriteRule homeware-designer/lazis designerdata.php?search=20
RewriteRule homeware-designer/atlantis designerdata.php?search=26
RewriteRule homeware-designer/mage designerdata.php?search=4

For these kind of exact-url rules, it's best to include the ^$ delimiters. The issue with needing the ^$ delimiters is that some rules are subsets of others. For example, the bathroom rule would catch the url bathroom-accessories if you didn't have the delimiters. In general, if you know that's the entire exact url you want, it's best to have the delimiters.
The other issue is these rules are all being checked, even after they match. In most cases, it isn't a problem, but like the bathroom word, some might be getting matched on more than one rule. To fix this, put [L] at the end of the rule, to indicate it's the Last rule if it matches - that is, it says if it matches, be done and exit.
It's common to also include an NC flag, for no-case, to not care if it's uppercase or lowercase.
RewriteRule designer-homeware index.php [NC,L]
#------------------ Living ---------------
RewriteRule living-room-hallway category.php?collection=1 [NC,L]
RewriteRule designer-shelves-storage contentdata.php?collection=1&type=17 [NC,L]
etc.
Try this out and see if it helps. I don't see anything wrong with the mage rule specifically, but the L and delimiters will at least keep the rules from overlapping each other.

Related

how to replace "?" and "=" sign with "/" in URL - PHP htaccess

i am working on project, which is running XAMPP localhost and PHP MYSQLI,
my question : how i replace "?","=" signs with "/" slash. ?
like, my url is "archive?date=2017-06-02&p=4"
and i want to force it "archive/2017-08-02/4"
i found many codes on stackoverflow and some other sites, but that are not working for me.
if codes are working then, CSS files and GET method doesn't work on my project.
complete code of .htaccess is given below.
Options +FollowSymlinks
RewriteEngine on
RewriteRule ^([^=]*)=([^=]*)=(.*) /$1/$2/$3 [N]
RewriteRule ^([^=]*)=([^=]*)$ $1/$2 [L]
RewriteRule ^home index.php [NC,L]
RewriteRule ^archive archive.php [NC,L]
RewriteRule ^about about.php [NC,L]
RewriteRule ^article article.php [NC,L]
RewriteRule ^news news.php [NC,L]
RewriteRule ^video videos.php [NC,L]
RewriteRule ^video?vid=([0-9]+) videos.php?q=$1 [NC,L]
RewriteRule ^article?num=([0-9]+) article.php?num=$1 [NC,L]
RewriteRule ^editorial?num=([0-9]+) editorial.php?num=$1 [NC,L]
RewriteRule ^news?news=([0-9]+) news.php?news=$1 [NC,L]
You cannot check against the query string in a rewrite rule. You need rewrite conditions for that:
RewriteCond %{QUERY_STRING} date=([^&]+)&p=(.+)
RewriteRule ^archive/? /archive/%1/%2?
Demo here: http://htaccess.mwl.be?share=81e85c09-d505-5206-ab14-6c5059107808
If you want to actually redirect just add [R=301,L] to the end of the RewriteRule.
However, looking at the above I suspect you have your script sitting listening at /archive/index.php?data=foo&p=bar but want URLs to be like /archive/date/p, ie pretty.
This is actually a very common misconception about how htaccess URL rewrites work when you first get into them.
RewriteRules will mask or redirect URLs for you but they cannot change the underlying location a script is located at and thus the address used to pass it information.
In other words - you can mask /archive/index.php?data=foo&p=bar as /archive/date/p so that requests made to /archive/date/p resolve to /archive/index.php?data=foo&p=bar, but you cannot make it so that if you enter /archive/index.php?data=foo&p=bar as URL you have the URL change to /archive/date/p while still serving content from /archive/date/p. It has to be either or.
If this all sounds about right my advice would be as follows:
First, put your code into a different file, say /archive/script.php.
Next add the following to your htaccess:
RewriteCond %{QUERY_STRING} date=([^&]+)&p=(.+)
RewriteRule ^archive/? /archive/%1/%2? [R=301,L]
RewriteRule ^archive/([^/]+)/([^/]+) /archive/script.php?date=$1&p=$2
Note that the first two lines are the same as before, but now there is a new line that looks for the masked URL format of /archive/date/p and sends it off to the actual script, which is handled by the new RewriteRule.
The behaviour of the new rule is demoed here: http://htaccess.mwl.be?share=06751667-f16f-5c13-91eb-dd5cffdc6db3
Hope this makes sense / helps.

How to get Apache's mod_rewrite working?

I know it's been asked a hundred times, and I also took my time searching and trying. Somehow I still can't get it to work, only partially.
I have structure of urls like these: (xxxx can be numbers as well)
index.php?mode=xxxxx
index.php?category=xxx
index.php?product=xxxx
index.php?article=xxxxx
index.php?blog&post=xxxxx
The url I'd like to see in the end of all variations:
www.example.com/something
www.example.com/something/something (in the blog&post case)
I also would like to hide index.php at the end.
If only have numbers and nothing at the end, the rules would be:
RewriteEngine on
RewriteRule ^mode/([0-9]+)$ /index.php?mode=$1 [L]
RewriteRule ^category/([0-9]+)$ /index.php?category=$1 [L]
RewriteRule ^product/([0-9]+)$ /index.php?product=$1 [L]
RewriteRule ^article/([0-9]+)$ /index.php?article=$1 [L]
RewriteRule ^blog/([a-zA-Z0-9-]+)$ /blog&post=$1 [L]

htaccess rules - multi-language website

I created a language script in my website. This script recognizes the language in the URL and loads the language definitions.
For example:
RewriteRule ^(.+)/about/?$ sobre2.php?lang=$1 <-- working fine
RewriteRule ^(.+)/contact/?$ contato2.php?lang=$1 <-- working fine
RewriteRule ^(.+)/products/?$ produtos2.php?lang=$1 <-- working fine
RewriteRule ^(.+)/contact/sales/?$ contato-vendas2.php?lang=$1 <-- working fine
RewriteRule ^(.+)/contact/general/?$ contato-form2.php?lang=$1 <-- working fine
The pages above are accessed, respectively, as this:
https://domain.com/b2b/pt-br/about/
https://domain.com/b2b/pt-br/contact/
https://domain.com/b2b/pt-br/products/
https://domain.com/b2b/pt-br/contact/sales/
https://domain.com/b2b/pt-br/contact/general/
This is working fine in all pages, except index.
When I try to do the same thing with the index page, using this code:
RewriteRule ^(.+)/?$ index2.php?lang=$1
Besides it doesn't work, it also affects all the other pages (and resources), so the resources are not loaded and the page looks like a "pure html".
I'd like to know how can I configure the htaccess to make my "index2.php" be accessible like this:
https://domain.com/b2b/pt-br/
Thank you.
.+ will match 1 or more of any character and if you place rule before other rules then this will make other rules ineffective.
You can use these rules:
RewriteEngine On
RewriteBase /b2b/
RewriteRule ^((?!pt-br/).*)$ pt-br/$1 [L,R=301,NC]
RewriteRule ^(.+)/about/?$ sobre2.php?lang=$1 [L,QSA]
RewriteRule ^(.+)/contact/?$ contato2.php?lang=$1 [L,QSA]
RewriteRule ^(.+)/products/?$ produtos2.php?lang=$1 [L,QSA]
RewriteRule ^(.+)/contact/sales/?$ contato-vendas2.php?lang=$1 [L,QSA]
RewriteRule ^(.+)/contact/general/?$ contato-form2.php?lang=$1 [L,QSA]
RewriteRule ^([a-z]{2}-[a-z]{2})/?$ index2.php?lang=$1 [NC,L,QSA]

htaccess convert underscores to hyphens for all files starting with the word "article"

I tried another way to do this, but it ended up crashing my server by using up all the memory.
My server admins came up with a second approach:
RewriteRule ^([^_]*)_([^_]*)_([^_]*)_([^_]*)_([^_]*)_([^_]*)_(.*)$ $1-$2-$3-$4-$5-$6-$7 [E=underscores:Yes]
RewriteRule ^([^_]*)_([^_]*)_([^_]*)_([^_]*)_([^_]*)_(.*)$ $1-$2-$3-$4-$5-$6 [E=underscores:Yes]
RewriteRule ^([^_]*)_([^_]*)_([^_]*)_([^_]*)_(.*)$ $1-$2-$3-$4-$5 [E=underscores:Yes]
RewriteRule ^([^_]*)_([^_]*)_([^_]*)_(.*)$ $1-$2-$3-$4 [E=underscores:Yes]
RewriteRule ^([^_]*)_([^_]*)_(.*)$ $1-$2-$3 [E=underscores:Yes]
RewriteRule ^([^_]*)_(.*)$ $1-$2 [E=underscores:Yes]
RewriteCond %{ENV:underscores} ^Yes$
RewriteRule (.*) http://www.mydomain.tld/$1 [R=301,L]
This approach seems more stable and doesn't use up memory.
The only problem is that this approach affects all files on the server, not just files that start with the word "article", such as http://www.mydomain.tld/article...
That doesn't work because this is a WordPress installation, and it tries to change all WordPress theme files that use underscores, rendering significant parts of the website unusable.
Can anyone suggest a way to modify this code to make it only apply when the word "article" is involved file name part of the URL?
Replace all of your rules with these 2 rules:
RewriteRule "^(article)/([^_]*)_+([^_]+_.*)$" /$1/$2-$3 [N]
RewriteRule "^(article)/([^_]*)_([^_]*)$" /$1/$2-$3 [L,R=301]
It turns out that there was, indeed, a solution to my inquiry. The following modification worked just fine:
RewriteRule ^article([^_]*)_([^_]*)_([^_]*)_([^_]*)_([^_]*)_([^_]*)_(.*)$ $1-$2-$3-$4-$5-$6-$7 [E=underscores:Yes]
RewriteRule ^article([^_]*)_([^_]*)_([^_]*)_([^_]*)_([^_]*)_(.*)$ $1-$2-$3-$4-$5-$6 [E=underscores:Yes]
RewriteRule ^article([^_]*)_([^_]*)_([^_]*)_([^_]*)_(.*)$ $1-$2-$3-$4-$5 [E=underscores:Yes]
RewriteRule ^article([^_]*)_([^_]*)_([^_]*)_(.*)$ $1-$2-$3-$4 [E=underscores:Yes]
RewriteRule ^article([^_]*)_([^_]*)_(.*)$ $1-$2-$3 [E=underscores:Yes]
RewriteRule ^article([^_]*)_(.*)$ $1-$2 [E=underscores:Yes]
RewriteCond %{ENV:underscores} ^Yes$
RewriteRule (.*) http://www.mydomain.tld/article$1 [R=301,L]
Panama Jack: if I were you, I wouldn't assume that the other solutions given weren't problematic, because as it turned out, they were. I can't say why, but I know that this solution stopped the memory drain and allowed the server to function normally. Are there other things that contribute to a memory drain? Of course! But that doesn't mean that the previous solutions I received couldn't also contribute to the memory issue.

.htaccess 301 redirect problem

i try to redirect url's like:
example.com/video/1640/video-name
to
example.com/video/1640/video-name/
i've tried with:
RewriteRule ^video/([^/]*)/([^/]*)/$ video.php?id=$1&title=$2 [L]
RewriteRule ^video/([^/]*)/([^/]*)$ /video/([^/]*)/([^/]*)/ [R=301,L]
but it is not working
my currently htaccess file has only the first line:
RewriteRule ^video/([^/]*)/([^/]*)/$ video.php?id=$1&title=$2 [L]
and videos only loads at
example.com/video/1640/video-name/
url type
i want to redirect the non-backslash url type
example.com/video/1640/video-name
to the correct one (the one with the backslash)
How can i do this?
Your second rule should be RewriteRule ^video/([^/]*)/([^/]*)$ /video/$1/$2/ [R=301,L]
Or you could forgo the redirect totally, and just say RewriteRule ^video/([^/]*)/([^/]*)/?$ video.php?id=$1&title=$2 [L] which will allow both to view your video.
Update FallingBullets is right (see the comments on this answer), his answer better suites the OP's problem, so please ignore this answer (I am leaving it for reference, though).
Maybe you simply have to prefix your pattern with a /?? E. g.
RewriteRule ^/?video/([^/]*)/([^/]*)/$ video.php?id=$1&title=$2 [L]
RewriteRule ^/?video/([^/]*)/([^/]*)$ /video/([^/]*)/([^/]*)/ [R=301,L]
# ^ these ones
instead of
RewriteRule ^video/([^/]*)/([^/]*)/$ video.php?id=$1&title=$2 [L]
RewriteRule ^video/([^/]*)/([^/]*)$ /video/([^/]*)/([^/]*)/ [R=301,L]
since you are anchoring the pattern at the beginning of the path (using ^).

Resources