Mod Rewrite Wilcard Subdomain - Internal Pages - apache

i am able to get subdomain variables (product name and language) with php via $_SERVER["HTTP_HOST"]
http://product.en.example.com
I do not know how to make to work in browser these urls for internal pages:
product.en.example.com/images
product.en.example.com/images/john
product.en.example.com/hobbies
product.en.example.com/hobbies/smith
images, hobbies = pageType
john, smith = peopleName
I think i should get the pageType via php query strings (GET) and serve the corresponding layout.
In .htaccess i have:
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\.
RewriteCond %{REQUEST_URI} !index\.php
RewriteCond %{HTTP_HOST} ^(.+?)\.(.+?)\.example\.com/$
RewriteRule (.+).(.+)\.example\.com\/(.*) /index.php [L]

There are multiple ways to achieve this. First of all you can parse the request uri in php using $_SERVER['REQUEST_URI'] which contains the requested URI.
An alternative is to use your .htaccess file. In this case you would not even have to parse the server name in php:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{HTTP_HOST} ^(.*?)\.?([^\.]+?)\.example\.com$
RewriteRule ^([^/]*)?/?(.*?)/?$ /index.php?product=%1&language=%2&pageType=$1&peopleName=$2 [L]
Note that I added the rule RewriteCond %{REQUEST_FILENAME} !-f instead of your check against index.php because this way you can serve assets like your css files without having them redirected to index.php.
Beware that HTTP_HOST has no trailing slash.
EDIT
As requirested in the comments:
In order to add another optional parameter you can use ([^/]*)?/?. Therefore the RewriteRule could look like:
RewriteRule ^([^/]*)?/?([^/]*)?/?(.*?)/?$ /index.php?product=%1&language=%2&pageType=$1&peopleName=$2&peopleAge=$3 [L]

Related

Both URL With PHP and Non-PHP Access after RewriteRule In Htaccess

Access Both URL With PHP and Non-PHP in PHP project after applying Htacces Rules
RewriteRule ^c/([a-zA-Z0-9-/]+)$ category.php?id=$1 [L]
RewriteRule ^p/([a-zA-Z0-9-/]+)$ detail.php?post=$1 [L]
Here I access both URLs like www.example.com/c/category-name and www.example.com/category.php?id=12 but I want only www.example.com/c/category-name URL. I don't Want Duplicate URLs both this page.
With your shown samples, attempts please try following htaccess rules. Make sure to clear your browser cache before testing your URLs.
RewriteEngine ON
##Internal rewrite rules.
RewriteCond %{HTTP_HOST} ^(?:www\.)?example.com$ [NC]
RewriteRule ^c/([\w-]+)/?$ category.php?id=$1 [QSA,NC,L]
##External redirect rules.
RewriteCond %{HTTP_HOST} ^(?:www\.)?example.com$ [NC]
RewriteCond %{THE_REQUEST} \s/category\.php?id=(\S+)\s [NC]
RewriteRule ^ /c/%1? [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^[^/]*/(.*)/?$ category.php?id=$1 [QSA,NC,L]
Unless you have changed an existing URL structure and category.php and/or detail.php have been indexed by search engines then you could simply force a 404 when either of these URLs are accessed directly.
For example, the following should go before your existing rewrites:
# Block direct access to "category.php" or "detail.php"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(category|detail)\.php$ - [R=404]
The check against the REDIRECT_STATUS env var ensures that we are only checking direct requests and not rewritten requests by the later rewrite.
Otherwise, if these "old" URLs have previously been indexed by search engines or linked to by third parties then you should redirect to the "new" (canonical) URLs instead. For example:
# Redirect "category.php" or "detail.php" to canonical URL
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ^(?:id|post)=([a-zA-Z0-9/-]+)$
RewriteRule ^(?:(c)ategory\.php|detail\.(p)hp)$ /$1/%1 [R=301,L]
I've moved the hyphen to the end of the character class (ie. from [a-zA-Z0-9-/] to [a-zA-Z0-9/-]) to avoid a potential ambiguity since hyphens are naturally special characters inside a character class.
The $1 backreference contains either c or p, depending on the request, to form the first path segment. %1 is the value captured from the URL-parameter. Importantly, this is the same regex you are using the later rewrite to match the value.
NB: Test first with a 302 (temporary) redirect to avoid potential caching issues.

Redirecting all urls, including no path, to a file in subdirectory

I have checked a large amount of existing answers regarding .htaccess redirects. However none of them have helped me.
What I want to accomplish is redirecting all request urls to /api/init.php. However I've only gotten so far to where my index page www.example.com simply gives me a file listing because of the missing index.php file, while every url request with a path is working.
How can I accomplish this with .htaccess without ending up with a directory listing on my landing page?
This is as far as I got:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /api/init.php?path=$1 [NC,L,QSA]
Well your site root is a directory, so this rule you have excludes existing directories. What you could do is only exclude existing files, and allow existing directories to be handled by the PHP script. Like this:
RewriteEngine on
RewriteCond %{REQUEST_URI} !=/api/init.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /api/init.php?path=$1 [L,QSA]
I removed the NC flag as it's not needed. I added a condition to prevent an unnecessary file-system check.
You don't have to pass the path on in a URL parameter, as you could get it from $_SERVER['REQUEST_URI'] in PHP (not the same as REQUEST_URI in mod_rewrite, in PHP it always has the original URI). If you wanted to do that then your rule becomes nice and simple:
RewriteEngine on
RewriteCond %{REQUEST_URI} !=/api/init.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ /api/init.php [L]
Because the query string will just be passed on unaffected (so QSA is not needed).

Keep URL request but adjust server path

How can I achieve the following:
I have two domains hosted within the same web root path on the server. Usually php manages my HTTP_Hosts dynamically. Related to my question I am using the directory lisings function of apache. Each Request for /peter/ should point effectively to a different directory.
example.com/peter/ -> /peter_example.com/
xamplee.com/peter/ -> /peter_xamplee.com/
The Url should always contain /peter/ but in effect link to the respective real path which I'd like to have hidden.
Thank you!
Finally, after getting into regex and into mode_rewrite the hard way I can come up with the solution all by myself:
Options -MultiViews
RewriteEngine On
RewriteBase /
# Force adding a trailing Slash
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*[^/])$ /$1/ [L,R=301]
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
RewriteRule ^peter/(.*)$ /peter_example\.com/$1 [NC,L]
RewriteCond %{HTTP_HOST} ^www\.xamplee\.com$ [NC]
RewriteRule ^peter/(.*)$ /peter_xamplee\.com/$1 [NC,L]

.htaccess rewrite to simultaneously change domain and remove path

My URL structure is currently as follows:
http://domain.com/folder/filename (CURRENT)
I want to change this so that I can use the following URL instead:
http://sub.domain.com/filename (NEW)
So accessing the CURRENT or the NEW url, should load the file located at the CURRENT url, but show the NEW url in the address bar. It should only apply to the "/folder/" path.
sub.domain.com is a mirror of domain.com, ie. they share the same file system and root directory.
This is what I have so far:
Options +FollowSymLinks
RewriteBase /
RewriteCond %{HTTP_HOST} ^(www.)?domain.com$ [NC]
RewriteCond %{REQUEST_URI} ^/folder/?(.*)$ [NC]
RewriteRule ^(.*)$ http://sub.domain.com/$1 [R=301,L]
This is working, but is missing the rule to remove the "/folder/" from the path. I've tried combining multiple RewriteRule's with no luck. Any ideas? Thanks.
UPDATE: Thanks again #Gerben - I understand what your rules are doing now, but the second one isn't working for me. I suspect because it's conflicting with some other rewrite rules, in particular those of WordPress, which are lower down in my .htaccess file:
# BEGIN WordPress
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress
Because of this the page ends up in a redirect loop, ie (from Chrome):
"The webpage at http://sub.domain.com/folder/index.php has resulted in too many redirects." - while the url I was originally trying to access was, for example, http://sub.domain.com/page
Any ideas?
Try:
RewriteCond %{HTTP_HOST} ^(www.)?domain.com$ [NC]
RewriteRule ^(folder/)?(.*)$ http://sub.domain.com/$2 [R=301,L]
This will redirect everything to sub.domain.com, and remove the /folder part of the URI if it is there. If not, it redirects and leaves the URI untouched.
RewriteCond %{THE_REQUEST} /folder/
RewriteRule ^folder/(.*)$ http://sub.domain.com/$1 [R=301,L]
RewriteCond %{HTTP_HOST} ^sub\.domain\.com$ [NC]
RewriteCond %{REQUEST_URI} !^/folder/
RewriteRule ^(.*)$ folder/$1 [L]
# WordPress rules here
edit the second R=301 should not have been there
But this won't work, as wordpress has no way of knowing you want folder. You could add the Proxy flag to the rewrite, but then you need to change the rule above to not redirect on this internal proxy request.

htaccess url rewrite help

I have the following rewrite URL:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Rewrite all other URLs
RewriteRule ^(.*)$ index.php?page=$1 [PT,L]
Now I want to add an exception, that if the URL is something like mysite.com/abc it should ignore it and all things inside it also. mysite.com/abc/dfgs also should be excluded from this rewriting.
How can I accomplish this?
If /abc is an existing directory, you can put another .htaccess file in there with
RewriteEngine Off
If it's really just one string you want to not rewrite (whether it exists or not)
RewriteCond %{REQUEST_URI} !^/abc
will not rewrite if the requested path starts with "/abc"
To test rewrite rules without messing up the site for regular browsers (not that you should be editing in a live environment of course, this is purely hypothetical :-) ), I've found the following very helpful:
RewriteCond %{REMOTE_ADDR} 12.34.56.78 # <-- where that's your IP address
This should avoid rewriting if the URI contains abc. This may or may not be exactly what you want. If it isn't edit your question.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
#Rewrite ONLY if the REQUEST does NOT contain abc
RewriteCond %{REQUEST_URI} !abc
# Rewrite all other URLs
RewriteRule ^(.*)$ index.php?page=$1 [PT,L]