Backward Compatibility Questions

Just been looking at the following article and had a few question as to why a few things are why they are which breaks backwards compatibility and some in what seems like needlessly.

https://github.com/y...rade-from-v1.md

Why does the render method work in this way, the way it worked before was fine and if someone wanted to return the output there was an option to return the output if needed. I quite liked not having any echos in my controllers.

this seems a little pointless it opens up more options for errors as the syntax has become more complicated (i’m sure theres some people who don’t know where pipe is on the keyboard…??). Having it take two separate params was easier to interpret, broke the method if not done right (which is preferred as now it introduces a silent error (maybe, need to look at the method?)). I’ve also in the past overloaded this method and used the category field to do certain checks in certain instances which now has added an extra step.

I would prefer if this method at least supported both methods. Also Yii::t() is probably one of the most common methods in any large translated site and having to update all these methods is a pain if updating a project from 1.1.

Yii 2 is a completely different code base, redesigned from the ground up. The developers are aiming to create the best framework that they can rather than maintain maximum backwards compatibility.

You don’t need to upgrade old sites to Yii 2, the Yii 1.1.x branch will remain stable.

In answer to your question, I expect that the rendering has changed to prevent the code divergence caused by accepting a boolean parameter which either outputs or returns a string. I’m not sure about the changes to translation as it’s something I’ve not yet needed to use.

In essence, any changes are likely to be intended to produce more elegant and maintainable code. Backwards compatibility won’t be the main concern because people don’t need to upgrade old projects; this is a completely new framework version.

I completely disagree with this. Just because its new major version it makes no sense that someone will not be upgrading any existing applications. This is just bad practice and when 1.1 reached EOL then you’re left with a web application that which will be on unsupported software (mysql/php) and will no longer have security updates. Our web applications aren’t standard blogs or general sites, these are enterprise web applications in the truest sense and maintenance and development on these applications are ongoing.

Yii 2 also isn’t a completely different code base, yes a lot has been redeveloped and restructured but parts of 1.1 still exist (yii::t() / render for example). We know a lot of code will break in the 2.0 upgrades and I’m not disputing that just wondering why certain things have been changed when they don’t necessarily need to be. Just because yii have said they’re not going to maintain backwards compatibility doesn’t mean you need to take a hammer to everything.

Personally i don’t care if Yii2 breaks BC, neither you should(we really need to move forward with Yii).

Why?

Because Yii 1.1 branch is stable and can be used years from now on, and it will also be supported by the Yii team for a period of time after 2.0 is released.

Now, let’s assume you have a mighty huge project built on Yii 1 (i do have a lot of them) and in 2015 Yii team decides to drop the support for Yii 1.1.x.

What do you do ?

Well, having in mind that we’re talking about a stable branch there might be nothing for you to do, the app already works so if you don’t upgrade php or anything else nothing should break(please note i am using Yii 1.1 with php 5.5.0 RC now and it works perfectly).

The only concern is security issues, thing that it should not happen to you if you built yourself a secure app (yii already offers all the tools you need to accomplish this).

Bottom line is, you can use Yii 1.1 years after it is not supported any more, just deal with it, you are a developer not a designer.

Regarding the other issues you have, with render() and Yii::t() etc, just go to github and ask/make suggestions, etc. I know that we should get a Response Class in Yii 2, so the render method can become just a shorthand to the Response class, things are to be changed in Yii 2 from day to day, if you care about the direction it goes, just get on github and get involved.

Struggling to keep BC with Yii 2 is just unreal and it doesn’t cut the effort.

Let’s move on with Yii already, we are behind zend/symfony and i don’t like this, but i do like the direction Yii 2 goes.

I’m with Keith and twisted1919. They both gave good arguments and here I add one more: compromising for backwards compatibility can potentially hinder the progress of the framework.

I think you’re both missing the point here for arguments sake. Resolving those issues will in no way what so ever hinder yii 2.0 going forward. Those changes do not add any extra functionality. I’ve used BC as a example but the point is if it ain’t broke and makes no enhancement then why change it.

Everyone whos replied in this thread so far has failed to realise this and the arguments for continuing to use yii 1 because its a difficult to upgrade is incomprehensible to me and as a developer goes against my way of working. I’m not saying make it easy to upgrade from yii 1 to yii 2. I haven’t highlighted dozens of other breaking issues i’m just wondering about these two specific issues which make no sense to me.

Hi all,

I think Jaggi posted 2 questions asking for the reasons of the change in render and Yii::t(). Not that it’s a bad thing the changing, just what were the reasons. I don’t understand them also. Especially Yii::t() which isn’t clear anymore imo.

Jaggi, about the changes you highlighted, here’s my opinion:

I like it. Brings uniformity. Only one echo and it is done.

I don’t like it. Not because the method signature has changed, but because it brings more string mangling to the framework.

Unless there’s a good reason for this, I’d like to see this reverted. Or using arrays, which is better than strings IMHO.

It’s a bad practice to print an output by default instead of returning it. The PHP team made the same mistake a long time ago with some functions like var_dump(). When they realized that there were cases where the output should not be displayed, they tried to keep BC so they added an optional parameter. Yii 1 did the same.

Yii 2 prefers a clean and consistent interface, even if it breaks BC with Yii 1. All methods return a value instead of displaying it, whereas Yii 1.1 was not consistent (cf CHtml::link()).

It also removes some performance bottlenecks and complex code. In Yii 1.1, the rendering can be returned through "output buffering" (see ob_start() and such). But this has many side effects. It was also hard to handle several layers of output buffering, and this caused difficult bugs.

I suppose that this change was for performance reasons, but I’m not sure about this. As for migrating, it should be easy to apply a substitute regexp to every PHP file.

More generally, I believe that migrating an application from Yii 1.1 to Yii 2.0 will be a hard work. The two changes above are not much when most of the model code will have to be rewritten. No more CDataProvider, no relations() method, no CDbCriteria, etc.

Printing instead of returning is bad - that is not good functional programming style: the functions have side-effects. Or, put differently: they do things behind your back.

I do like the change.

If we want it printed, we print the data that we get from the function.

It also makes it easier to chain function calls, concatenate, delay output or send it to another function.

Good programming practice IMO.

render, makes sense. But what about t()? I can’t see any advantage other than obsfucation?

The main reason for the Yii::t() change is because I want it easier to use if your category is the default one (which is the case mostly). For example, you can use Yii::t(‘translate me’). Without this, you have to type Yii::t(‘app’, ‘translate me’).

I also like it better that you don’t have to explicit specify the translation category anymore. But then why not using like @Rodrigo Coelho suggested? If it’s a string, use it as the translation, if it’s an array(), use the first element as the category and the second as the translation. I think a is_array check is faster than a strpos && preg_match.

Qiang, thanks for the clarification!

I agree with Müller’s points.

I see two aspects being tackled here:

  1. Ease of use.

After reading the documentation for YiiBase:t, I agree with Qiang that it will be easy for app developers to use the method. We simply won’t need to pass the category when we’re using the default “app” category.

But this simplicity comes at a cost:

  • We will embed functionality in a string. And the the framework will have to check the string for this value.

  • Extension authors won’t probably have the same simplicity; they’ll need to embed the category inside the string (because I didn’t find a way to change the string from the default “app” category for a single Module; it is hardcoded in I18N). Having to specify the category in a module is not a big issue, though (the problem is having to do it inside a string).

  1. Embedding functionality in a string.

This is something I didn’t like from 1.1. One example in 1.1 occurs in the CActiveRecord::relations method for MANY_MANY relations, where you had to specify multiple parts of the relation in a single string.

In this case, having another method parameter would be ideal, but having an array could be a good compromise, with the benefits of:

  • Providing better documentation.

  • Being extensible (will probably need associative arrays).

  • Possibly being faster than handling strings (no benchmarks were made).

The array would be need only when there’s more information to provide than the message string.

The only drawback I can think of is that the code will be more verbose when the array is used.

I like Müller’s solution. Qiang, I think it is better than current one.

Pros

  • All the pros of current one.

  • Better IDE support.

  • Less error prone.

  • Familiar PHP syntax.

Cons

None?

What is Muller’s solution? Use some code examples to explain?

The proposed solution would use code like:




// Default category, as it is now:

Yii::t('message');


// Another category, with an array:

Yii::t(array('category', 'message'));



The order of the values (category and message) or if the array should be associative weren’t discussed.

Another way would be to make the method variadic. Allow signatures

t( message: string ): string

t( message: string, params: array ): string

t( message: string, params: array, language: string ): string

t( category: string, message: string ): string

t( category: string, message: string, params: array ): string

t( category: string, message: string, params: array, language: string ): string

or simly introduce a method t2.

@Ben: thanks. I like both. The t2 approach is slightly better.

Wait, what ?

So we should have Yii::t() and Yii::t2() ? Come on…