5

I am working on a yii2 project, and would like to deploy it to an apache server where the entire website is expected to exist in the /public_html directory, and /public_html is the web root for that host. The issue is that yii2 expects the web root to be /web, and it expects most of the site hierarchy to exist outside of the /web directory.

I would prefer not to have to change the webroot to /public_html/web, and for future projects, it may not be an option. So, is there a way to place the entire site hierarchy in /public_html , and still have the site work correctly?

I have tried creating a /public_html/.htaccess file with the following contents:

    RewriteEngine on
    RewriteCond %{REQUEST_URI} !web/
    RewriteRule (.*) /web/$1 [L]

And this seemed to work correctly, at first. Nothing outside of /public_html/web was accessible, and files within subdirectories of /web, such as /web/js/signup.js which could be accessed via the url http://localhost/js/signup.js, but this caused my routing rules (which were set up on a local system where I could have the web root pointing at /web) to no longer be recognized.

So, I would be happy with either an alternate to the .htaccess route, or a suggestion to how to fix the routing rules so that the .htaccess route would work.

Edit for Clarification

I have a hosting provider where the web root is ~/public_html . Yii has documentation explaining that you can rename www to public_html, and have everything that would normally be outside of /www located in ~, along with the various dotfiles and user-documents that Linux normally places in ~. I would prefer to have all site-related directories together (under the webroot).

As an alternative, a two-directory structure, such as the following would work:

~/
 |--- (Various dotfiles and subdirectories unrelated to the web site)
 |--- yii - Contains all subfolders that should be outside of the web root
      |--- commands
      |--- config
      |--- controllers 
      |--- (etc...)
 |--- public_html - Contains everything that can be within the web root.
      |--- (etc...)
TMorgan
  • 655
  • 1
  • 7
  • 13

2 Answers2

3

This has been asked so many times that they made a page for it in the Yii2 docs.

I personally answered this too many times to remember.

arogachev
  • 33,150
  • 7
  • 114
  • 117
Mihai P.
  • 9,307
  • 3
  • 38
  • 49
  • 1
    I've read that page a few times, but it doesn't clearly address how to move all of the source files to within the web root. – TMorgan Oct 22 '15 at 17:41
  • 1
    It does not address it because it should not be done. Only a couple of index.php files should be int he web root, the rest should be outside. Security feature. – Mihai P. Oct 23 '15 at 06:58
2

This can be done via the use of aliases.

Move your web directory to the new webroot (assuming ~/mysite.com is your existing site):

rm -rf ~/public_html
mv ~/mysite.com/web ~/public_html

Then, you move everything that was outside of your webroot to the new directory:

mv -prf ~/mysite.com ~/mysite.example-external

At this point, you should have a web root at ~/public_html , and you should have everything else in ~/mysite.example-external. You then edit your ~/public_html/index.php file. Please note that this is not considered part of yii core, so it's ok to modify it. The new index should have some variation on this:

<?php

// comment out the following two lines when deployed to production
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');

$thepath = __DIR__ . '/../mysite.example-external';

require( $thepath . '/vendor/autoload.php');
require( $thepath . '/vendor/yiisoft/yii2/Yii.php');

$config = require( $thepath . '/config/web.php');

(new yii\web\Application($config))->run();

From here, you also have to add aliases to your ~/mysite.example-external/config/web.php file, so yii can find its core files. In the web.php, at the point where $config is assigned a value, modify it to look something like the following:

$config = [
    'aliases'   => [
        'webroot/assets' => '/Users/XXXXXX/mysite.example-external/web/assets',
        'root' => '/Users/XXXXXX/mysite.example-external/web',
    ],
TMorgan
  • 655
  • 1
  • 7
  • 13
  • Note that for the site this was originally pertaining to, I just let the external files clutter the home directory. This was done on a test site to see if it was possible. – TMorgan Feb 18 '16 at 22:13
  • All this make sense, but I do not understand how the last row: (new yii\web\Application($config))->run(); is going to work, when index.php is separated from the rest. How does the server know what yii is? – Perry J Apr 30 '17 at 21:32
  • The aliases in web.php file indicate the path that yii should be using to find files outside the webroot. To make this work, I had to modify the index.php file within the webroot to pull in the '/vendor/autoload.php', '/vendor/yiisoft/yii2/Yii.php', and '/config/web.php' files from this new root, but from that point on, autoload should know to search this external root. – TMorgan May 01 '17 at 15:40