I'm new to apache & php world and I struggle with .htaccess redirections.
Here is what I want to do:
people of trust will have access to a dedicated directory in /members.
/ => index.php
/<user> => /members/<user>/index.{php,html}
/<user>/... => /members/<user>/...
/<user>/reload = > index.php?reload=<user>
Directory layout:
- index.php
- .htaccess
- members/
- <user1>/
- member's html/php
- <user2>/
What I've done so far (not working):
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www.subdomain.exemple\.com [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.subdomain.exemple.com/$1 [R,L]
RewriteCond %{HTTP_HOST} ^subdomain.exemple\.com [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.subdomain.exemple.com/$1 [R,L]
RewriteRule ^/$ index.php [L]
RewriteRule ^$ index.php [L]
# [a-z]+ is member's username
RewriteRule ^([a-z]+)/reload/$ index.php?reload=$1 [L]
RewriteRule ^([a-z]+)/reload$ index.php?reload=$1 [L]
#ROOT (I don't know how to redirect to php or html depending on which file exists)
RewriteRule ^([a-z]+)/$ members/$1/index.php [L]
RewriteRule ^([a-z]+)$ members/$1/index.php [L]
#Every other URL excluding / and /<user>/reload
RewriteRule ^(.+)$ members/$1 [L]
I also want to "isolate" members' directory by prohibiting php scripts to access parent directories. I've found this but does it mean I should write a rule for each member's directory?
<Directory /parentDirectory/childDirectoryOne>
php_admin_value open_basedir "/parentDirectory/childDirectoryOne"
</Directory>
I've finally managed to get it work.
To avoid the loop mentioned by #arkascha, I added a negative lookahead (?!members). But at the website's root, index.php was redirected to /members/index.php. So I append a second negative lookahead (?!index.php).
The last struggle was that exemple.com/user was redirected to exemple.com/members/user. Couldn't resolve this one on purpose, but it works. Here is the final code :
RewriteRule ^(?:members)?([a-z]+)/reload/?$ index.php?reload=$1 [L]
RewriteRule ^(?!members)(?!index.php)(.+)$ members/$1 [L]
Concerning the "isolation" of member's directories, I still have no solution.
Related
I want to create pretty url. But, I got some problem with .htaccess. For example I have url domain/some.php?f=query-string.
I want to change domain/query-string (expected url). Is that possible to change / redirect via .htaccess. Or maybe from php file itsself.
this is a bit of htaccess snippet i made, but i get it blank/error page
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
RewriteRule ^/([^/.]+)$ some.php?f=$1 [NC,L]
</IfModule>
Thanks for your attention.
RewriteRule ^/([^/.]+)$ some.php?f=$1 [NC,L]
In .htaccess, the URL-path matched by the RewriteRule pattern does not start with a slash, so the above will never match and it will do nothing. This should be written like the following instead:
RewriteRule ^([^/.]+)$ some.php?f=$1 [L]
The NC flag is not required here, since the regex is already "case-insensitive".
So I have 2 domain names on one server 2 different sites I have mod-rewrite on the one domain name which I would like to work for the one domain name only but when I upload the .htaccess file the 1 domain name works great but the other site / domain name shows
Not Found
The requested URL was not found on this server.
Additionally, a 404 Not Found _error_ was encountered while trying to use an ErrorDocument to handle the request.
If I remove the mod rewrite file the second site works and shows but the first site needs the mod rewrite to work
is there any way to set the mod rewrite to only run for the one domain name?
Just wanted to add the main domain name is in the root and the second domain name is in a file in the root so I want all the conditions to work for domain name 1 which is in the root but not domain name 2 which is in a folder in the root. When I visit domain name 2 I get a 404 error.
options -multiviews
options All -Indexes
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} mydomainname.com$ [NC]
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^home$ index.php
RewriteRule ^dashboard$ dashboard.php
RewriteRule ^advertiser$ advertiser.php
RewriteRule ^add_campaign$ add_campaign.php
RewriteRule ^edit_campaign$ edit_campaign.php
RewriteRule ^stats$ view_statistics.php
RewriteRule ^login$ login.php
RewriteRule ^logout$ logout.php
RewriteRule ^withdrawals$ withdrawals.php
RewriteRule ^register$ register.php
RewriteRule ^report$ report.php
RewriteRule ^referrals$ referrals.php
RewriteRule ^contact$ contact.php
RewriteRule ^add_wallet$ add_wallet.php
RewriteRule ^payment_page$ payment_page.php
RewriteRule ^forgot_password$ forgot_password.php
RewriteRule ^my_account$ my_account.php
RewriteRule ^(admin)($|/) - [L]
RewriteRule ^([A-Za-z0-9-]+)/?$ view_link.php?s=$1 [L]
RewriteRule ^page_([^/]+)/?$ pages.php?slug=$1 [L]
</IfModule>
RewriteConds work only on the one RewriteRule immediately following them, so you would have to repeat them before every single one.
It might make more sense to work with a negated pattern here - check if the host name was not mydomainname.com, and follow that by a rule that simply says, “okay we done here”, by using the [L] flag.
RewriteEngine On
RewriteBase /
# check if the host name was not mydomainname.com
# pattern anchored at the start using ^ as well here, so that notmydomainname.com
# would not be matched as well, and the . escaped
# whole thing negated, by putting ! in front of it
RewriteCond %{HTTP_HOST} !^mydomainname\.com$ [NC]
# match absolutely anything with the .
# don’t do any actual rewriting, by using - as the substitution
# [L] flag to say, that’s it, we are done with the rewriting here
RewriteRule . - [L]
# … rest of your rules follow here
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
# …
I have my directory like this:
/index.php (website main page)
/sites
site1
site2
site3
when I go to site1.example.com, i want it to show example.com/sites/site1/index.php
when I go to site1.example.com/page1, i want it to show the file example.com/sites/site1/page1.php
how can i do that? thanks!
I assume all your subdomains point to the same place as the main domain, so subdomain.example.com and example.com point to the same place.
Try something like the following in the .htaccess file in the root of the main site:
RewriteEngine On
# Exclude requests for the www subdomain
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteRule ^ - [L]
# Requests for the site root
RewriteCond %{HTTP_HOST} ^(.+)\.example\.com [NC]
RewriteRule ^$ sites/%1/index.php [L]
# Requests that are "assumed" to be .php files
RewriteCond %{HTTP_HOST} ^(.+)\.example\.com [NC]
RewriteRule ^([^.]*)$ sites/%1/$1.php [L]
# All other requests
RewriteCond %{HTTP_HOST} ^(.+)\.example\.com [NC]
RewriteRule !^sites/ sites/%1%{REQUEST_URI} [L]
This assumes that a valid URL-path does not contain a dot.
%1 is a backreference to the captured group in the CondPattern (ie. the subdomain) and $1 is a backreference to the captured group in the RewriteRule pattern.
However, how do you want to handle non-PHP files and other static resources?
Also, how can I do a 404 page?
You can define a custom error document. For example:
ErrorDocument 404 /errors/404.php
However, you'll need to make an exception at the top of your .htaccess file to prevent this from being rewritten by the directives that follow. For example:
RewriteRule ^errors/ - [L]
You need to:
Setup a Wildcard DNS record
Write a rule for your .htaccess
The rule could look like that:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(.*)\.example\.com
RewriteRule ^(.*)$ http://example.com/sites/%1/$1 [L,NC,QSA]
That's it.
I have an htaccess rewrite URL as below:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www.mywebsite.com$ [NC]
RewriteRule ^(.*)$ http://mywebsite.com/$1 [R=301,L]
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^my-page\.html$ /my-page.php [L]
RewriteRule ^my-page/([^/]*)\.html$ /level1.php?num=$1 [L]
RewriteRule ^my-page/([^/]*)/([^/]*)\.html$ /level2.php?level1=$1&level2=$2 [L]
RewriteRule ^([^/]*)\.html$ /level3.php?level3=$1 [L]
These rules above rewrite URLs from mywebsite.com/my-page.php to mywebsite.com/my-page.html.
Now, what I want to achieve is mywebsite.com/my-page/ to be redirected to mywebsite.com/my-page.php (which in turn rewrites to mywebsite.com/my-page.html).
What I have tried, I created a directory "my-page" and tried to redirect requests from mywebsite.com/my-page/ to /my-page.html.
I don't know what went wrong. I can see in the network tab that a request is made to /my-page/ and gets rewritten to mywebsite.com/my-page.htmlmy-page/, which gives a 302 Status ☹
Please help! Thank you.
You can try use RedirectMatch to achieve this.
Redirect to my-page.php:
RedirectMatch 301 ^/my-page/ http://mywebsite.com/my-page.php
or straight away to my-page.html if this is your goal:
RedirectMatch 301 ^/my-page/ http://mywebsite.com/my-page.html
or, what will be best - change the code responsible for mywebsite.com/my-page.htmlmy-page/, but I can't see it in question you have asked :)
Please give the following a try. Brief descriptions are found in the comments for each section.
RewriteEngine On
# Trim www.
RewriteCond %{HTTP_HOST} ^www\.mywebsite\.com$ [NC]
RewriteRule ^(.*)$ http://mywebsite.com/$1 [R=301,L]
RewriteBase /
# Redirect /my-page[/] to /my-page.html
# >> Note: change 302 to 301 to make permanent
RewriteRule ^my-page/?$ my-page.html [R=302,L]
# Allow existing files and directories
# Recommended to comment out the first line
RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
# Rewrite *.html to respective page
RewriteRule ^my-page.html$ my-page.php [L]
RewriteRule ^my-page/([^/]*).html$ level1.php?num=$1 [L]
RewriteRule ^my-page/([^/]*)/([^/]*).html$ level2.php?level1=$1&level2=$2 [L]
RewriteRule ^([^/]*).html$ level3.php?level3=$1 [L]
The important part here is that you do the required redirect before any other rewrites (except the www. removal).
Also, you previously had the two conditions which stated that if the request was not for a file or directory, then proceed with the next rule, but that wouldn't have accounted for the last two rules. As such, this version tells Apache to stop everything if the request is for an existing file or directory. I would recommend, for security purposes, that you comment out the line that checks for existing directories.
My code:
RewriteEngine on
RewriteBase /
RewriteRule ^article/([a-z]+)/?$ index.php?page=article&name=$1 [L]
RewriteRule ^([a-z]+)/?$ index.php?page=$1 [L]
I am using WAMP and had setup a Virtual Host.
In my index.php, there is code to get page passed and checks if it exists(in database). If not, display an error message. It works fine.
Eg: http://mysite/contactus/
But it will not work if I use a a directory name as page_name in the URL. Eg: http://mysite/images/. This will display page not found error (ie. checks database and no page found, so display "not found"). But it will not display images,css(linked file) in the page. Also, it shows http://mysite/images/?page=images in addressbar.
Like that, if I goto js folder which is used to store javascript files, above problem occurs. So, problem is caused if any subdirectory's name is passed as pagename.
How to solve this ?
When http://mysite/images/ is supplied, mod_rewrite is redirecting to http://mysite/images/index.php?page=images instead of http://mysite/index.php?page=images
Edit
Please tell me how to block hotlinking of files and directory, and redirect back to index page or send some browser header error ?
I tried this:
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.*) http://%{HTTP_HOST} [R,L]
RewriteRule ^article/([a-z]+)/?$ /index.php?page=article&name=$1 [L]
RewriteRule ^([a-z]+)/?$ /index.php?page=$1 [L]
Edit
New code(semi-working):
RewriteEngine on
RewriteBase /
# remove trailing slash ONLY if it is not an existing folder
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1/ [R,L]
RewriteRule ^article/([a-z]+)/?$ http://%{HTTP_HOST}/index.php?page=article&name=$1 [L]
RewriteRule ^([a-z]+)/?$ http://%{HTTP_HOST}/index.php?page=$1 [L]
This code will clear the problem with not displaying pics and css when a directory name is mentioned. But whatever pagename i specify eg:http://mysite/contactus, it will goto URL: http://mysite/index.php?page=contactus. Even if I use a directory name eg: http://mysite/js, it will goto: http://mysite/index.php?page=js
I am very confused.
RewriteEngine on
RewriteBase /
RewriteRule ^article/([a-z]+)/?$ index.php?page=article&name=$1 [L]
RewriteRule ^([a-z]+)/*$ /index.php?page=$1 [L]
you have to put the slash in front.
Edit: changed the ? to *
My understanding is that your script is for documents only, not images or other resources.
Then you should ignore them right away. Try adding this line right after RewriteBase like this :
RewriteEngine on
RewriteBase /rewrite/
RewriteRule ^/(images|js)/(.*)$ - [L]
RewriteRule ^article/([a-z]+)/?$ index.php?page=article&name=$1 [L]
RewriteRule ^([a-z]+)/?$ index.php?page=$1 [L]
Then these subdirectories would be served right away, thus bypassing the next RewriteRule set.
For the problem with the directories I usually force a slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^\.]+[^/])$ $1/ [R]