1. Because in Yii 2.0, we will use namespace, it will be troublesome to use static classes as helpers. For example, instead of writing 'CHtml::textField' in Yii 1.x, we will need to write 'yii\web\helpers\Html::textField' unless we use the namespace beforehand in the view script.
2. Static classes are difficult to be customized and extended.

Related with this we also have a design decision to make regarding "view". Currently, views in Yii are just PHP scripts. There's no view object (note that view renderer is a different thing). Questions are:

1. Should we create a view object in Yii 2.0?
2. If so, how can we maintain the current simplicity and efficiency in view usage?

About helpers:
Well, I think the way the helpers are working right now is great, however, if views are objects this functions can be moved to the View object.

About views:
I think it is a good idea, however, we need to get a way to keep the "views" as PHP-free files as much as possible IMHO, most of the designers I've been working with love the way Yii handles views.
Idea:
In MyController class we could call a MyView class that handles the views... someting like:

MyView::render('index', $params)

Well, this is the 'old-style' call... now we could be able to do something like:

the 1st implementation, render will create an instance of CView using the 3rd parameter to override class default properties, the first parameter to define the viewFile and the 2nd parameter to define the viewData
the 2nd one pass 1 argument that will be used by createComponent, in addition to 'class'=>$this->viewClass
I would go for the 1st one, as it is simpler

As for the helpers, I agree with Ricardo

Quote

if views are objects this functions can be moved to the View object.

but I haven't reached a conclusion about how the implementation should be done, as it is need be used by widgets, views, and sometimes, outside those 2

defined helpers are not singletons across view files (unless you define it as an object) , only application helpers are
We could use Yii::app()->setComponent($name,$value) instead, which would lead to conflicts between view defined helpers and application components

Hm, the first one won't work, because Html is neither a function nor a property. The second one could possibly work if written as "Yii::$Html->func();" (accessing a static property). But I'm not sure if __get works in a static context...

However, your first example looks like calling a plain function in c/c++ using namespaces. Maybe this would be the easiest solution for helpers: simply a collection of functions (and maybe also variables) defined in their own namespace (are static helper classes any more than that?).

Namespaces could be extended with new functions by the user. But on the other hand, autoloading and method overloading wouldn't be possible...

1. Should we create a view object in Yii 2.0?
2. If so, how can we maintain the current simplicity and efficiency in view usage?

I think having a View object could make mach sense and make the overal OO design more clean. Such a View class could act as container for the rendered output and also take away lot of rendering and post processing logic from the controller. Thus i don't think it would affect efficiency much (but can't really tell). The View object could also keep all view related properties: variables, layout, registered clientscripts, Css, etc. And of course contain the HTML helpers mentioned above.

@Ben
I like the idea of __callStatic, that could also be used to get components, and helpers could be components, as there is no difference between a component and a helper, correct me if I'm wrong

I guess this is true. I can't see any difference between those new, no longer static helpers and other application components.

So basically, no new syntax would be needed at all. Simply configure helpers as components. Done.

---

About the views:

I really like the current script-like views. And I believe the simpler they become, the better. I'm not sure what the new view-objects are intended to do. If they are only meant as containers around the view files like Mike suggested, then they're certainly a good idea (taking care of layout assignment, rendering, ...).

But the actual view itself should remain a simple html (xml, xforms, ...) script with as little php code inside as possible.

I've argued against the static helper classes before, and I know from building several large projects with Yii that attempting to extend or override functionality of the helpers is a pain. Static helpers, in my opinion, need to be eliminated - helpers need to be concrete classes so we can extend/override as needed.

So the question is where/how to configure the helpers.

I'm with the school of not introducing a bunch of new concepts - but rather use what Yii already provides. So adding your helpers as application components gets my vote - it's the simplest approach, and it's already supported and well-understood by anyone using Yii.

The question then is how to access the helpers most conveniently. We should benchmark the proposed solution by comparing to the existing solution.

What we have currently looks like this:

Hello, <?=CHtml::encode($name)?>

If the HTML helper was an application component, it would look like this:

Hello, <?=Yii::app()->html->encode($name)?>

Clearly, that's ugly and cumbersome, and involves a lot of overhead in terms of resolving the clasname, static method, application component and then finally the encode() method, on every single invocation. So that's not acceptable.

Someone pointed out that you could add the helpers to the controller, so then you'd have something like this:

Hello, <?=$this->html->encode($name)?>

That's slightly better, but still looks cumbersome and messy compared to the static method-call.

In terms of performance, the shortest path to the html helper would be via a local variable:

Hello, <?=$html->encode($name)?>

This is better in terms of performance, as it's just calling a method on an object - it's also shorter and easier to type than any of the other options.

In my opinion, that would be the best approach.

And I'm aware of the issues with this approach - like the fact that the helpers are now occupying the same namespace as the view-data, so that view-data could collide with your helpers. I don't see this as being a really big problem, and you can work around that, depending on how the helpers are introduced into the view-data.

The other problem is the fact that you would need to construct and initialize any required view-helper application components prior to rendering the view. Typically, that's going to mean one or two components, which would be required by the majority of views anyway, so I don't see that being a drastic issue either - and we're only talking about constructing these components once during any request that renders a view, so it doesn't seem like that's going to cause any real performance impact.

As far as how to get the helpers into local variables in the view, I would suggest adding a CViewRenderer::$helpers property - which by default might contain something like array('htmlHelper' => 'html'), e.g. a map where application component id => view-data variable name.

Since this means that collisions between view-data and helpers could occur, I would suggest throwing an exception if controller/action code attempts to overwrite a helper with another value.

On a note of backwards compatibility - I would say, don't worry too much about it. This being a major framework update, we should feel free to architect as needed, without worrying too much about backwards compatibility - we should favor comfort, speed and good practices of new applications and new developers, over migrations of legacy applications. What's much more interesting is the new possibilities and improvements, paving the way for the future - building a new app should be less effort and more joy, and if that means that migrating a legacy app takes more effort, so be it. Just my personal opinion :-)

If somebody does need to upgrade a project, this can be done quite easily by doing a replace-in-files on their view-folders, replacing "CHtml::" with "$html->".

I wonder if it was possible to configure "accessor classes"... Don't know how to name them. Classes that only serve the purpose to access data from elsewhere. Imagine if we could use the helpers like now:

echo CHtml::textField(...);

But without an CHtml class being actually declared. So the autoloader fires. It checks:

if (isset(Yii::app()->accessor['CHtml']))

And if such an accessor is defined, it creates an empty class that only implements the __callStatic based on application configuration:

I wonder if it was possible to configure "accessor classes"... Don't know how to name them.

I would strongly discourage the use of a "black magic" auto-loader with eval(), but I do find certain aspects of this idea to be interesting.

I see this being mostly useful for backwards compatibility purposes - for instance, if you look at what I described above, having the helpers available simply as application components, you could do this:

Assuming the instance-methods of the new HTML-helper are compatible with the static methods of the old CHtml class, this thin class should have CHtml working just the way it always did, but now with the added benefit of being able to extend/replace the underlying helper-implementation.

I would not recommend using this as the primary/recommended approach - HTML helper methods get called many times during every request, and this will add overhead. It also makes it less obvious how to reach the HTML helper instance, in case the new instance-based helper has properties or components you need to access - the static calls only facilitate method-calls.

So as mentioned, I find this interesting mainly for backwards compatibility purposes, not as a general pattern for a 2.0 approach that would get my recommendation.

But I could see you including this thin compatibility class - perhaps marking it as deprecated. Even if it's not 100% compatible with ye olde CHtml, it still might help speed up application migrations.

I agree. Using the component-style approach is far better, because it is well known, suits most our needs (don't like the lengthy call if used as a helper) and is easier to understand. Also a big problem with such generated classes would be, that they wouldn't be supported by IDEs. It's just that I had this idea and wanted to know if it's possible.

A set of legacy facades could be provided as a package, so they don't need to be in the core.

But I'm still thinking about a way how the helpers could be made accessible without the danger of variable name collisions, and without a lengthy syntax...

One of the things i like from Yii is its clean and easy code design... Yii 2.0 should maintain that...

Edit:

By the way, static classes are fast, non-static able to extend/override... is Yii going to loose speed in order to satisfy some needs? Can we find a way where both are satisfied? I truly won't like to loose speed...

I really like the idea of __callStatic, why not using from the CHtml object itself? can it be part of the CComponent? Would it be confusing? Maybe a CHelper base class extended from CComponent could have that __callStatic and then the rest of the helper extend from CHelper having __callStatic within... so It will depend on the programmer whether to use static methods or not

By the way, static classes are fast, non-static able to extend/override... is Yii going to loose speed in order to satisfy some needs? Can we find a way where both are satisfied? I truly won't like to loose speed...

Me neither, so I did a quick benchmark - check the results for yourself, and check my code, but from what I could gather, static method-calls are about 25-30% slower than instance method-calls.

Reality in PHP is often the opposite of what you might logically assume :-)

My guess is, the introduction of namespaces in recent version of PHP has added some overhead to static method-calls...

EDIT: of course, if you have a static compatibility class as I proposed, that will add overhead due to two method-calls and magic being invoked on every call. But as I emphasized, this was meant as a helpful means of getting through a migration, not an end-solution.