Mar 3, 2018

klimov-paul

Yii 2.1 Early Access

Interested developers are welcome to try Yii 2.1 branch, which is already available for early access. It brings many new features and embraces PSR standards. However, it also brings significant backwards compatibility break. While it is not yet finished, it is already prepared for usage as a development platform.

Warning: Yii 2.1 branch is unstable and can be broken anytime, its current code may change dramatically before actual release. Do NOT attempt ot use it for the actual projects in 'production' stage, unless you are ready to deal with the consequences!

You can browse Yii 2.1 code at GitHub and install it using "2.1.x-dev" version for "yiisoft/yii2" Composer package.

Composer

In order to install Yii 2.1, you should specify version "2.1.x-dev" for "yiisoft/yii2" package in your 'composer.json' file:

"require": {
    "yiisoft/yii2": "2.1.x-dev",
    ...
}

Attention: since 2.1 Yii dropped its own PHP class autoloader in favor of the one provided by Composer. Thus you will need to configure "autoload" for your project at 'composer.json' otherwise PHP script will be unable to find classes declared at your project.

For example:

{
    "autoload": {
        "psr-4": {"app\\": ""}
    },
    "autoload-dev": {
        "psr-4": {"tests\\": "tests"}
    },
    ...
}

In case autoload for the project files is missing web application will trigger Yii application error like "Unable to resolve request 'site/error'".

Note that in 2.1 some former "yiisoft/yii2" package classes have been moved into separate repositories:

In case your project requires one of these, you should add corresponding packages to your composer.json. So in order get full equivalent of Yii 2.0 for 2.1, composer configuration should be the following:

"require": {
   "yiisoft/yii2": "2.1.x-dev",
   "yiisoft/yii2-jquery": "1.0.x-dev",
   "yiisoft/yii2-captcha": "1.0.x-dev",
   "yiisoft/yii2-rest": "1.0.x-dev",
   "yiisoft/yii2-mssql": "1.0.x-dev",
   "yiisoft/yii2-oracle": "1.0.x-dev",
   "yiisoft/yii2-maskedinput": "1.0.x-dev",
   ...
}

Most of the official extensions also have development branches compatible with Yii 2.1. The following composer configuration example will install all extensions available for 2.1:

"require": {
   "yiisoft/yii2": "2.1.x-dev",
   ...
   "yiisoft/yii2-debug": "2.1.x-dev",
   "yiisoft/yii2-gii": "2.1.x-dev",
   "yiisoft/yii2-swiftmailer": "2.2.x-dev",
   "yiisoft/yii2-bootstrap": "2.2.x-dev",
   "yiisoft/yii2-jui": "2.1.x-dev",
   "yiisoft/yii2-httpclient": "2.1.x-dev",
   "yiisoft/yii2-authclient": "2.2.x-dev",
   "yiisoft/yii2-mongodb": "2.2.x-dev",
   "yiisoft/yii2-sphinx": "2.2.x-dev",
   "yiisoft/yii2-imagine": "2.2.x-dev",
   "yiisoft/yii2-faker": "2.1.x-dev"
}

Basic code upgrade

Ensure that you code does not use any deprecated constructions like following:

  • Invocation of className(), e.g. SomeClass::className(). It should be replaced by native PHP ::class construction
  • Throwing or catching yii\base\InvalidParamException. It should be replaced by yii\base\InvalidArgumentException
  • Usage of yii\console\Controller constants, e.g. EXIT_CODE_NORMAL or EXIT_CODE_ERROR, for exit code. They should be replaced by constants provided via yii\console\ExitCode class.

Any DI object configuration should use '__class' keyword instead of 'class' for the class name specification. This affects DI container, Yii::createObject() and thus any application component specification. So former Yii application config like following:

return [
    'components' = [
        'mailer' => [
            'class' => yii\swiftmailer\Mailer::class,
        ],
        'mutex' => [
           'class' => yii\mutex\FileMutex::class
        ],
        'db' => [
            'class' => yii\db\Connection::class,
            'dsn' => 'mysql:host=localhost;dbname=myproject',
            'username' => '???',
            'password' => '???',
        ],
    ]
];

now should look like this:

return [
    'components' = [
        'mailer' => [
            '__class' => yii\swiftmailer\Mailer::class,
        ],
        'mutex' => [
           '__class' => yii\mutex\FileMutex::class
        ],
        'db' => [
            '__class' => yii\db\Connection::class,
            'dsn' => 'mysql:host=localhost;dbname=myproject',
            'username' => '???',
            'password' => '???',
        ],
        // ...
    ],
    // ...
];

Logging

At 2.1 logging has been rewritten according to PSR-3, which in particular allows you to use Monolog as logger for your project. Application component 'log' does not exist anymore. You should configure logger directly via Yii::setLogger() or using Application::setLogger(), e.g. 'logger' key in application config.

So former Yii log config like following:

return [
    'bootstrap' => [
        'log', // should be removed for 2.1
    ],
    'components' = [
        // should be converted to 'logger' for 2.1
        'log' => [
            'traceLevel' => YII_DEBUG ? 3 : 0,
            'targets' => [
                [
                    'class' => yii\log\FileTarget::class,
                    'levels' => ['error', 'warning'],
                ],
            ],
        ],
        // ...
    ],
    // ...
];

now should look like this:

return [
    // no bootstrap
    'logger' => [
        'traceLevel' => YII_DEBUG ? 3 : 0,
        'targets' => [
            [
                '__class' => yii\log\FileTarget::class,
                'levels' => ['error', 'warning'],
            ],
        ],
    ],
    'components' = [
        // no 'log' component
        // ...
    ],
    // ...
];

Caching

At 2.1 caching has been rewritten according to PSR-16, which allows your usage of 3rd party cache providers easily. In order to keep 'cache dependency' feature cache specification has been changed. Now any cache component should use yii\caching\Cache class (or implement yii\caching\CacheInterface), while actual cache storage is determined via Cache::$handler.

So former Yii cache config like following:

return [
    'components' = [
        'cache' => [
            'class' => yii\caching\DbCache::class,
            'cacheTable' => 'my_cache',
        ],
        // ...
    ],
    // ...
];

now should look like this:

return [
    'components' = [
        'cache' => [
            '__class' => yii\caching\Cache::class,
            'handler' => [
                '__class' => yii\caching\DbCache::class,
                'cacheTable' => 'my_cache',
            ],
        ],
        // ...
    ],
    // ...
];

Be careful: it may happen, that in case of incorrect cache configuration (e.g. using old one), you will not receive an immediate error, but just some latent incorrect behavior.

JQuery

As it was already said all JQuery related code has been moved to "yiisoft/yii2-jquery" package. This, in particular, includes yii.js, client-side validation for ActiveForm and filter handler for GridView. Without extra adjustments simple usage of ActiveForm or GridView widget will no longer provide any JavaScript code registration, and thus no 'fancy' client-side effects. You will need to attach 'clientScript' behavior to the widget in order to make it behave like before.

ActiveForm example:

<?php $form = ActiveForm::begin([
    'id' => 'login-form',
    'as clientScript' => yii\jquery\ActiveFormClientScript::class, // attach JQuery client script, enabling client-side validation:
]); ?>
...
<?php ActiveForm::end(); ?>

GridView example:

<?= GridView::widget([
    'as clientScript' => yii\jquery\GridViewClientScript::class, // attach JQuery client script, enabling filter auto-submit
    'dataProvider' => $dataProvider,
    // ...
]); ?>

Live example

In order to get more clear impression on Yii 2.1 usage, you may refer to the working project template, which has been already updated to 2.1 - ii2tech/project-template

Install via composer:

composer create-project --prefer-dist --stability=dev yii2tech/project-template yii-test 2.0.x-dev

Install via git:

# clone repo:
git clone git@github.com:yii2tech/project-template.git yii-test
# go to project:
cd yii-test
# get 2.0 branch:
git fetch
git checkout 2.0

In order to configure project and make it running run 'install.php' file:

cd yii-test
php install.php

Comments (15)

  1. Mar 3, 2018

    Using two words as keys is not a good idea - instead of "as clientScript" could be simply "clientScript" or just "script" perhaps? Attaching JS scripts to each element - well, we have hundreds of ActiveForm elements ... would it be possible to configure globally attached library scripts? Otherwise it would take a lot of additional scripting comparing to 2.0 - simplicity fading away ...

    Also what's the reasong to use underscored "__class" instead of previous "class" ? Is there conflict somewhere with PHP reserved word?

  2. Mar 4, 2018

    @lubosdz, I think it's fine to do a DI hack:

    Yii::$container->set(\yii\widgets\ActiveForm::class, [
        'as clientScript' => \yii\jquery\ActiveFormClientScript::class
    ]);
    
  3. Mar 5, 2018

    Using two words as keys is not a good idea

    It is like that for beahviors since the very first 2.0 version. Noone complained so far :)

    Also what's the reasong to use underscored "__class" instead of previous "class" ?

    Being able to configure a component with a property named class which is quite common.

  4. Mar 6, 2018

    Ради нескольких людей, кто использует свойство class вы сломали конфиги у тысяч проектов. Приложу мнение мудрого человека по этому вопросу https://github.com/yiisoft/yii2/issues/2871

  5. Mar 6, 2018

    @vyachin, that was for a change within 2.0 which is meant not to break backwards compatibiltiy intentionally. 2.1 is meant to be compatibility breaking release where we have a chance to clean things up without looking at existing code too much.

  6. Mar 6, 2018

    @samdark я Вас полностью поддерживаю в движении вперед. Однако конкретно это изменение сделано в угоду "очень узкого круга лиц" и отрицательно сказывается на всем сообществе. Конечно два символа не сильно скажутся на объеме кода, но сделают его менее читабельным, а кривую обучения более сложной.

    Почему Вы решили, что свойство $class используется чаще чем $class? Те кто использовал название $class были готовы к ограничениям и как-то его обходили. Однако возможно были те кто использовал $class. Теперь обоим группа придется вносить изменения.

    Мне очень нравится, все что делает команда Yii, однако я очень надеюсь, вы не станете развивать yii согласно требованиям или видению некоторых членов или компаний.

  7. Mar 6, 2018

    вы сломали конфиги у тысяч проектов.

    От этого изменения ниодин проект сам по себе не сломается. Правку нужно вносить только если вы переходите с версии 2.0.х на 2.1.х, а это делается осознанно.
    Старые версии у вас никто не отнял. Если переход на новый синтаксис вызывает у вас такой большой стрэсс, но оставайтесь на старых версиях, где ничего не ломается.

    Конечно два символа не сильно скажутся на объеме кода, но сделают его менее читабельным, а кривую обучения более сложной.

    Использование двойного подчеркивая (__) является распрастраненной практикой в PHP для обозначение специальный конструкций и методов например:

    • __FILE__
    • __DIR__
    • __construct()
    • __set()/__get()
    • и т.д.

    Странно, что в то время, как все эти конструкции не вызывают у вас негодования, использование __class превратилось для вас в трагедию...

    Конструкция __class теперь ясно отмечена как специальная, при этом ее назначение угадать не сложно.
    Кроме того такая конструкция хорошо гармонирует с заданием параметров конструктора - __construct(). Например:

    [
        '__class' => app\components\Foo::class,
        '__construct()' => ['some constructor argument 1', 'some constructor argument 2'],
    ]
    

    Теперь обоим группа придется вносить изменения.

    Когда я обновлял шаблон yii2tech/project-template на исправление конфигурации (она там сравнительно сложная) у меня ушло около 5 минут.
    Если у вас достаточно свободного времени чтобы подыскивать мудрые изречения из интренета, то наверняка найдется время и дня внесения таких правок, если хорошенько поискать.

  8. Mar 6, 2018

    @klimov-paul Оставим в стороне язык PHP.

    Никто не скажет что это выглядит гармонично

    [
    	'foo'=> [
        	'__class' => app\components\Foo::class,
        ]
    ]
    

    вот эти варианты логичны, понятны и "гармоничны".

    [
    	'foo'=> [
            'class' => app\components\Foo::class,
            'className' => app\components\Foo::className(),
        ]
    ]
    

    А первый вариант знаком любому, кто знаком с yii начиная с первой версии.

    Странно, что в то время, как все эти конструкции не вызывают у вас негодования, использование __class превратилось для вас в трагедию...

    Я не делаю из этого трагедию. Мне кажется изменение названий параметров не есть движение вперед.

  9. Mar 6, 2018

    Я не вижу принципиальной разницы каким ключевым словом обозначено имя класса в конфигурации будь то class или __class. Как уже было сказано, изменение вызвано необходимостью дать возможность разработчикам свободно объявлять поля или свойства с названием class и задавать для них конфигурацию, например:

    class Ticket
    {
        public $class;
    }
    
    Yii::createObject([
        '__class' => Foo::class,
        'class' => 'A',
    ]);
    

    Тем временем ваши контр-аргументы сводятся к тому, что новая нотация оскорбляет ваши эстетические чувства. Но тут уж ничего не поделаешь. Как говориться "на вкус и цвет товарищей нет".

  10. Mar 6, 2018

    Some guys cannot understand russian :-)

  11. Mar 6, 2018

    @lubosdz

    That's why I'm replying in English. Short version is that @vyachin doesn't like class__class change because it's breaking existing app and Paul explains why the choice was made (repeating nearly same words as I've used above).

  12. Mar 7, 2018

    @samdark
    OK, thank you.

    Since there will be many BC & design changes in 2.1, it might be better to set version 3+ rather than 2.1 to avoid confusions in composer.json.

    BTW we are in a difficult situation - we are working (30% done) on a long-term project which should live for 10+ years, we have put lots of efforts into it already ... Now new version with many BC changes is coming out ... should we stick with version 2.0 or wait & rework for 2.1/3.0 with longer life cycle ... What would you do ? :-)

  13. Mar 7, 2018

    I'd extract more into domain layer that doesn't depend on the framework much i.e. separate classes that do not inherit from anything and cover these w/ tests. These will work regardless of Yii version.

  14. Mar 24, 2018

    Hi, at first place, this looks great and I can't wait to give it a try :)
    Anyway, there is one typo issue in example

    'mutex' => [
    	__class' => yii\mutex\FileMutex::class
    ],
    

    There is missin ' at the begining of __class.

  15. Mar 24, 2018

    Yes. Fixed it. Thanks.

Signup in order to comment.