Directory Structure for Multiple Applications

I’m new to Yii - I’ve installed the basic application template (archive) without any issues.

I now want to make the framework available for multiple applications, so that the framework does not have to be installed for each app.

I’ve looked at the advanced application template, but I think I’m correct in saying that it’s more for a project that shares the same code base (frontend/backend)?

The structure I had in mind was the following:

[indent]/vendor[/indent]

[indent]/Apps/TestApp1[/indent]

[indent][indent]/Apps/TestApp1/assets[/indent][/indent]

[indent][indent]/Apps/TestApp1/commands[/indent][/indent]

[indent][indent]/Apps/TestApp1/config[/indent][/indent]

[indent][indent]/Apps/TestApp1/controllers[/indent][/indent]

[indent][indent]/Apps/TestApp1/mail[/indent][/indent]

[indent][indent]/Apps/TestApp1/models[/indent][/indent]

[indent][indent]/Apps/TestApp1/runtime[/indent][/indent]

[indent][indent]/Apps/TestApp1/tests[/indent][/indent]

[indent][indent]/Apps/TestApp1/views[/indent][/indent]

[indent][indent]/Apps/TestApp1/web[/indent][/indent]

[indent]/Apps/TestApp2[/indent]

[indent][indent]/Apps/TestApp2/assets[/indent][/indent]

[indent][indent]/Apps/TestApp2/commands[/indent][/indent]

[indent][indent]/Apps/TestApp2/config[/indent][/indent]

[indent][indent]/Apps/TestApp2/controllers[/indent][/indent]

[indent][indent]/Apps/TestApp2/mail[/indent][/indent]

[indent][indent]/Apps/TestApp2/models[/indent][/indent]

[indent][indent]/Apps/TestApp2/runtime[/indent][/indent]

[indent][indent]/Apps/TestApp2/tests[/indent][/indent]

[indent][indent]/Apps/TestApp2/views[/indent][/indent]

[indent][indent]/Apps/TestApp2/web[/indent][/indent]

The index.php in each application has been amended from:




require(__DIR__ . '/../vendor/autoload.php');

require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');



To:




require(__DIR__ . '/../../../vendor/autoload.php');

require(__DIR__ . '/../../../vendor/yiisoft/yii2/Yii.php');



This does not work, I am getting multiple errors with the first being:

The file or directory to be published does not exist: C:\wamp\Apps\TestApp1\vendor\bower/jquery/dist

Could you point me in the correct direction on how to achieve this?

Many Thanks

I am dealing with similar problem, I also want to share Yii2 for more projects.

I am trying to separate Yii2 framework code into folder. I tried it install with composer but it "pre-installed" vendor folder containing "bower-assets, ezyang and other folders".

When I separated yii2 folder fron vendor/yiisoft and placed it to web_root folder and then tried from web accessible folder (document_root) and it’s index.php file load framework, I am constantly getting some errors.


// 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');


require(__DIR__ . '/../path/to/yii2/framework/lib/vendor/autoload.php');

require(__DIR__ . '/../path/to/yii2/framework/lib/vendor/yiisoft/yii2/Yii.php');


$config = require(__DIR__ . '/../path/to/folder/containing/app/files/not-accessible/from/web/config/web.php');


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



So maybe anyone who tried to at least get "pure" Yii2 framework code using Composer?

My composer.json:


{

	"authors": [

    	{

        	"name": "David dubak Dubovsky",

        	"role": "development"

    	}

	],

	"require": {

    	"php": ">=5.4.0",

    	"yiisoft/yii2": "2.0.4"

	}

}



So I quite solved problem and separated Yii2 framework code from composer installation and placed it into desired folder in my folder structure.

Now I am able to just from index.php say where is my Yii2 lib located and also application code. So they are not accessible from the web.

The problem is that those pre-installed extensions like "debug" or "bootstrap" are not working. But I will look at it later.

I’m still struggling with this using the archive installation methods, any ideas?

Has anyone got any advice on this - I haven’t been able to get this working.

I’m sure this would be a common problem for anyone wanting to use the framework for multiple projects. I don’t want to have to install the framework for each project.

Thanks

This might be the answer:




{

    "config": {

        "vendor-dir": "../vendor"

    }

}



I’m not sure if it works or not.

But, I don’t understand why you have to share the vendor directory among all of your applications.

Do you worry about the disk space? The whole ‘vendor’ directory is only 38 mb on my server disk (‘vendor/yiisoft’ is just 5 mb!).

You should note that the “dependencies” might vary among the apps. It’s far safer to have an independent vendor directory for each app.

Thank you for your response, sorry it’s been a while. I will try out the suggestion when I get some time and get back to you.

I am looking to migrate a CRM system to the Yii Framework. There could be multiple instances of the CRM system on the same server (for different clients), I therefore want all instances to point at the same framework instance.

You can definitely set it up to use a different vendor location. You’ll need to change the include paths in most of your bootstrap files, as well as updating the composer.json file.

In composer.json




...

"config": {

        "process-timeout": 1800,

	"vendor-dir":"/path/to/shared/vendors/"

    },

...

 "extra": {

     ...

        "asset-installer-paths": {

            "npm-asset-library": "/path/to/shared/vendors/npm",

            "bower-asset-library": "/path/to/shared/vendors/bower"

        }

    }



Your revised requires should look something like:




require('/path/to/shared/vendors/autoload.php');

require('/path/to/shared/vendors/yiisoft/yii2/Yii.php');



Then you need to update the following (Assuming multiple basic apps)

/yii

/web/index.php

/web/index-test.php

/tests/codeception/_bootstrap.php

/tests/codeception/bin/_bootstrap.php

Then, in your main config/web.php add




    'vendorPath' => '/path/to/shared/vendors',



As stated, ONLY do this if you want all of those applications to run with the same dependencies.

There is just no point in doing that!

Why?

That way, when something needs to be updated/tweaked, all your clients are going to be affected.

There is a good reason why Composer packages are managed per project.

Only PHP people will think that it is a good idea. ;)

Updating those clients will only take a simple bash script that executes ‘composer update’ or whatever - and that is all you need to do.

Having shared packages also makes it impossible to tweak the individual clients…

But, as always, if you are using Yii, you can do it your way. ;)

Because we are our own client. I have 5 websites that all share common base. It’d be ridiculous to store 5+ copies of the vendor libraries on the server.

That’s exactly why. Update one, and they’re all up to date.

It’s essentially just a different version of the advanced app. If you have multiple domains or subdomains running common code, does it matter where that vendor library is?

I am glad that we turned off downvoting :P

If those ‘clients’ are wholly independent applications, you are “breaking all the rules”, Dana :)

To me, one of the best changes from Yii 1 to Yii 2 is exactly the fact that the individual applications are self-contained.

You don’t need to break all the things when you upgrade Yii.

I really love that Yii is a vendor, just like ‘extensions’ has become.

The ‘extensions’ directory was a major head ache and/or a royal pain in the rearside in Yii 1.

You cannot compare it to the advanced application because that application is one application as the name implies - they share not only the ‘vendor’ directory, but also have shared views, models, …

It’s a big “if” - Your premise that they’re wholly independent applications is flawed ;) They’re not. Far from it.

It’s 5 different front ends that share a considerable amount of code. I don’t think this is something that most people would ever need or want to do, but in our case, it’s essential.

If you’ve got:

/www/site1

/www/site2

/www/site3

/www/site4

/www/sharedLib/vendors/

/www/sharedLib/commonCustomCode/

(Note: that doesn’t preclude you from also adding /www/site6 that has it’s own vendor library)

How is that different from:

/www/backend

/www/frontend

/www/environments

/www/console

/www/vendors

/www/common

except I’d need:

/www/backend

/www/frontend

/www/frontend2

/www/frontend3

And … I’d have a lot of other directories out in the main www folder (common, console, tests,etc.) that I would have to keep track of in relation to OTHER sites on the server that don’t use Yii 2.0.

The big difference is that /common/, /console/, etc. are primarily in the /sharedLib/ and only those things which are unique to each app are outside of that, as they are in the advanced app backend and frontend.

It’s really no different, just a lot cleaner for a server where there is a mix of frameworks being used. If one of the sites needs to be held to some different version level, or use a completely different package, then of course it would be set up without the shared vendor library. But if 99% of what you’re doing needs to stay in perfect sync, sharing that library is the best way to do so.

There’s just nothing worse than having to update a module (or 5) that’s in use in 3 different sites and having each themed to a completely different version of jQuery and Bootstrap :P I’d much rather just keep all three up to date and talking the same language.

I’m certainly not suggesting that this is something everyone should do, as most people won’t have so many applications that are so dependent on one another. But if you’re in a position where you need to, it’s good to know you can. ;)

I totally agree :lol:

I agree with Dana and am searching for a good, clear solution to have all extensions of all yii2 projects under common vendor-dir and each project’s composer.json would list only needed extensions in the require section

You need to list them all in every project’s require section or you’ll have to run composer update only from the project which has all extension listed.

If you put all extensions into composer’s global config, then you’ll still need to remove the require (and require-dev) section from every project’s composer.json.

The problem is with the way composer interprets composer.json. If section is present in the local file, then it takes precedence over the global settings in whole, so it deletes anything not listed instead of merging (at least on demand?).

Any idea to have every project consistent (list properly only needed extensions in require, require-dev, extra sections) to be able to move it from development machine to production server separately, and still have everything required to run multiple projects on development machine under single vendor path?