rewrite rule for an URL with 2 queries - .htaccess

My URL looks like this:
example.com/index.php?f=directory&s=page
I want it to be like this instead:
example.com/directory/page
my rewrite rules look like this right now:
RewriteRule ^([A-Za-z0-9]+).html$ https://www.example.net/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^/?(.*?)/?$ index.php?s=$1 [L]
it appears to work but not quite because if I call the queries in PHP I get something like this:
print $_GET['f'] */ it prints nothing
print $_GET['s'] */ it prints directory/page
which is not what I intend. How can I fix it?
Thank you.

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^/?(.*?)/?$ index.php?s=$1 [L]
Do it like this instead:
RewriteRule ^([^/]+)/([^/]+)$ index.php?f=$1&s=$2 [L]
Request /directory/page and it internally rewrites the request to index.php?f=directory&s=page.
By making the regex more specific, the filesystem checks can probably be avoided.
To redirect from index.php?f=directory&s=page to /directory/page (if these URLs have already been indexed and/or linked to by third parties), then add the following redirect before the above directive:
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ^f=([^&]+)&s=([^&]+)$
RewriteRule ^index\.php$ /%1/%2 [R=301,L]
But you must already be linking to the canonical /directory/page URL in your application.
Test with 302s to avoid potential caching issues. Clear your browser cache before testing.
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^/?(.*?)/?$ index.php?s=$1 [L]
You are only assigning a single URL parameter s, so yes, $_GET['f'] will indeed be empty.

Related

Switching language with .htaccess

I want to add another language to my website (an app written in PHP 7).
I found out, good SEO practices say that every page on my site should be accessible from differend URLs, depending on the language.
Currently my .htaccess looks something like this:
RewriteEngine on
Options +FollowSymLinks
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^([a-zA-z0-9-]+)$ $1.php [NC,L]
So when user types in (or clicks a link) http://example.com/contact they get page contact.php (if exists).
What I want to achieve is, to redirect http://example.com/en/contact to the very same file contact.php, but with $_GET argument and still redirecting /contact to contact.php (without this argument). I thought that would be:
... everything from above code sample and then:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^en/([a-zA-z0-9-]+)$ $1.php?lang=en [NC,L]
But it doesn't work. Any ideas why and how to make this work?
Last condition checks that en/file.php exists, which is never the case. That's why the rule is never met. Either you remove it (but it will be applied even on nonexistent files) or you use this workaround by rewriting the faulty condition
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1\.php -f
RewriteRule ^en/([^/]+)$ /$1.php?lang=en [NC,L]
To be more complete, you can also redirect users that try to access /contact.php?lang=en directly (better for SEO). Here is how your final htaccess should look like
RewriteEngine On
# if url is /file.php?lang=en and file exists then redirect to /en/file
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{THE_REQUEST} \s/([^/\s\?&]+)\.php\?lang=en\s [NC]
RewriteRule ^ /en/%1? [R=301,L]
# if url is /en/file and /file.php exists then internally rewrite to /file.php?lang=en
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1\.php -f
RewriteRule ^en/([^/]+)$ /$1.php?lang=en [NC,L]
Note: the above code is specific to en language, but you can easily adapt it to multiple languages

Remove duplicate content issue using htaccess

My .htaccess file looks likes this:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php?pg=$1 [L]
When a non-file or non-dir url is requested, it works fine.
But if index.php?pg=(pagename) is requested, it also works which can possibly lead to duplicate content issue.
Is there a way to prevent this?
You're right, this can lead to duplicate content.
And, yes, it is possible to avoid it.
This solution redirects old url to new url equivalent, for instance http://website.com/index.php?pg=get/my/page/please.html to http://website.com/get/my/page/please.html.
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} \s/index\.php\?pg=([^&\s]*)\s [NC]
RewriteRule ^ %1? [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?pg=$1 [L]

Need to rewrite parameters AND redirect with htaccess

I need to simultaneously do two things with htaccess.
I need to take a URL like:
http://client.example.com/123
and rewrite the directory to a param, and simultaneously add another subdomain to the url so it looks like this:
http://client.qa.example.com/?param=123
This does the param bit correctly, but I can't figure out how to add the subdir:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^/[^/]+/?$
RewriteRule ^([^/]*)/?$ /?param=$1 [L]
You can examine the host header using a RewriteCond and extract the relevant parts of the name. Use them in the rewrite. Back references to matches in RewriteConds appear as %n
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{HTTP_HOST} (.+?)\.(.*)
RewriteRule ^([^/]*)/?$ http://%1.qa.%2/?param=$1 [R,L]
(.+?)\.(.*) will do a match on everything up to the first . and then everything to the end. So client and example.com will respectively be in %1 and %2
If your .htaccess is in the root of client.example.com, it should be a simple redirect. Of course the directory has to be a fake directory or this won't redirect.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/?$ http://client.qa.example.com/?param=$1 [R=301,QSA,L]
You can use the following to match (check for htaccess syntax):
(http://[^.]+\.)([^/]+/)([^/]*)/?$
And replace with:
$1qa.$2?param=$3
See DEMO
Finally got it working using:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{HTTP_HOST} (.+?)\.(.*)
RewriteRule ^([^/]*)/?$ http://%1.qa.%2/?param=$1 [R,L]
Now I just have to figure out how to work in 2 parameters, given that param 2 isn't always going to be present.

rewrite url to root directory with url cutting

I have such urls:
http://site.ru/ontent/wefwefw/article.php?article=369-tayskaya-kuhnya-recept-s-foto
http://site.ru/ontent/wefwefw/article.php?article=32237-ogurci-recepti-na-zimu
http://site.ru/ontent/wefwefw/article.php?article=90-ogurci-na-zimu-recepti-po-koreyski
I want to rewrite tham like:
http://site.ru/tayskaya-kuhnya-recept-s-foto.html
http://site.ru/ogurci-recepti-na-zimu.html
I tried smth like:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ ontent/wefwefw/$1 [L]
But how cut unnecessary parts of string?
Unless article.php is able to derive the right article from the title alone, what you want to do is not possible. mod_rewrite is good at rewriting things, but it can't summon an article-id from thin air if it isn't in the original request. You would have something like:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+)\.html$ ontent/wefwefw/article.php?article=$1 [L]
When you would request http://site.ru/tayskaya-kuhnya-recept-s-foto.html, it will load http://site.ru/ontent/wefwefw/article.php?article=tayskaya-kuhnya-recept-s-foto. Then you have to get the id 369 in some other way based on the title if needed.
The best in this case is:
http://site.ru/369-tayskaya-kuhnya-recept-s-foto.html
redirect to
http://site.ru/ontent/wefwefw/article.php?article=369
with:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(\d+)-[^/]*\.html$ ontent/wefwefw/article.php?article=$1 [L]

if url not exist htaccess rewrite

I'm newbie in htaccess..
I have some conditions like this..
if user access
first/second/third
it's equal to
first.api.php?rquest=second&attr=third
but if the value of rquest is 'index', it will be erased from URL, like
first/third
equal to
first.api.php?rquest=index&attr=third
not
first/index/third
I had all night looking for solution, but no result.
I know system being confused if the request is index but attr has a value, it will treat the attr like rquest. see above, first/third, system will treat the 'third' segment as rquest.
Is it possible to rewrite url like that?
this is my work all night, I know this is still crap..
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s
RewriteCond %{QUERY_STRING} !rquest=index
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/?$ $1.api.php?rquest=$2&attr=$3 [NC]
RewriteRule ^([a-zA-Z0-9_-]+)/(.*)$ $1.api.php?rquest=$2 [QSA]
RewriteCond %{REQUEST_FILENAME} -s
RewriteCond %{QUERY_STRING} rquest=index
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)$ $1.api.php?rquest=index&attr=$2 [NC]
RewriteRule ^([a-zA-Z0-9_-]+)$ $1.api.php?rquest=index [QSA,L]
</IfModule>
Try something like this:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/?$ /$1.api.php?rquest=$2&attr=$3 [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/?$ /$1.api.php?rquest=index&attr=$2 [L,QSA]
Not clear what you were trying to achieve with your old rewrite rules, but the above should do what you've described.

Resources