How to add many rules to RewriteEngine - php

Hello I have this rewrite-rule example it makes the following example:
[http://localhost/project/index.php?url=something]
on my site I use it to make
[http://localhost/project/index.php?url=task/add]
shown as
[http://localhost/project/task/add]
This is my code
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]
I need to make 3 other things
make url [http://localhost/project/index.php?url=tasks/view/&page=2]
shown as [http://localhost/project/tasks/view:2]
or [http://localhost/project/tasks/view#2]
then my upload folder named (files) I wanna to redirect anyone get any
file from this folder just browser
download files on upload folder named (files) with custom url like as [http://localhost/project/getfile/1]

First of all I want to remind you that # is the 'anchor' part of an url. It is never sent to the server, so rewriting to it is probably not the best idea.
What your existing rule does, is internally rewriting all requests that do not map to an existing file, directory or symlink to index.php. If you want to rewrite urls like http://localhost/project/tasks/view:2 to be rewritten to http://localhost/project/index.php?url=tasks/view&page=2, you'll need to add this rule before the rule you already have. Otherwise the more general rule would match it before the more specific rule can.
I also presume you have your .htaccess in your /project/ directory.
make url [http://localhost/project/index.php?url=tasks/view/&page=2]
shown as [http://localhost/project/tasks/view:2]
or [http://localhost/project/tasks/view#2]
Adding the following rule before your existing rule should handle those urls nicely.
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^tasks/view:(.+)$ index.php?url=tasks/view&page=$1 [QSA,L]
Alternativelly, why don't you simply explode( $_GET['url'], ':' ); in index.php instead of this rule.
then my upload folder named (files) I wanna to redirect anyone get any
file from this folder just browser
If you want to stop all direct requests to /project/files, you can use the %{THE_REQUEST} trick and the [F] (forbidden) flag. If you want to display a custom error page, add an errordocument handler for the forbidden status code.
RewriteCond %{THE_REQUEST} ^(GET|POST)\ /project/files
RewriteRule ^ - [F,L]
download files on upload folder named (files) with custom url like as
[http://localhost/project/getfile/1]
Remember that for every request you send to the server, Apache will match it against a regex in the RewriteRule and either rewrite it internally or redirect the user. To internally rewrite a request to /project/getfile/1 to /project/files/1 you can use the following rule. Add it before the rule you already have.
RewriteRule ^getfile/(.*)$ /files/$1 [L]
I encourage you to read the documentation for mod_rewrite.

Related

Why can some urls contain "fake" directories?

Currently, I'm trying to set up updates for passes that are added to the Wallet app on iOS.
One thing that is interesting is that having the url https://example.com/index.php/var1/var2 still works and index.php is still run. Is there a reason why this url format works?
.htaccess/mod_rewrite is the reason why it's working.
For example:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?path=$1 [NC,L,QSA]
Having this rules inside a file named .htaccess in the root folder of your website, will make the path /var1/var2 available inside $_GET['path']

.htaccess redirect a folder if filename existing with the same name

Some servers creates subdomains folders in the same folder as main domain.
As a result if a main domain has news.php page rewritten to /news (just to remove php extension for SEO reasons) and /news folder existing at the same time, the user is being redirected to /news folder instead of news.php file.
I could redirect specific folders to a file with:
RedirectMatch 301 ^/plotki/?$ /plotki.php
but how to redirect all of them to the same filename as directory with some exception like /tags, /scripts etc. and all php files in main directory ?
If I understand the problem correctly: when a file exists in the main folder, you don't want a rewrite. However, if a folder is matched, it should also not rewrite to one file.
Lets assume you want all traffic to "index.php" but dont want the file "news.php" (which is in the main folder) nor the folder "/include/" to be redirected to index.php
The easiest way to do this, would be with a rewrite rule. For that you first need to turn on the rewriteEngine in the .htaccess file.
RewriteEngine On
The rewriteEngine works with conditions and rewrites. In your case there could be multiple contitions that should be met, prior to rewriting. If one of the conditions is not met, don't rewrite.
The below line tests if the "Request URI" contains the text "/include/". Only if it does NOT contain that in the url, it will let you continue to the next line and finally rewrite. You can place all exceptions like the below example. Note that you can use regular expression for this! [NC] means "No-case" more info
RewriteCond %{REQUEST_URI} !/include/ [NC]
RewriteCond %{REQUEST_URI} !(/include/|/folder 2/|/folder[0-9]{2}) [NC]
After you place all exceptions as a rewrite condition, you want to make sure that if the file exists on the server, the rewrite rule does not apply. This is done with the line containing "!-f". Lastly you must make sure that the rewrite rule is not applied when the request URL already IS the index.php file (else you will get an internal, ethernal loop, and a 505 error). The final line sends all data to index.php. Note that I do not send any additional parameters to index.php. In index.php you can read $_SERVER['REQUEST_URI'] to obtain all data you need!
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !index.php [NC]
RewriteRule ^(.*)$ /index.php [L]
You can use http://htaccess.madewithlove.be/ to test your htaccess conditions. The script will tell if a condition is met or not. Note that the website does not support all variables like %{REQUEST_FILENAME}
==Edit==
If you only want to redirect traffic to /page/... to page.php, but leave all other traffic as is you can make one more condition.
RewriteCond %{REQUEST_URI} !/include/ [NC]
RewriteCond %{REQUEST_URI} ^/page/ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !page.php [NC]
RewriteRule ^(.*)$ /page.php [L]
^/page/ means: ^ represents the beginning of the string, so, the Request URI must START with /page/ in order to match the condition. If it does so, it will continue and rewrite that url to page.php

cant figure out mod_rewrite for php query string =/

here is my website
http://www.coolcodez.net/ios/nicucalc
notice when you click on pages on the nav you get urls like
http://www.coolcodez.net/ios/nicucalc/index.php?page=features
I put an .htaccess file in my nicucalc directory. I want the urls to look like this
http://www.coolcodez.net/ios/nicucalc/features
even better would be
http://www.coolcodez.net/nicucalc/features
here is my htaccess file. It's never working properly..
RewriteEngine on
RewriteCond %{QUERY_STRING} ^page=(.*)$
RewriteRule ^index\.php$ /%1/? [R=301,L]
what am i doing wrong. explanation as well please
also note: this folder is located inside of a wordpress installation folder. not sure if that htaccess file would be affecting mine somehow
The rule that you have redirects requests for index.php to /features/ (or whatever the "page" is). This is fine in and of itself but you need something that rewrites it internally back to index.php. Because of that you need 2 rules, one to redirect (matches request) and one to internally rewrite (matches URI):
RewriteEngine On
RewriteBase /ios/nicucalc/
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /ios/nicucalc/index\.php\?page=([^&\ ]+)&?([^\ ]*)
RewriteRule ^ /ios/nicucalc/%1?%2 [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?page=$1 [L,QSA]
The first rule matches against the request, this looks like:
GET /ios/nicucalc/index.php?page=features HTTP/1.1
The "features" is captured and backreferenced in the rule using %1. The second rule first checks if the request points to an existing file or directory. If it doesn't then the URI is captured and then rewritten to index.php and the URI gets passed to the script via the "page" parameter.

How to deal with CSS, JS files when used with global apache redirect (for user friendly url's)

I have the following in my htaccess file:
RewriteEngine On
RewriteRule ^(.*)$ rewrite.php?data=$1 [L,QSA]
From rewrite.php I redirect to the correct pages depending on the url. Problem is that it redirects all files including css and js. I tried including these files but I now realise that was dumb of me. Should I redirect when there is and appropriate extension in the url? If redirecting is the way to go what method would be best? header location or HTTP_redirect?
Or is this not a good idea performance or work involved wise? I could go for something like this but I know next to nothing about apache and would rather not work with it right now.
RewriteRule ^(.*).css$ /includes/compressor.php?i=$1.css [L]
I previously had the following in my htaccess file:
RewriteCond %{REQUEST_FILENAME} !-f
I decided to remove this because:
I would not be able to include the header and other common files in the rewrite.php file. I would also not be able to have a database call in the rewrite file that would determine the page to include and to reuse the data for the page contents.
Unwanted files would be reachable such as service used only by external app.
The compression should be done once, and not for every request. You can then exclude requests from the URL rewriting if the corresponding file exists:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ rewrite.php?data=$1 [L,QSA]
How about redirecting only if the requested file does not exist on the server?
You could use the following rewrite conditions to achieve this.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^(.*)$ rewrite.php?data=$1 [L,QSA]
So if the request is for a CSS/JS/HTML/Image file that already exists on the server then no rewriting takes place and the request for the file is processed. If the file does not exist, it will run your rewrite rule to rewrite.php

Create dynamic subdirectories using htaccess and php

Every single time a user registers on my site I would like them to have their own subdirectory with their registered "username". Every user subdirectory will have the same "index.php" file which will do something.
For example: "/users/username1/" and "/users/username2/"
If some one wants to access the subdirectory they would simple go to:
"www.example.com/users/username1/" or "www.example.com/users/username2/"
The easy and messy solution would be to simply create a subdirectory for every user and place the same "index.php" file in every directory. But to me this is only going to crowd my server space and make my directories large.
I wanted to know if all this can be done using .htaccess? Can I create one "index.php" and one ".htaccess" file and place them both in my "/users/" directory? What would be the actual code that I would have to place in my .htaccess file??
If you have a better way of doing this please let me know. I am using Apache and PHP as my working environment.
Thank you
Well, for example, you could do it all with one htaccess like this:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
</IfModule>
What it does:
switches on rewrite engine
checks if a requested file exists
checks if a requested directory exists
if NOT, it redirects request to your main index.php
Basically that means if you enter url such as yourdomain.com/users/ivan/, you request will be redirected to:
index.php?url=/users/ivan
then you $_GET['url'] in your index.php and split it into pieces.
That's just an example, there other mod_rewrite methods to do this.
Make it virtual. There are no subdirectories, you can use mod_rewrite to simulate that.
With mod_rewrite you can make /users/username1 lead to /users.php?user=username1 for instance. Everything is transparent for the client, he wont notice what is really happening.
By using something like this:
RewriteEngine On
RewriteRule ^([\-_0-9A-Za-z]+)$ index.php?a=$1 [L]
You can customize RewriteRule as much as you want.
You can essentially type in any directory you want, and it will be redirected to your index.php page.
If you want to make sure the existing directories are not redirected, do this:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([\-_0-9A-Za-z]+)$ index.php?a=$1 [L]
If you want to limit the scope, so only a subdirectory of user/ is redirected (similar to Stack Overflow), simply add in 'user' to the start of the rule:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^user/([\-_0-9A-Za-z]+)$ index.php?a=$1 [L]
And finally, if you want to have an individual file handle all user requests seperate from your actual index.php page:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^user/([\-_0-9A-Za-z]+)$ users.php?a=$1 [L]
This is a very similar setup I use to distribute CSS files.
Note: The Directory will be contained is $_GET['a']

Categories