Component creation

In Yii 1.x, we have Yii::createComponent() to create a new component. We also have CWidgetFactory and skin feature to systematically initialize component properties.

In Yii 2.0, we hope we can unify both of them, and if possible we can make use of the dependency injection pattern. Of course, we still want the creation process to be efficient, since it is directly related with the overall performance of the framework.

If you have any idea, please discuss it here. Thanks.

I hope this will not affect the way (ajax) events are handled - that is one thing that might be improved upon…


I had some problems with the jui-widgets. I wanted to apply some basic values to all jui-widgets, so I had to create a skin file for every widget type rather than just for the base class CJuiWidget.

Would be cool if you could enable "skinning-by-parent-class".

Guys, it’s not about JavaScript part at all, it’s about configuring defaults for components like it’s currently done for widgets. I like the idea but not sure about how it can be implemented without introducing another $this->widget like call.

I don’t meant in JavaScript, my posting was about PHP class attributes, e.g.

public $scriptUrl;

public $themeUrl;

Hello, i think a new Dependency Container Class should be created to hold some parts of createComponents methods

and the CwidgetFactory methods and properties all together, this new class CDependencyContainer should

handle some default values for some properties of the components.

//can be abstract or interface

  abstract class CDependencyContainer{

          public $params_cwidgetFactory=array(); 

          public $params_components=array(); 

       public function __construct($params=null,$something=false){

                    $this->params_components = $params;

               //by default the $params_components should load some 

           if(empty($this->params_components ))

                  // load all default values for component creation


                  //load the user defined params




I have argued for the unification of these two components before - I have nothing to add, except I’m happy to see that’s the direction you’re planning to go :slight_smile:

As for dependency injection - I have yet to see a truly good implementation in PHP, and frankly I have my doubts as to the usefulness of this pattern in the PHP language.

Most days, the application component concept used in Yii does a good job - and I realize this is not dependency injection, but it is a component registry, such as is commonly used (in some form or another) in DI implementations.

The component registry tends to work well in PHP, and many frameworks implement one. I’m not convinced that the additional benefits of DI are worth the complexity and overhead they add. And I’m not saying there aren’t benefits, but given that DI is not a simple pattern to understand in the first place, I think you will find that very few people will be able to use it correctly (or willing to use it at all) to begin with. It just doesn’t lend itself well to the average PHP developers pragmatic approach to programming.

That, and as said, show me an implementation in PHP that performs well, actually does DI, and is easy to understand and implement? (I would love to see one, but yours would be the first!)

I agree with this sentiment, the application component as a registry is a good compromise for most uses. It is also a simpler concept to understand and use. There is a tricky point with regards to components that require another component, e.g. a db cache component needing a db component. Currently, the cache component would accept a db id string and during init, it will reference this db from the registry. This means that the cache component is coupled with the registry.

Just for some inspiration, the German Wikipedia page has a list of DI-Frameworks.

I’m not really concerned with that, given that the entire application is probably coupled with the registry to begin with.

Of course, with DI, you could decouple it all, which would make your unit tests more consistent - even if currently it’s not a great hassle to just replace certain application components during test runs.

As said, I’m not against DI - unless it’s as bad as the other PHP implementations I’ve seen :wink:

I’ve remembered an issue with config we currenty have. At least it’s true for widget factory. Example: need to specify image for a grid button via widget factory but it should be relative to webroot (application can be inside of webroot directly or inside a subdir). We have to use Yii::app()->baseUrl and we can’t since config is read before application is fully functional.

Possible solution:

Allow using anonymous functions in config. If config item is anonymous function, execute it and use result during component initialization. This was I’ll be able to postpone calling Yii::app()->baseUrl and it will work.

I have run into this problem myself - it seems more to be a problem with the way configuration is created.

In my own applications, I’ve been using a custom configuration framework, which allows multiple layers of configuration - e.g. a fixed base configuration, separate layers on top of that for live/test/dev sites, and another layer on top of that with your local overrides.

More to the point, this configuration-class runs prior to loading/initializing the framework and application object, and allows each layer to use the configuration values provided by the previous layer. Things like base URL or other base paths/URLs are configured in the fixed base configuration, so that live/test/dev/local configurations can aggregate these values.

I could find sample code and post it if there’s any interest…

Does baseUrl have to be a method? Would it make sense for Yii to load a constants.php from the config/ directory and define the base URL there. Then you can create a helper file to use the base url anywhere you needed it or use the constant directly in cases where you cannot use a helper.

Well, it’s much more handy to get baseURL automatically. You can define constants the way you’ve suggested in Yii 1.1. No problem with it.