Trouble with 2 RewriteRule - apache

I have a trouble with two Rewriterule in my htaccess
RewriteRule ^(.*)/(.*)/(.*)/([0-9]+)/?$ viewauthor.php?lg=$1&cat=$2&nameauthor=$3&id=$4 [NC,L]
RewriteRule ^(.*)/(.*)/(.*)/([0-9]+)/?$ viewbook.php?lg=$1&cat=$2&namebook=$3&id=$4 [NC,L]
I can't access to the second rewriterule cause it's similar.
to see which page I am on. I put echo $_SERVER['QUERY_STRING']; in those two page.
When I remove the flag [NC,L], I access to the second rewriterule but the lg=viewauthor.php instead lg=en.

You need a prefix to differentiate but you don't capture it, it's just used to match a rule:
RewriteRule ^author/(.*)/(.*)/(.*)/([0-9]+)/?$ viewauthor.php?lg=$1&cat=$2&nameauthor=$3&id=$4 [B,NC,L]
RewriteRule ^book/(.*)/(.*)/(.*)/([0-9]+)/?$ viewbook.php?lg=$1&cat=$2&namebook=$3&id=$4 [B,NC,L]
Now make your URLs like /author/foo/far/faz/1 and /book/boo/bar/baz/2. Note the addition of the B flags.

Related

Add hyphen to clean URL with htaccess

I am following the single page approach for my website, all the GET requests were built like: index.php?ressource=product&identifier=5
To achieve clean URLs, I have found a generator which created this:
RewriteEngine On
RewriteCond %{HTTPS} !^on$ [NC]
RewriteRule . https://%{HTTP_HOST}/ [L] HTTPS_HOST ???
RewriteEngine On
RewriteRule ^([0-9a-zA-Z]+)/([0-9a-zA-Z]+)/([0-9a-zA-Z]+)$ ?ressource=$1&identifier=$2&action=$3 [L]
RewriteRule ^([0-9a-zA-Z]+)/([0-9a-zA-Z]+)$ ?ressource=$1&identifier=$2 [L]
#EOF
I have added the first three lines to force the user's client to go to my https site.
Now I also would like to have a hyphen within the identifier value, something like article/terms-of-service.
I did some research and I need to either use the NC, QSA or both flags, but whenever I add one of those flags I get the Server Error 500.
Okay, i have found the solution to add hyphen within the clean urls:
RewriteEngine On
RewriteRule ^([a-z]+)/([0-9a-üA-Ü\-]+)/([a-z]+)$ ?ressource=$1&identifier=$2&kwargs=$3 [L]
RewriteRule ^([a-z]+)/([0-9a-üA-Ü\-\%\s]+)$ ?ressource=$1&identifier=$2 [L]
RewriteRule ^([a-z]+)$ ?ressource=$1 [L]
the hyphen character had to be added to the regular expression

Apache mod_rewrite rule to hide URI part

I need to cut some part of URI, but I still need to pass it internally.
Ex: www.hostname.com/category/N-abcdef
To: www.hostname.com/category
But I need internally to do a redirect passing N-abcdef
If I put these rules, it work:
RewriteRule ^/category/N-abcdef$ /category [R=301]
RewriteRule ^/category$ /category/N-abcdef [PT]
But I was trying to do something more generic, because the N-.* is different for each category. I've tried these:
RewriteCond %{REQUEST_URI} ^/(.*)/(N-.*)/?$
RewriteRule ^/(.*)/(N-.*)/?$ /$1 [R=301]
RewriteRule ^/(.*)$ /$1/%2 [PT]
These rules even remove the desired part (N-.*), But does not make the internal redirect correctly, as the reported result is not desirable.
In short, I need to hide the N-FOO URI.
Any suggestion?

Escape string within RewriteRule

I am currently chewing on this problem: I am reworking a sort of CMS system, the result will be that URLs will look entire differently, but I want to save links and bookmarks, so I scrathced this .htaccess file together:
RewriteEngine on
# Rewrite old links to match with new URL syntax:
# universal rewrite
RewriteCond %{REQUEST_URI}~%{QUERY_STRING} ^(.*?\/*)? (viewuser|viewstory|reviews|news)\.php~(.+)$ [NC]
RewriteRule ^(.+).php$ %1?action=redirect&source=$1&%3 [R=301,L,NE]
And it works, http://example.com/news.php?action=newsstory&nid=51 actually becomes http://example.com/?action=redirect&source=news&action=newsstory&nid=51
But you can see the problem, a double action. Using 'action' is not the most inventive term, but it is what the script I need to feed is working with, and also what I am getting from the old one, so I need to either:
replace the second 'action' with anything else
or serialize/escape the entire part which is defined by %3 from, the RewriteCond
In case you are wondering, the question mark required the use of a RewriteCond, couldn't get it to work any other way, so any solution that gets rid of it is just as welcome.
Well, thanks for looking into and maybe even shedding a light onto things, I just made my way into the whole regex thing, but havewn't entirely figured how variables are passed from chained RewriteRule to another, maybe that would have been the way to got, but try and error didn't get me anywhere.
Try removing the NE flag and use a B:
RewriteCond %{REQUEST_URI}~%{QUERY_STRING} ^(.*?\/*)?(viewuser|viewstory|reviews|news)\.php~(.+)$ [NC]
RewriteRule ^(.+).php$ /?action=redirect&source=$1&%3 [R=301,L,B]
The only problem is that the %1 backreference will get encoded as well so I left that out. If you must have it there, you can try doing a two step rewrite:
RewriteCond %{REQUEST_URI}~%{QUERY_STRING} ^(.*?\/*)?(viewuser|viewstory|reviews|news)\.php~(.+)$ [NC]
RewriteRule ^(.+).php$ /special-rewrite-here?action=redirect&source=$1&%3 [L,B]
RewriteCond %{THE_REQUEST} ^[A-Z]+\ (.*?\/*)?(viewuser|viewstory|reviews|news)\.php~(.+)$ [NC]
RewriteRule ^special-rewrite-here$ /%1 [L,R=301]
Fixed with help from Jon Lin:
RewriteCond %{REQUEST_URI}~%{QUERY_STRING} ^(.*?\/*)? (viewuser|viewstory|reviews|news)\.php~(.+)$ [NC]
RewriteRule ^(.+).php$ /special-rewrite-here?action=redirect&source=$1&old_data=%3 [B]
RewriteCond %{REQUEST_URI}~%{QUERY_STRING} ^(.*?\/*)? (viewuser|viewstory|reviews|news)\.php~(.+)$ [NC]
RewriteRule ^/.+$ %1 [L,R=301]
I had to do the RewriteCond again to preserve %1, and had to modify the second RewriteRule slightly, but he sure got me on the right track, so: problem solved, the rest will take place in PHP, that should be no problem then.

Mod_rewrite in two directions?

An existing page is called /foo/bar.php. What I have done is a rewrite so that when a user types /foobar, it load the contents of /foo/bar.php (while keeping /foobar in the url bar)
But I also want the opposite - when a user clicks on a link or types /foo/bar.php, I want to have /foobar in the url. The reason is to avoid manually changing all the links.
How could I do that (if possible without an http redirect, but via some rewrite magic)? And is it possible for those two rules to co-exist?
Edit - After the first response, I realized my description of the problem was not proper. /foobar is not supposed to be a concatenation of foo, bar of /foo/bar.php, but an arbitrary string (/whatever).
Edit 2:
I now added RewriteRule ^whetever/?$ /foo/bar.php [L] in the / .htaccess. Then I added RewriteRule bar\.php$ /whetever [R=302,L] in the /foo .htaccess. The problem is it 's a circular reference and fails.
Thanks,
John
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/foo/[^/]+\.php$
RewriteCond %{IS_SUBREQ} !true
RewriteRule ^/foo/([^/]+)\.php$ /foo$1 [R,L]
RewriteCond %{REQUEST_URI} ^/foo[^/]
RewriteRule ^/foo(.*) /foo/$1.php [L]
The first part matches /foo/something.php and transforms them into /foosomething, but only if it is not a sub-request.
The second part takes any /foosometing and transforms it into /foo/something.php, via sub-request
You can try matching against %{THE_REQUEST} and only do the redirect when the actual request is for the php file:
RewriteEngine On
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /foo/bar\.php
RewriteRule bar\.php$ /whatever [R=302,L]
RewriteRule ^whatever/?$ /foo/bar.php [L]

mod_rewrite weird problem

I have a strange problem with mod_rewrite, the rules that are relevant here are:
RewriteRule ^(.*)\/igre\-(.*)\.php\?Page=([0-9]+)$ game.php?GameUrl=$2&Page=$3 [L]
RewriteRule ^(.*)\/igre\-(.*)\.php$ game.php?GameUrl=$2&Page=1 [L]
And a corresponding URL might look something like this:
example.com/miselne-igre/igre-shirk.php?Page=2
example.com/miselne-igre/igre-shirk.php
The problem is that the first rule has no effect. If I use the first URL from the example I always get 1 into the Page variable, which shows that the second rule is used.
So what's wrong with the first one? And why is the second rule even matching a URL with ".php?Page=XYZ" at the end, if I said that the URL ends with ".php"?
ps: other rules in the .htaccess file are working fine...
The query string is not part of the URI path that is being processed by the RewriteRule directive. You have to use the RewriteCond directive to process the query string.
RewriteCond %{QUERY_STRING} ^Page=[0-9]+$
RewriteRule ^[^/]+/igre-([^/]+)\.php$ game.php?GameUrl=$1&%0 [L]
RewriteRule ^[^/]+/igre-([^/]+)\.php$ game.php?GameUrl=$1&Page=1 [L]
But you can still simplify this by using the QSA flag (query string append):
RewriteRule ^[^/]+/igre-([^/]+)\.php$ game.php?GameUrl=$1 [L,QSA]
mod_rewrite is not using the query in it's rewriting process. Therefor you first RewriteRule is ignored. You could combine it with a RewriteCond (haven't tested it though) like so:
RewriteCond %{QUERY_STRING} Page=([0-9]+)
RewriteRule ^(.*)\/igre\-(.*)\.php\?Page=([0-9]+)$ game.php?GameUrl=$2 [L, qsappend]
# qsappend appends the original query, in this case (Page=xx)
Ah, like Gumbo said; you can also use %1 to back reference to the page numer.
Is it just me or are your arguments back-to-front?
Do you mean:
RewriteRule ^(.*)\/(.*)\-igre\.php\?Page=([0-9]+)$ game.php?GameUrl=$2&Page=$3 [L]
RewriteRule ^(.*)\/(.*)\-igre\.php$ game.php?GameUrl=$2&Page=1 [L]
You wanted to match miselne-igre not igre-miselne.
Obviously this doesn't address the main issue, but thought I'd throw that in.
Dom