htaccess rewriterule for directory structure - php

I have the following .htaccess rewrite problem. We have requests entering with multiple subdirectories and an .html file
for example dir1/file.html
or dir1/dir2/file.html
or dir1/dir2/dir3/file.html
or dir1/dir2/dir3/dir4/file.html
what we eventually need is a rewrite rule to
index.html?dir1=$1&dir2=$2&dir3=$3&dir4=$4&file=$5
(where dir2 to dir5 would be empty if path is too short)
Is there any way to do that directly in the .htaccess file, or is it necessary to handle it in php?

I will see if I can test this out, but this should work for the problem as your question states it:
RewriteRule ^/([a-z0-9]+)/?([^/]*)$ /index.php?dir1=$1&$2 [QSA]
RewriteRule ^/([a-z0-9]+)/([a-z0-9]+)/([a-z0-9]+)/([a-z0-9]+)/?$ /index.php?dir1=$1&dir2=$2&dir3=$3&dir4=$4 [L]
RewriteRule ^/([a-z0-9]+)/([a-z0-9]+)/([a-z0-9]+)/?$ /index.php?dir1=$1&dir2=$2&dir3=$3 [L]
RewriteRule ^/([a-z0-9]+)/([a-z0-9]+)/?$ /index.php?dir1=$1&dir2=$2 [L]
RewriteRule ^/([a-z0-9]+)/?$ /index.php?dir1=$1 [L]
I emphasize should because only you can really say what your site structure is & how this cascading ruleset would affect your application.
The regex used is fairly simple:
([a-z0-9]+)
That captures any directory name with letters & characters. If you want to capture—let’s say—underscores and dashes on top of that, it would change to something like:
([a-z0-9_-]+)
The first rewrite rule I have set—^/([a-z0-9]+)/?([^/]*)$—is to capture anything that comes after dir1 just in case there’s data to capture that is not a strict directory structure. You can comment that out if you wish. Just added it since that’s how I like to handle situations that need URL parsing like this.
Also, have you considered adding this to the rewrite rule? Perhaps at the top before the rules cascade in?
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

I would suggest you this
http://domain/dir1-dir2-dir3-dir4-dir5-file.html
rules
RewriteEngine On
RewriteBase /
RewriteRule (.+)-(.+) $1/$2 [N]
you can even make it dynamic by adding these
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1
this is much cleaner.
UPDATE:
well I didn't mean you use the second part but anyways I explain what I meant, it's not wrong that people use QUERY STRING for passing path in URL but it's important how you do that like in this URL
http://domain/index.php?route=dir1/dir2/dir3/dir4/dir5/file.html
as you can see you will grab the path easily with just one GET variable and even handling of this in RewriteRule is much easier like
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?route=$1&%{QUERY_STRING} [L]
which will let you to have a URL like this
http://domain/dir1/dir2/dir3/.../file.html
and with any reason you may change those slash to hyphen or other acceptable chars which become like this
http://domain/dir1-dir2-dir3-dir4-dir5-dir6-dir7-file.html
and as I said it's more easier to pass the current QUERY_STRING which will look like this
http://domain/dir1-dir2-file.html?q=extra_query_value
and result in PHP if you dump $_GET will be:
q => 'extra_query_value'
route => 'dir1/dir2/file.html'
and finally in PHP you may easily explode them to have all folders' name by individual variable.

Related

Exposed folders in MVC application

Well, as a start please excuse me for my beginner English..
I want to know more about security in PHP MVC applications
I've created my own MVC, I still haven't finished it.
My application directory is exposed by URL access with child elements.
How to make this hidden from visitors?
Following is what I am trying
Apache mod_rewrite ?
I still don't know to make it empty index.html in each folder like the framework Codeigniter ?
What to use for something to indicate ?
and,
... how to make ?
Edit
I know a litte something about rewrite_rules
Below is my .htaccess
Options -MultiViews
RewriteEngine On
RewriteBase /ligia
#RewriteCond %{REQUEST_FILENAME} -f [OR]
#RewriteCond %{REQUEST_FILENAME} -l [OR]
#RewriteCond %{REQUEST_FILENAME} -d
#RewriteRule .+ -
#I know, it is commented
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule "^(.+)$" "index.php?uri=$1" [QSA,L]
But I am afraid if this is the best way to hold my MVC application
security!?
I need help!
First make sure that your .htaccess file is in your document root (the same place as index.php) or it'll only affect the sub-folder it's in (and any sub-folders within that - recursively).
Next make a slight change to your rule so it looks something like:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?path=$1 [NC,L,QSA]
At the moment you're just matching on . which is one instance of any character, you need at least .* to match any number of instances of any character.
If you want the whole shebang installed in a sub-directory, such as /mvc/ or /framework/ the least complicated way to do it is to change the rewrite rule slightly to take that into account.
RewriteRule ^(.*)$ /mvc/index.php?path=$1 [NC,L,QSA]
And ensure that your index.php is in that folder whilst the .htaccess file is in the document root.
NC = No Case (not case sensitive, not really necessary since there are no characters in the pattern)
L = Last (it'll stop rewriting at after this Rewrite so make sure it's the last thing in your list of rewrites)
QSA = Query String Apend, just in case you've got something like ?like=penguins on the end which you want to keep and pass to index.php.

Keep question mark on $_GET with rewrite rule

So I've found this interesting question on making the question mark symbol appear on $_GET variable after using rewrite rules.
However, as much as I've tried to accomplish this myself, I didn't quite understand how it works to have the same result on my website.
Here's my rewrite rule:
RewriteRule ^(.+)$ index.php?uri=$1 [QSA,L]
This basically allows me to route users to specific places without hard coding each page on my htaccess file, so if a user goes to /about/contact page, he's actually going to index.php?uri=/about/contact.
The problem is that sometimes I WANT the question mark to be kept in $_GET. Let's say a topic title of "What's up?" then my url would search for a topic like /topic/what-s-up? and would match with what-s-up? in the database. But, right now, my $_GET variable stores just "what-s-up" (without the "?") and my database still stores "what-s-up?" (with the "?"), which would say that there's no topic with that title when there actually is.
How can I keep the question mark so /topic/what-s-up? still translates to /topic/what-s-up? in the query string?
EDIT: FULL .HTACCESS FILE FOR TEST PURPOSES
Options -Indexes
DirectoryIndex index.html index.php
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ index.php?uri=$1 [QSA,L]
You can change your rule to this to capture optional ? in uri parameter:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{THE_REQUEST} \s/+([^?]*\??\S*)\sHTTP [NC]
RewriteRule ^(.+)$ index.php?uri=%1 [QSA,L]
Since we want ? also to be captured we are using RewriteCond %{THE_REQUEST} since pattern in RewriteRule only matches REQUEST_URI. Since we are capturing value from RewriteCond hence we are using %1 instead of $1 as back-reference.
THE_REQUEST variable represents complete original request received by Apache from your browser and it doesn't get overwritten after execution of some rewrite rules. Example value of this variable is GET /index.php?id=123 HTTP/1.1
I know its late, but i used php urlencode() to pass the question mark, as it converts ? to %3F

Dynamic URL Rewrite from GET

I want to rewrite my URLs which are based upon directories I have
My directories look like this:
index.php
galleries
-Party Weekend
-2014
-Bunchofimages.png
-Other pics
-Pictures.png
And the urls look like:
example.com/?f=/Party%20Weekend/2014
And I was looking for something like
example.com/Party-Weekend/2014
(Can be a dash or a + sign, doesn't really matter)
(Using .htaccess seems like the best option but I have no experience with .htaccess at all)
Also do I need to customize every single folder in the rewrite engine or can this be done dynamicly? (So I don't need to make a new rule for every folder I create)
I tried this but doesn't rewrite anything at all
RewriteEngine On
RewriteRule ^([^/]*)/$ /?f=$1 [L]
Am I doing something wrong here?
Try something like:
RewriteEngine On
RewriteCond %{THE_REQUEST} \ /+\?f=([^\ &]+)
RewriteRule ^ /%1? [L,R]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/galleries%{REQUEST_URI} -d
RewriteRule ^(.*)$ /?f=$1 [L]
There may be some encoding issues related to the spaces in your folder names, so you may either need some combination of the NE or B flags in side the brackets.
Using .htacces is the best and only way
you don't have to customize all folders you do it all dynamically
please go to this page for more details its easy
URL Rewriting for Beginners :
http://www.addedbytes.com/articles/for-beginners/url-rewriting-for-beginners/

Rewriting example.com/section.php?username=xyz to example.com/xyz/section

Using the following htaccess, I have been able to rewrite example.com/profile.php?username=xyz to example.com/xyz,
RewriteEngine On
RewriteRule ^([a-zA-Z0-9_-]+)$ profile.php?user=$1
RewriteRule ^([a-zA-Z0-9_-]+)/$ profile.php?user=$1
Adding the following to the above,
RewriteRule ^([a-zA-Z0-9_-]+)/section$ section.php?user=$1
RewriteRule ^([a-zA-Z0-9_-]+)/section/$ section.php?user=$1
did not resolve example.com/section.php?username=xyz to example.com/xyz/section.
Am I doing something wrong here?
First of all: The manner of speaking would rather be the opposite: The rules you showed are to rewrite requests like /xyz internally to /profile.php?username=xyz and not vice versa.
Now if you want to rewrite requests like /xyz/section internally to /section.php?username=xyz where section and xyz are variable, try these rules:
RewriteRule ^([a-zA-Z0-9_-]+)/?$ profile.php?user=$1
RewriteRule ^([a-zA-Z0-9_-]+)/([^/]+)/?$ $2.php?user=$1
To look for static files (images, css) in the right directory without having to write the file address, do:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
Before writing the code suggested by RageD
(Sorry, should have posted it as a comment but I needed newlines)
I tested it and it works. Try this:
RewriteRule ^([a-zA-Z0-9_-]+)\/section$ section.php?user=$1
RewriteRule ^([a-zA-Z0-9_-]+)\/section\/$ section.php?user=$1
All I did was escaping the / in the URL since / is a regex delimiter.

Why won't this simple RewriteRule work?

This should be simple but I cannot figure it out. I have this very simple mod_rewrite rule and it just doesn't want to work. This is the entire contents of the .htaccess file.
RewriteEngine On
RewriteRule ^([A-Za-z0-9-_/\.]+)/?$ index.php?page=$1 [L]
If I call the URL domain.com/foo it should rewrite it to index.php?page=foo. But instead, it rewrites it to index.php?page=index.php. I have tried multiple URLs:
index.php?page=foo
index.php
/foo
/
In all cases, PHP acts as if 'page' is set to "index.php". It isn't a fault with index.php because I replaced the entire contents of index.php with a script that simple echoed the value of 'page' and it still comes out as index.php.
Really lost where I'm going wrong here, any help would be awesome!
Thanks
Adrian
Any reason you can't use something simpler, such as:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?page=$1 [L]
If you're trying to keep existing pages from being re-written, then the !-f will take care of that (if file does not exist and if directory does not exist, then re-write)
I think this is what your looking for. Unfortunately it doesn't really work well if the URL has other GET arguments (IE, /some/url/path?page=1).
RewriteEngine On
RewriteRule ^(.*)$ index.php?page=$1 [L]
Better idea.
RewriteEngine On
RewriteRule ^(.*)$ index.php [L,QSA]
The QSA flag will forward the GET params and then in index.php use $_SERVER['REQUEST_URI'] and parse_url to route the request.
From http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html:
'qsappend|QSA' (query string append)
This flag forces the rewriting engine to append a query string part
in the substitution string to the existing one instead of replacing it.
Use this when you want to add more data to the query string via a rewrite rule.

Categories