Kohana: Completely remove index.php from url (not repeated issue) - kohana

===== CLARIFICATION =====
Please note this, there are hundred of answers to posts similar to this one, but people only cover a part of the problem, not the real one i'm asking here.
=====
I'm using Kohana 3.2, and i want to completely remove index.php from the url. For example, i want to access to the controller foo, action bar.
Normally, with bootstrap and htaccess correctly setted up, i can access like this:
www.domain.com/foo/bar.
But i can also access like this:
www.domain.com/index.php/foo/bar
I want to allow users to ONLY access like the first way, and not like the second way.
I have this section in bootstrap.php:
Kohana::init(array(
'base_url' => '/',
'index_file' => '',
));
i tried taking off index_file line, changing its value to FALSE, and i am still able to access foo/bar both ways.
I think the solution is modifying htaccess, but i tried some changes and it isnt working as i want. I'm using the original htaccess which came with kohana:
# Turn on URL rewriting
RewriteEngine On
# Installation directory
RewriteBase /knisu/
# Protect hidden files from being viewed
<Files .*>
Order Deny,Allow
Deny From All
</Files>
# Protect application and system files from being viewed
RewriteRule ^(?:application|modules|system)\b.* index.php/$0 [L]
# Allow any files or directories that exist to be displayed directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Rewrite all other URLs to index.php/URL
RewriteRule .* index.php/$0 [PT]
Any help would be appreciated :)
EDIT:
I found an answer that could make it work in another post:
# Redirect from:
# http://localhost/index.php/welcome
# to
# http://localhost/welcome
#
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^index\.php/?(.*)?$ $1 [R,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ ?/$1 [L]
The thing is, the author says: "this works but the problem is with the files and dirs that exists he must put the complete path for the images, css, js, etc... I will fix later"
May be that helps to find the final solution?

I think using the original htaccess is better, but with improvements.
After the...
RewriteRule ^(?:application|modules|system)\b.* index.php/$0 [L]
This should do the redirection of the "index.php/",
# Redirect any "index.php/user/profile/" to "/user/profile/"
RewriteRule ^index.php/(.*)$ /$0 [L,R=302]
In my experience, passing css/js through controllers slower than pure apache/nginx request.

Related

Codeigniter sub-folder multiple controllers

Here is my htaccess file and it works somewhat. Not matter what controller I specify it always goes to the home page
<IfModule mod_rewrite.c>
RewriteEngine On
#Checks to see if the user is attempting to access a valid file,
#such as an image or css document, if this isn't true it sends the
#request to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
#This last condition enables access to the images and css folders, and the robots.txt file
RewriteCond $1 !^(index\.php|css|js)
RewriteRule ^(.*)$ index.php/$1 [L]
</IfModule>
This is my website URL
http://automationmetrics.local/automation/
Thoughts?
Some things I usually check when this happens to me:
Have I enabled the mod_rewrite module in Apache?
Have I set $config['index_page'] to blank?
If the above works, here's the one that I use, that's working on my end:
https://gist.github.com/petrepatrasc/6925413
If you're STILL out of luck, then try fiddling with the $config['uri_protocol'] parameter - I remember that I could only get it to work on Windows (with IIS at the time) using REQUEST_URI as a value. Might be related to that.
The first two rules get triggered on all the files, just like it says in the comment. So this one:
RewriteCond $1 !^(index\.php|css|js)
seems redundant and removing it should solve the issue you're having.

Htaccess rule to make urls like this ?page=1 look like /page/1 in Codeigniter

This is how my urls currently look:
http://mysite.com/?page=1
How can I make this work?:
http://mysite.com/page/1
There is a post on StackOverflow that asks the same question. But the accepted solution isn't working for me. Because I am using Codeigniter and my page results in a 404 perhaps because since the url pattern of a CI site is:
domain/controller/method
The system is assuming that I am requesting a controller called "page" and a method called "1" both of which of course doesn't exist. Or maybye it's due to a conflict with the other code in my htaccess file (which I downloaded from the CI wiki, it gets rid of index.php and does a few security things). Here is my entire htaccess file:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
#Removes access to the system folder by users. Additionally this will allow you to create a System.php controller, 'system' can be replaced if you have renamed your system folder.
RewriteCond %{REQUEST_URI} ^system.*
RewriteRule ^(.*)$ /index.php?/$1 [L]
#When your application folder isn't in the system folder. This snippet prevents user access to the application folder. Rename 'application' to your applications folder name.
RewriteCond %{REQUEST_URI} ^application.*
RewriteRule ^(.*)$ /index.php?/$1 [L]
#Checks to see if the user is attempting to access a valid file, such as an image or css document, if this isn't true it sends the request to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]
#Pretty urls for pagination links
RewriteRule (.*) index.php?page=$1
</IfModule>
The non indented bit is the solution I got from that other SO question that isn't working for me.
Any solutions to this CI pagination issue?
UPDATE
Ok, read some of the docs and now I have this working:
http://mysite.com/home/index/2
What would be the htaccess rule to turn that into?:
http://mysite.com/page/2
You should make this configuration at /application/config/routes.php (and let the .htaccess just for hide the index.php as you are already doing).
$route['page/(:any)'] = 'home/index/$1';
Or better, like #zaherg remembered (ensures that only numbers could by matched):
$route['page/(:num)'] = 'home/index/$1';
This way all the requests to http://mysite.com/page/2 will be treated internally as http://mysite.com/home/index/2 and so forth.
I suggest you take a look at CodeIgniter User Guide - URI Routing and CodeIgniter User Guide - Tutorial − Introduction.
Good luck.
RewriteEngine on
RewriteCond $1 !^(index\.php|images|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]
from CodeIgniter docs
That will handle removing the index.php, but what happens after that depends how CodeIgniter's query string handling is set up: it can be configured to use a query string rather than a path. See the link for more details.

htaccess query. 2 rewrites rules for 2 home pages

I'm hoping someone might be able to help with a problem I'm having due to my lack of experience and knowledge with htaccess.
What we're doing is running IP Boards forum software and wordpress both in the root directory. The IPB has the index.php file (because of having indexed url's) and the new Wordpress's index.php file has been renamed to blog.php.
At the very top of the htaccess file we've added: DirectoryIndex blog.php index.php - so the new wordpress opens first.
The problem I'm having is trying to have 2 rewriterules in the htaccess file for the friendly urls from the forum software and also the permalinks for the new wordpress.
I can only seem to have one or the other.
Please could anyone tell me, or point me in the right direction to get both working.
This is what I'm doing so far but sadly no joy, but works fine if we remove one of the condition and rewrites.
<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /blog.php [L]
</IfModule>
Many thanks in advance.
Not sure if you still want an answer. Either way, if you are trying to go to two different pages you need some way of distinguishing them.
DirectoryIndex basically tells the default file (and order) when entering a directory. So http://host.com/ with both blog.php and index.php in the directory will serve up blog.php because it is first in the list you gave the server. If there is only index.php, it will serve that. If neither (and you don't have anything else in the list) it will throw a 404 because no default file is found.
EDIT: it will try to list contents if not found. My bad. If you don't allow directory listing, then it will probably show an error code. To turn off directory listing look in options: http://httpd.apache.org/docs/current/mod/core.html#options
http://httpd.apache.org/docs/current/mod/mod_dir.html
Your rewrite rules seem to kind of want do the same thing in a different order. If you request http://host.com/a and a is not a file or directory (according to the conditions) it will go to index.php.. if index.php doesn't exist, then it will loop until the server catches it, because you don't check that. So, that means the second set of conditions don't do anything, because either index.php exists or it doesn't and the next set probably won't really be reached unless it does.
You need to decide how to differentiate the two (/blog/ for the blog.php and / for index.php or something) and make one of them the default. If you want to randomize it, I would suggest doing that through PHP.
http://httpd.apache.org/docs/current/mod/mod_rewrite.html
.. to redirect from root to /forums/ through htaccess try this:
RewriteEngine on
RewriteCond %{REQUEST_URI} !^/forums/
RewriteRule ^(.*)$ /forums/$1 [L]

ignore specific directories in htaccess using mod_rewrite

I've got the following code in my .htaccess to strip out index.php from the urls in my CMS-based site.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
This code works great and it routes requests exactly how I want. For example, with URL: http://example.com/contact/ the directory contact doesn't actually exist if you look in the FTP; instead index.php handles the request and shows my contact info. Perfect. Well, almost perfect.
I want to modify this code to specify a couple directories in FTP that should be ignored. For example, if I've got a folder called assets, when I go to http://example.com/assets/ the default DirectoryIndex page is displayed. Instead, I want this directory to be ignored -- I want index.php to handle /assets/.
TL;DR: How can I modify the above code to explicitly ignore certain existing directories (so that index.php handles them instead of the DirectoryIndex)?
Why not adding this below or before your code?
RewriteRule ^(assets/.*)$ /index.php/$1 [L]

How to pass-through requests not going to specific directories to index.php/path?

In my present project I've got several directories: application (my MVC files, which mustn't be accessed), images, css, and js. Effectively I want all requests to images/css/js to proceed unchanged, but all others I wish to call index.php/my/path.
My .htaccess currently looks like this, and is wreaking havoc with my routing.
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond $1 !^(index\.php|images|js|css|robots\.txt)
RewriteRule ^(.*)$ http://example.com/index.php/$1 [L]
</IfModule>
This isn't working as relative URLs start stacking up, such as: example.com/blog/view/1/blog/view/2.
When I attempt something like,--
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_URI} !^/(index\.php|images|js|css|robots\.txt)
RewriteRule ^ index.php%{REQUEST_URI} [PT]
</IfModule>
I get this error with any request: No input file specified.
How can I force all requests not to my whitelisted directories to call, not redirect to (redirection murders posting, I found), index.php/path? IE, when /blog/view/1 is requested by the browser, .htaccess calls index.php/blog/view/1. The reference files at Apache's site aren't too clear about how to do this sort of thing—that, or, I am just missing the point of what I'm reading about RewriteRule.
And, I really want to understand this. Why will your answer work? Why are my attempts failing?
This is what I have in my .htaccess for my framework:
<IfModule mod_rewrite.c>
RewriteEngine on
#This will stop processing if it's images
RewriteRule \.(css|jpe?g|gif|png|js)$ - [L]
#Redirect everything to apache
#If the requested filename isn’t a file….
RewriteCond %{REQUEST_FILENAME} !-f
#and it isn’t a folder…
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?$1 [L,QSA]
#L = (last - stop processing rules)
#QSA = (append query string from requeste to substring URL)
</IfModule>
Hope this helps.
PS: Maybe you want to remove the lines to stop redirecting if it's a file or folder ;)
Antonio helped me get on the right track, so here's the resulting .htaccess:
<IfModule mod_rewrite.c>
RewriteEngine on
# skip if whitelisted directory
RewriteRule ^(images|css|js|robots\.txt|index\.php) - [L]
# rewrite everything else to index.php/uri
RewriteRule . index.php%{ENV:REQUEST_URI} [NE,L]
</IfModule>
You're going to have to do that using PHP. For example, if you wanted to split your URI into something like domain.tld/controller/action/param, then you could use the following PHP code as a start:
<?php
// Filter URI data from full path
$uri_string = str_replace($_SERVER['SCRIPT_NAME'], '', $_SERVER['REQUEST_URI']);
$uri_string = trim($uri_string, '/'); // Make sure we don't get empty array elements
// Retrieve URI data
$uri_data = explode('/', $uri_string);
In that case, $uri_data[0] is the controller, $uri_data[1] is the action, and beyond that are parameters. Note that this isn't a foolproof method, and it's never a great idea to trust user-entered input like this, so you should whitelist those controllers and actions which can be used.
From here, knowing the controller and having a consistent directory structure, you can require_once the proper controller and call the action using variable variables.
This is what I use in my .htaccess file for my CMS:
Options -Indexes
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ index.php/$1 [NC,L]
And then in my index.php file I have:
$path_info = '';
$path_info = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : $path_info;
$path_info = isset($_SERVER['ORIG_PATH_INFO']) ? $_SERVER['ORIG_PATH_INFO'] : $path_info;
$request = explode('/', trim($path_info, '/'));
// if $request[0] is set, it's the controller
// if $request[1] is set, it's the action
// all other $request indexes are parameters
Hope this helps.

Resources