Apache RewriteRule to hide Folder - apache

I've read a lot of beginner tutorials and other threads here on the topic mod_rewrite, but I can't get my (simple) RewriteRule to work.
My local domain is http://localhost/movies, and my structure is:
/movies
|-.htaccess
|-index.php
|-/pages
|-profile.php
|-faq.php
|-statistics.php
So my URLs would be e.g.:
http://localhost/movies/pages/profile.php
But I want them this way:
http://localhost/movies/profile
I achieved this with simple rules in my .htaccess:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule profile pages/profile.php
RewriteRule faq pages/faq.php
RewriteRule statistics pages/statistics.php
</IfModule>
Now I've tried to sum it up in one rule:
RewriteRule ^(\w+)$ pages/$1.php
So my thought is, that /(\w+)$ captures any characters and puts it in $1
But this doesn't seem to work, so where might be my error?
The output I get: Object not found! 404
Edit:
The answers in the possible duplicate aren't working neither
RewriteRule ^/(.*)$ /pages/$1
Or
RewriteRule (.*) /subfoldername/$1

Related

.htaccess RewriteRule gives right link but also a 404

I'm hosting different sites
http://example.nl/example.nl/_sites/byos/
http://example.nl/example.nl/_sites/eggbot/
http://example.nl/example.nl/_sites/hslab/
http://example.nl/example.nl/_sites/prolactin/
And yes there is a folder that has the same name as the domain, there is a reason for that.
And I want the links to become:
http://example.nl/byos/
http://example.nl/eggbot/
http://example.nl/hslab/
http://example.nl/prolactin/
This is one of the many attempts:
RewriteEngine On
Options +FollowSymlinks
RewriteCond %{REQUEST_URI} !(.*)example.nl/_sites
RewriteRule ^(.*)$ example.nl/_sites/$1 [L]
And this one:
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
RewriteRule ^example.nl/_sites/(.*)$ /$1 [L,NC,R]
The last one brings me close, it changes the address in what I want it to be, but it also results in a 404 now.
I also tried it with renaming the example.nl folder so it is not the same as the domain name but the problem seems to be the same.
In case it is important for later, I also have folders with files here:
http://example.nl/example.nl/_misc/
http://example.nl/example.nl/_plugins/
But I don't care if those get renamed, since they won't appear in the url bar, unless the user goes directly to one of those files, but I don't care about that.
So how can I omit the example.nl/_sites/ part and still have the website working?
I have seen the similar questions on SO, but for me it looks like Chinese in another dialect.
---- edit:
using the following of the answer from anubhava:
RewriteCond %{HTTP_HOST}::%{THE_REQUEST} ^(?:www\.)?([^:]+)::GET\s/+\1/_sites/(\S*)\s [NC]
RewriteRule ^ /%2 [R=301,NE,L]
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^[^/]+/?$ %1/_sites%{REQUEST_URI} [L]
I don't get a 404 anymore.
But this files for example:
http://hslab.nl/hslab.nl/_misc/bna.js
It tries to load it as:
http://hslab.nl/_misc/bna.js
Which fails. In the code it was targeted as:
src="../../_misc/bna.js"
In case it helps here is a screenshot of the folder hslab.nl:
Without hardcoding host name, you may try these rules in your site root .htaccess:
RewriteCond %{HTTP_HOST}::%{THE_REQUEST} ^(?:www\.)?([^:]+)::GET\s/+\1/_sites/(\S*)\s [NC]
RewriteRule ^ /%2 [R=301,NE,L]
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^[^/]+/?$ %1/_sites%{REQUEST_URI} [L]
With your shown samples, could you please try following. Fair warning I have written this in mobile so yet to test it should work IMHO will test it in sometime too. Also since you mentioned there could be multiple domains so I have specifically put a condition to check if it's example.nl here in case you want to rewrite request for any domain then we could omit that condition too.
RewriteEngine ON
RewriteCond %{HTTP_HOST} ^example\.nl$ [NC]
RewriteRule ^([a-zA-Z]+)/?$ %{HTTP_HOST}/_sites/$1 [L]
Note: in case you directories/folders are not necessarily starting with alphabets and could be anything then change regex in above from ^([a-zA-Z]+)/?$ TO ^([.*])/?$

Enable human readable URL's in .htaccess

Preface: Yes this question seems like duplicated, and I found related questions, but answers from there didnt help to me. :(
Hello, I want to add human readable URL's support for my PHP project. For now my URL quesry string looks like:
index.php?url=main/index
I would like to make it looks like:
index.php/main/index
I read following articles:
Stackoverflow
Cheatsheet
Stackoverflow
Stackoverflow
But when I do this:
var_dump($_GET['url']); // get empty array
, get empty array like no url parameter added.
My current .htaccess:
DirectoryIndex index.php
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteRule ^(.*)$ index.php?url=$1 [NC]
Can somebody help me please? Thanks!
URL: http://domain.com/index.php/controller/action
Rewritten URL: http://domain.com/index.php?url=controller/action
.htaccess
DirectoryIndex index.php
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteRule ^index.php/(.*)$ /index.php?url=$1 [L,QSA]
Explanation:
The .* in the pattern ^index.php/(.*)$ matches everything after index.php/ on the incoming URL. The parentheses helps to capture the part as variable $1, which is then added at the end of the substitution URL /index.php?url= + $1.
[L, QSA]:
L ignore other rewrite rules, if this fits.
QSA means query string append.
You have
index.php?url=main/index
Yuo want to rewrite (and then user redirect) to this
index.php/main/index
What about trying this?
DirectoryIndex index.php
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} ^url=([a-z]+)/([a-z]+)$
RewriteRule ^.*$ http://mydomain.site/index.php/%1/%2 [R=302,L]
R=301 or 302 depend on your need
On this example i assumed that on the original url there are only a-z chars.
Just to clarify (due the fact generally the process is inverse) on this way the users will be redirect, this rules does not convert links on your page.
In line
RewriteRule ^(.*)$ index.php?url=$1 [NC] the (.*) matches the part of the url up to '?' where the query begins.
To use the values passed in the query you need the QSA flag. Means Query String Append.
If Your URL : www.abcd.com/index.php/abcd/...
.htaccess
RewriteEngine on
RewriteCond $1 !^(index\.php|resources|robots\.txt)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L,QSA]
Try the below code, Only considered for index.php you can replace it as per your requirement. Let me know if you need further assistance.
DirectoryIndex index.php
Options +FollowSymLinks
RewriteEngine ON
RewriteBase /
RewriteRule ^(index\.php)/([0-9a-zA-Z\/_-]{1,99}) index.php?url=$2
What worked for me is:-
<?php var_dump($_GET); ?> this is the only thing I did on url http://localhost/baba.php/abcd . and original .htaccess file
DirectoryIndex baba.php
RewriteEngine ON
RewriteBase /
RewriteRule ^(baba\.php)*/([0-9a-zA-Z\/_-]{1,99}) baba.php?url=$2
For Magento 2.4 Magento will always drop any GET parameters from the URL in a htaccess rewrite. The only way I found to make it work was to create a rewrite module. The setup is here: https://magento.stackexchange.com/a/158811/109113

mod_rewrite with multiple query strings?

I'm trying to cleanup some URLs on my blog, so I've decided to look into mod_rewrite. I haven't a clue what I'm doing though, so I was hoping I could get some help :P I have links like http://kn3rdmeister.com/blog/post.php?y=2012&m=07&d=04&id=4. Although it works, and people still get the content I want them to have, I don't like them having to look at all the query strings. I want to turn the above link into http://kn3rdmeister.com/blog/2012/07/04/4.php.
This is what my .htaccess looks like right now.
RewriteEngine On
RewriteCond %{QUERY_STRING} ^y=([0-9){4})&m=([0-9]{2})&d=([0-9]{2})&id=([0-9]*)$
RewriteRule ^/blog/post\.php$ http://kn3rdmeister.com/blog/%1/%2/%3/%4.php? [L]
Like I said, I'm absolutely clueless :D
If you're using apache 2.0 or higher, you're going to need to remove the leading slash (the prefix) if these rules are in an .htaccess file, so that your regular expression looks like this:
# also note this needs to be a "]"--v
RewriteCond %{QUERY_STRING} ^y=([0-9]{4})&m=([0-9]{2})&d=([0-9]{2})&id=([0-9]*)$
RewriteRule ^blog/post\.php$ http://kn3rdmeister.com/blog/%1/%2/%3/%4.php? [L]
This is going to make it so when someone puts http://kn3rdmeister.com/blog/post.php?y=2012&m=07&d=04&id=4 in their browser's URL address bar, their browser will get redirected to http://kn3rdmeister.com/blog/2012/07/04/4.php and the new URL will appear in their address bar.
I assume you've got something setup on your server to handle a request like blog/2012/07/04/4.php.
At first you should define your URLs!!!
Like:
/blog shows front page
/blog/1234 shows post 1234
/blog/date/2012 shows posts by year
/blog/date/2012/06 shows posts by year and month
/blog/date/2012/06/01 shows posts by year and month and day
and so on...
First option is to rewrite each of your defined URLs to index.php. Your index.php has only to handle the submitted GET parameters.
### Do only if rewrite is installed
<IfModule mod_rewrite.c>
### Start rewrite and set basedir
RewriteEngine on
RewriteBase /
### Rewrite only if no file link or dir exists
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
### Rewrite frontpage
RewriteRule ^blog$ /index.php?action=showfront [L,QSA]
### Rewrite post
RewriteRule ^blog/([0-9]+)$ /index.php?action=showpost_by_id&id=$1 [L,QSA]
### Rewrite posts by date
RewriteRule ^blog/date/([0-9]{4})$ /index.php?action=showposts_by_date&year=$1 [L,QSA]
RewriteRule ^blog/date/([0-9]{4})/([0-9]{2})$ /index.php?action=showposts_by_date&year=$1&month=$2 [L,QSA]
RewriteRule ^blog/date/([0-9]{4})/([0-9]{2})/([0-9]{2})$ /index.php?action=showposts_by_date&year=$1&month=$2&day=$3 [L,QSA]
### Rewrite posts by tag
RewriteRule ^blog/tag/([a-zA-Z0-9_-]+)$ /index.php?action=showposts_by_tag&tag=$1 [L,QSA]
</IfModule>
Test in index.php with:
print_r($_GET);
print_r($_POST);
The second option is to rewrite all URLs and your index.php needs to handle all possible URLs. So at first it needs something like a router that splits the incoming URL in parts and then send the requested page or an error-page. I would try this at first as the bloody school.
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^ index.php%{REQUEST_URI} [L]
</IfModule>
Test in index.php with:
print_r(explode('/', ltrim($_SERVER['PATH_INFO'], '/')));
print_r($_GET);
print_r($_POST);
The third option is to use a PHP framework. A framework may help you to write your code quite fast. It delivers you many base-classes like a router. (f.e. ZendFramework, Flow3, Kohana, Symfony, CodeIgniter, CakePHP, yii and others). This will make you more advanced.
The fourth and laziest option is to use a ready made software like Wordpress.

.htaccess to vhost

Anyone know what to put in vhost.conf for apache to replicate this (from .htaccess):
RewriteEngine on
RewriteCond $1 !^(index\.php|images|scripts|css|uploads|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]
Basically I want all requests except those for /images, /scripts or /css to go through /index.php.
It works when I use the .htaccess file but I'd like to know how to do it via vhost.conf as well. Anyone know if it's better to use one over the other as well (vhost.conf vs htaccess) in terms of performance, stability, etc?
It should work when prepending the pattern with /, either:
RewriteCond $1 !^(index\.php|images|scripts|css|uploads|robots\.txt)
RewriteRule ^/(.*)$ /index.php/$1 [L]
Or:
RewriteCond $1 !^/(index\.php|images|scripts|css|uploads|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]
The disadvantage of .htaccess files is simply that they virtually need to be interpreted with every request while the virtual host configuration is just interpreted once when the server is started.
Gumbo++
I wrote this article on the httpd wiki to cover questions like this one.
http://wiki.apache.org/httpd/RewriteContext

Apache mod_rewrite going berserk - redirecting where it shouldn't

I have a script that echoes a meta redirect to a page called account_management.php5, but for some reason it automatically redirects from there to index.php5. My .htaccess file handles a couple of redirects automatically, for example index.html|php5 to the domain root, and that's the only place I can see this problem originating, but I don't understand why. This is my .htaccess file:
RewriteEngine On
#remember to change this to aromaclear
RewriteCond %{HTTP_HOST} !^sinaesthesia\.co.uk$ [NC]
RewriteRule ^(.*)$ http://sinaesthesia.co.uk/$1 [R=301,L]
RewriteCond %{THE_REQUEST} ^GET\ .*/index\.(php5|html)\ HTTP
RewriteRule ^(.*)index\.(php5|html)$ /$1 [R=301,L]
#translate any .html ending into .php5
RewriteRule ^(.*)\.html$ /$1\.php5
#change / for ?
RewriteRule ^(.*)\.html/(.*)$ /$1\.html?$2
#strip .html from search res page
RewriteRule ^(.*)search/(.*)$ /$1search_results\.html/search=$2
#translate product details link from search res page
RewriteRule ^products/(.*)/(.*)/(.*)$ /product_details.php5?category=$1&title=$2&id=$3 [L]
#Translate products/psorisis/chamomile-skin-cream-P[x] to productview.php5?id=1
RewriteRule ^products/.*-P([0-9]+) /productview.php5?id=$1 [L]
Wrong:
RewriteRule ^(.*)\.html$ /$1\.php5
Right:
RewriteRule ^(.*)\.html$ /$1.php5
Righter:
RewriteRule ^(.*)\.html$ /$1.php5 [QSA]
This same mistake of escaping special chars in the second param of RewriteRule is happening in other rules too, I don't know if apache will handle it, but I know you don't need it because second param is not a regexp.
Never compare to %{THE_REQUEST}, thats a weird thing to do, you don't need that. Moreover, this condition is fine without it. Just put there:
RewriteRule ^(.*)index\.(php5|html)$ $1 [R=301,QSA,L]
Now look at it:
RewriteRule ^(.*)\.html/(.*)$ /$1.html?$2
First, you are still accepting that there are references to .html files, just after trying to translate all .html to .php5, there's something wrong here.
Moreover, you are defineing as QueryString something that was originally a file path, and are not even putting it in a key. It won't work, it need some more treatment.
#strip .html from search res page
RewriteRule ^(.*)search/(.*)$ /$1search_results.html/search=$2
Wasn't it supposed to strip the .html? Because it is actually putting a .html there. Maybe as it is not an [L] it get fixed in the next loop, but you could just get all fixed right here.
#translate product details link from search res page
RewriteRule ^products/(.*)/(.*)/(.*)$ /product_details.php5?category=$1&title=$2&id=$3 [L]
This one full of .* is potentially unstable, specially delimitating the end. You should do this:
RewriteRule ^products/([^/]*)/([^/]*)/([^/]*) /product_details.php5?category=$1&title=$2&id=$3 [L]
# or:
RewriteRule ^products/(.*?)/(.*?)/([^/]*) /product_details.php5?category=$1&title=$2&id=$3 [L]
The last one looks correct, except that you should strip the special character that may be faced as a range delimiter, the "-". I don't think it work after a *, but just to be sure and correct the syntax:
RewriteRule ^products/.*\-P([0-9]+) /productview.php5?id=$1 [L]
Add this just after RewriteEngine on
RewriteLogLevel 9
RewriteLog /tmp/rw.log
Then restart the webserver. It should help you debug the problem.
Edit: Sorry, I didn't notice the .htaccess above. This will only work from the main apache configuration file.