Yii framework: Using htaccess for site in sub directory not working on Hostgator - apache

I'm trying to set up Yii site to be loaded from sub directory to root domain. In my root site folder I have only root .htaccess file and sub directory "subdir" which contains Yii site. I found a solution that works on my local environment:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*) subdir/index.php/$1 [QSA,L]
But when I upload the site to HostGator it just does not work correctly
For example
if I use http://localhost/contact on my local environment, correct page is opened (called site/contact - site controller and contact action. I've added Yii 'contact'=>'site/contact' rule to the urlManager, so both http://localhost/contact and http://localhost/site/contact can work)
If I use http://mydomain.com/contact or (http://mydomain.com/site/contact) on HostGator, I get default index page (called site/index - site controller and default index action instead)
When I choose to access subsites directly like http://mydomain.com/subdir/contact it works fine, but it does not work if I use http://mydomain.com/contact
I guess that I need somehow to change this last rule in htaccess, but not sure how. Thanks!

I've found alternative solution that works. I was forced to use old fashioned URLs instead of paths, so I've changed my urlManager to:
'urlManager'=>array(
//'urlFormat'=>'path',
'showScriptName'=>true,
'caseSensitive'=>false,
'rules'=>array(
...
)
)
And my root htaccess looks now like this:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /subdir/index.php?r=$1 [QSA,L]
So, when accessing
http://mydomain.com/site/contact
Actual mapped URL is
http://mydomain.com/subdir/index.php?r=site/contact
which as result returns correct contact page

Since, you stated in your previous question that www.mysite.com/mysite/frontend/www/controller/action works fine; you should be using:
AddHandler application/x-httpd-php53s .php .html
Options +SymLinksIfOwnerMatch
IndexIgnore */*
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{HTTP_HOST} ^(www.)?mysite.com$
RewriteCond %{REQUEST_URI} !^/mysite/frontend/www
RewriteRule ^(.*)$ /mysite/frontend/www/$1 [L]

You dont need to edit .htaccess. You just need to move the Yii entry script (index.php) and the default .htaccess up from the subdirectory to the webroot (so that they reside directly under public_html). Once you move index.php and .htaccess to the root directory, all web requests will be routed directly to index.php under webroot (rather than to the subdirectory), thus eliminating the /subdirectory part of the url.
After you move the files, you will need to edit index.php to update the references to the yii.php file (under the Yii framework directory) as well as the Yii config file (main.php). Lastly, you will need to move the assets directory to directly the webroot, since by default, Yii expects the assets directory to be located in the same location as the entry script).
That should be all you need to do, but if you need more details, I describe the approach fully here:
http://muhammadatt.tumblr.com/post/83149364519/modifying-a-yii-application-to-run-from-a-subdirectory

Related

Vue.js router on a shared hosting plan?

I deployed a simple Vue.js website to a shared hosting plan. The website consists of a few internal links that use the router. Links such as /contact or /about.
I read that I need to use a .htaccess on shared web hosts so the router can navigate between its paths. Indeed, I added this code in the .htaccess file:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</IfModule>
One thing I noticed is that the router can navigate between its internal links, for example if I'm on the www.domain.com and click on the contact link, it goes to www.domain.com/contact and the page opens up.
However www.domain.com/contact doesn't exist in reality because if I type it out manually in the browser's address bar (without accessing it via a link on a page), then I get a page not found error. That sucks because Google probably won't be able to index my page then.
Is there any way to fix that?
The server is also running PHP. It has a PHP website on it beside the Vue.js one. I think I will need to touch the .htacess in the root folder instead of the one in Vue.js's dist folder.
The .htaccess in the root folder (the one in the root domain) looks like this:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
Is there a way not to remove those? but also add the Vue.JS rules?

Page not found when rewriting URL through .htaccess

I've been having problems trying to set up my .htaccess for the site.
I am trying to remove a folder from the URL when a page accesses this. I managed to successfully remove the folder from the path using this post How can I remove this directory/folder from url with htaccess rewrite? but when I load the page up, none of the css, javascript or other resources are loaded correctly.
When I try to access the resource from the url it says 'The requested URL /modules/content/styles/default.css was not found on this server.'
Modules is the folder I am trying to remove when accessing a page, however it seems that when I added the code to htaccess, it's adding "modules" to all paths.
My file structure looks like this
I have a .htaccess file in the root directory with the code:
RewriteEngine on
RewriteRule !^/?modules modules%{REQUEST_URI} [L,NC]
I also have one in the modules folder with the code:
RewriteEngine On
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+modules([^\s]*) [NC]
RewriteRule ^ %1 [R=301,L]
I have tried multiple solutions but all end with "Page not found", this is the closest I have gotten but now I am having a problem with resources.
Any help would be great!
You need to change this rule in root .htaccess:
RewriteEngine on
# If the request is not for a valid directory
RewriteCond %{REQUEST_FILENAME} !-d
# If the request is not for a valid file
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule !^modules/ modules%{REQUEST_URI} [L,NC]

Redirect all to index.php using htaccess

I am writing a simple PHP-based MVC-ish framework. I want this framework to be able to be installed in any directory.
My PHP script grabs the request uri and breaks it off into segments. It makes segment 1 the controller and segment 2 the action. This goes all fine when I do this:
http://www.example.com/mvc/module/test/
It will go to the specific module controller and method. Now I have a default controller, the home controller, which is in folder home.
Now when I access this folder directly http://www.example.com/mvc/home/
It will display a 403 forbidden , because this folder does exist, instead it should also go back to http://www.example.com/mvc/index.php
If I would have installed the framework in a different folder, lets say folder framework it has to redirect back to http://www.example.com/framework/index.php
I would like to redirect every folder and php file back to the index.php, leaving everything else the way it is.
My first problem I encountered was it never redirects to the right folder, always to the domain root folder.
This is what I tried :
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]
Your rewrite rule looks almost ok.
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.
The $_GET['path'] variable will contain the fake directory structure, so /mvc/module/test for instance, which you can then use in index.php to determine the Controller and actions you want to perform.
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.
Alternative to $_GET['path'] (updated Feb '18 and Jan '19)
It's not actually necessary (nor even common now) to set the path as a $_GET variable, many frameworks will rely on $_SERVER['REQUEST_URI'] to retrieve the same information - normally to determine which Controller to use - but the principle is exactly the same.
This does simplify the RewriteRule slightly as you don't need to create the path parameter (which means the OP's original RewriteRule will now work):
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /index.php [L,QSA]
However, the rule about installing in a sub-directory still applies, e.g.
RewriteRule ^.*$ /mvc/index.php [L,QSA]
The flags:
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 Append, just in case you've got something like ?like=penguins on the end which you want to keep and pass to index.php.
To redirect everything that doesnt exist to index.php , you can also use the FallBackResource directive
FallbackResource /index.php
It works same as the ErrorDocument , when you request a non-existent path or file on the server, the directive silently forwords the request to index.php .
If you want to redirect everything (including existant files or folders ) to index.php , you can use something like the following :
RewriteEngine on
RewriteRule ^((?!index\.php).+)$ /index.php [L]
Note the pattern ^((?!index\.php).+)$ matches any uri except index.php we have excluded the destination path to prevent infinite looping error.
There is one "trick" for this problem that fits all scenarios, a so obvious solution that you will have to try it to believe it actually works... :)
Here it is...
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [L,QSA]
</IfModule>
Basically, you are asking MOD_REWRITE to forward to index.php the URI request always when a file exists AND always when the requested file doesn't exist!
When investigating the source code of MOD-REWRITE to understand how it works I realized that all its checks always happen after the verification if the referenced file exists or not. Only then the RegEx are processed. Even when your URI points to a folder, Apache will enforce the check for the index files listed in its configuration file.
Based on that simple discovery, turned obvious a simple file validation would be enough for all possible calls, as far as we double-tap the file presence check and route both results to the same end-point, covering 100% of the possibilities.
IMPORTANT: Notice there is no "/" in index.php. By default, MOD_REWRITE will use the folder it is set as "base folder" for the forwarding. The beauty of it is that it doesn't necessarily need to be the "root folder" of the site, allowing this solution work for localhost/ and/or any subfolder you apply it.
Ultimately, some other solutions I tested before (the ones that appeared to be working fine) broke the PHP ability to "require" a file via its relative path, which is a bummer. Be careful.
Some people may say this is an inelegant solution. It may be, actually, but as far as tests, in several scenarios, several servers, several different Apache versions, etc., this solution worked 100% on all cases!
You can use something like this:
RewriteEngine on
RewriteRule ^.+$ /index.php [L]
This will redirect every query to the root directory's index.php. Note that it will also redirect queries for files that exist, such as images, javascript files or style sheets.
Silly answer but if you can't figure out why its not redirecting check that the following is enabled for the web folder ..
AllowOverride All
This will enable you to run htaccess which must be running! (there are alternatives but not on will cause problems https://httpd.apache.org/docs/2.4/mod/core.html#allowoverride)
just in case you were still wondering how to redirect all request either if the directory exists (for core framework folders and files) to the framework index handler, after some error/success attempts just noticed I just needed to change the RewriteCond in the .htaccess file
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
the above condition states "not found files" and "not found directories", ok, what if just remove "not found" (!-d) line, and ended with something like the below:
RewriteEngine on
RewriteBase /framework/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /framework/index.php [L,QSA]
It worked for me like a charm
I just had to face the same kind of issue with my Laravel 7 project, in Debian 10 shared hosting. I have to add RewriteBase / to my .htaccess within /public/ directory. So the .htaccess looks a like
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /index.php [L,QSA]
After doing that don't forget to change your href in,
home
Example:
.htaccess file
RewriteEngine On
RewriteRule ^about/$ /about.php
PHP file:
about

mod_rewrite -> doesn't work as expected

i use the following .htaccess to redirect all requests to my index.php except if a folder or file exists.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?uri=$1 [QSA]
But if i try url's like domain.com/thing/a/thing/b i get redirected to my index.php but everything else is messed up. The html doesn't link properly to the stylesheet and so on.
My application is working kinda like a MVC-Framework, i.e. everything happens over the index.php. So i don't want that other files are accessible except files in a public folder and some specific files. Namely cron.php in the root and some css/js/image files down the folder structure.
More details on the file structure: https://bitbucket.org/BrainInBlack/source-motd-plus/src
Or do i have to link stylesheets and other stuff with absolute paths, i.e. "http://domain.com/path/to/style.css" and so on?
use a slash client before (.*)$ index.php?uri=$1.
use this code:
RewriteRule ^/client(.*)$ index.php?uri=$1
You either need to change all your links to absolute links or add a
<base href="http://domain.com/">
to the header of your pages.

mod-rewrite to ignore the subdomain

I'm using a mod-rewrite for pretty URLs, meant to run on the domain root. Working fine but now I'm trying to make it run on a subdomain and it keeps giving "500 Internal Server Error".
The subdomain automatically redirects to the folder with that name on my hosting account (sub.domain.com shows the content of domain.com/sub/). Does it fail because this request is already being mod-rewritten automatically or can I simply change something in the htaccess to address the subdomain instead?
Options +FollowSymLinks
IndexIgnore */*
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php
Contact your ISP and check if they are setting the DocumentRoot for the sub domains to the /domain/sub/ directory (it's probable) or alternatively using an internal RewriteRule to direct traffic to that directory (you can see if there's an external rewrite / redirect in place via Chrome or Firefox + firebug, use the developer tools to check the response header, on the network Tab). If they have set the document root you will need to copy or symbolically link ALL the files you want accessible via the sub-domain, to the /domain.com/sub/ directory e.g. the .htaccess, index.php, images, js and css files and sub directories. If they are using an internal rewrite, a quick tweak to your own existing internal rewrite, in the existing .htaccess file, should suffice e.g.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]