Upgrading from Version 1.1 ========================== There are many differences between Yii version 2.0 and 1.1, because Yii is completely rewritten for 2.0. As a result, upgrading from version 1.1 is not as trivial as upgrading between minor versions. In this chapter, we will summarize the major differences between the two versions. Please note that Yii 2.0 introduces many new features which are not covered in this summary. It is highly recommended that you read through the whole definitive guide to learn about these features. Chances could be that some features you previously have to develop by yourself are already part of the core code now. Installation ------------ Yii 2.0 fully embraces [Composer](https://getcomposer.org/), a de facto PHP package manager. Installation of the core framework as well as extensions are all installed through Composer. Please refer to the [Starting from Basic App](start-basic.md) chapter to learn how to install Yii 2.0. If you want to create new extensions or turn your existing 1.1 extensions into 2.0, please refer to the [Creating Extensions](extend-creating-extensions.md) chapter. PHP Requirements ---------------- Yii 2.0 requires PHP 5.4 or above, which is a huge improvement over PHP 5.2 as required by Yii 1.1. As a result, there are many differences at language level that you should pay attention to. Below is a summary of the major changes regarding PHP: - [Namespaces](http://php.net/manual/en/language.namespaces.php). - [Anonymous functions](http://php.net/manual/en/functions.anonymous.php). - Short array syntax `[...elements...]` is used instead of `array(...elements...)`. - Short echo tags ` 'MyClass', 'property1' => 'abc', 'property2' => 'cde', ], [$param1, $param2]); ``` More details about configurations can be found in the [Object Configurations](concept-configurations.md) chapter. Events ------ There is no longer the need to define an `on`-method in order to define an event in Yii 2.0. Instead, you can use whatever event names. You can trigger an event by calling the [[yii\base\Component::trigger()|trigger()]] method: ```php $event = new \yii\base\Event; $component->trigger($eventName, $event); ``` And to attach a handler to an event, you can use the [[yii\base\Component::on()|on()]] method: ```php $component->on($eventName, $handler); // To detach the handler, use: // $component->off($eventName, $handler); ``` There are many enhancements to the event features. For more details, please refer to the [Events](concept-events.md) chapter. Path Aliases ------------ Yii 2.0 expands the usage of path aliases to both file/directory paths and URLs. It also requires an alias name to start with a `@` character so that it can be differentiated from normal file/directory paths and URLs. For example, the alias `@yii` refers to the Yii installation directory. Path aliases are supported in most places in the Yii core code. For example, [[yii\caching\FileCache::cachePath]] can take both a path alias and a normal directory path. Path alias is also closely related with class namespaces. It is recommended that a path alias be defined for each root namespace so that you can use Yii the class autoloader without any further configuration. For example, because `@yii` refers to the Yii installation directory, a class like `yii\web\Request` can be autoloaded by Yii. If you use a third party library such as Zend Framework, you may define a path alias `@Zend` which refers to its installation directory and Yii will be able to autoload any class in this library. More on path aliases can be found in the [Path Aliases](concept-aliases.md) chapter. Views ----- The most significant change about views is that `$this` in a view no longer refers to the current controller or widget. Instead, it refers to a *view* object which is a new concept introduced in 2.0. The *view* object is of class [[yii\web\View]] which represents the view part of the MVC pattern. In you want to access the controller or widget in a view, you should use `$this->context`. To render a partial view within another view, you should use `$this->render()` now. And you have to echo it explicitly because the `render()` method will return the rendering result rather than directly displaying it. For example, ```php echo $this->render('_item', ['item' => $item]); ``` Besides using PHP as the primary template language, Yii 2.0 is also equipped with official support for two popular template engines: Smarty and Twig. The Prado template engine is no longer supported. To use these template engines, you need to configure the `view` application component by setting the [[yii\base\View::$renderers|View::$renderers]] property. Please refer to the [Template Engines](tutorial-template-engines.md) chapter for more details. Models ------ Yii 2.0 uses [[yii\base\Model]] as the base model class which is similar to `CModel` in 1.1. The class `CFormModel` is dropped. Instead, you should extend [[yii\base\Model]] to create a form model class. Yii 2.0 introduces a new method called [[yii\base\Model::scenarios()|scenarios()]] to declare supported scenarios and under which scenario an attribute needs to be validated and can be considered as safe or not. For example, ```php public function scenarios() { return [ 'backend' => ['email', 'role'], 'frontend' => ['email', '!name'], ]; } ``` In the above, two scenarios are declared: `backend` and `frontend`. For the `backend` scenario, both of the `email` and `role` attributes are safe and can be massively assigned; for the `frontend` scenario, `email` can be massively assigned while `role` cannot. Both `email` and `role` should be validated. The [[yii\base\Model::rules()|rules()]] method is still used to declare validation rules. Note that because of the introduction of [[yii\base\Model::scenarios()|scenarios()]], there is no more `unsafe` validator. In most cases, you do not need to override [[yii\base\Model::scenarios()|scenarios()]] if the [[yii\base\Model::rules()|rules()]] method fully specifies the scenarios and there is no need to declare `unsafe` attributes. To learn more details about models, please refer to the [Models](basic-models.md) chapter. Controllers ----------- Yii 2.0 uses [[yii\web\Controller]] as the base controller class which is similar to `CWebController` in 1.1. And [[yii\base\Action]] is the base class for action classes. The most obvious change when you write code in a controller action is that you should return the content that you want to render instead of echoing it. For example, ```php public function actionView($id) { $model = \app\models\Post::findOne($id); if ($model) { return $this->render('view', ['model' => $model]); } else { throw new \yii\web\NotFoundHttpException; } } ``` Please refer to the [Controllers](structure-controllers.md) chapter for more details about controllers. Widgets ------- Yii 2.0 uses [[yii\base\Widget]] as the base widget class which is similar to `CWidget` in 1.1. To get better IDE support, Yii 2.0 introduces a new syntax for using widgets. The static methods [[yii\base\Widget::begin()|begin()]], [[yii\base\Widget::end()|end()]] and [[yii\base\Widget::widget()|widget()]] are introduced and can be used as follows, ```php use yii\widgets\Menu; use yii\widgets\ActiveForm; // Note that you have to "echo" the result to display it echo Menu::widget(['items' => $items]); // Passing an array to initialize the object properties $form = ActiveForm::begin([ 'options' => ['class' => 'form-horizontal'], 'fieldConfig' => ['inputOptions' => ['class' => 'input-xlarge']], ]); ... form input fields here ... ActiveForm::end(); ``` Please refer to the [Widgets](structure-widgets.md) chapter for more details. Themes ------ Themes work completely different in 2.0. They are now based on a path mapping mechanism which maps a source view file path to a themed view file path. For example, if the path map for a theme is `['/web/views' => '/web/themes/basic']`, then the themed version for a view file `/web/views/site/index.php` will be `/web/themes/basic/site/index.php`. For this reason, themes can now be applied to any view file, even if a view rendered outside of the context of a controller or a widget. Also, there is no more `CThemeManager`. Instead, `theme` is a configurable property of the `view` application component. Please refer to the [Theming](tutorial-theming.md) chapter for more details. Console Applications -------------------- Console applications are now organized as controllers, like Web applications. Console controllers should extend from [[yii\console\Controller]] which is similar to `CConsoleCommand` in 1.1. To run a console command, use `yii `, where `` stands for a controller route (e.g. `sitemap/index`). Additional anonymous arguments are passed as the parameters to the corresponding controller action method, while named arguments are parsed according to the declarations in [[yii\console\Controller::options()]]. Yii 2.0 supports automatic generation of command help information from comment blocks. Please refer to the [Console Commands](tutorial-console.md) chapter for more details. I18N ---- Yii 2.0 removes date formatter and number formatter in favor of the PECL intl PHP module. Message translation is now performed via the `i18n` application component. The component manages a set of message sources, which allows you to use different message sources based on message categories. Please refer to the [Internationalization](tutorial-i18n.md) chapter for more details. Action Filters -------------- Action filters are implemented via behaviors now. You should extend from [[yii\base\ActionFilter]] to define a new filter. To use a filter, you should attach the filter class to the controller as a behavior. For example, to use the [[yii\filters\AccessControl]] filter, you should have the following code in a controller: ```php public function behaviors() { return [ 'access' => [ 'class' => 'yii\filters\AccessControl', 'rules' => [ ['allow' => true, 'actions' => ['admin'], 'roles' => ['@']], ], ], ]; } ``` Please refer to the [Filtering](runtime-filtering.md) chapter for more details. Assets ------ Yii 2.0 introduces a new concept called *asset bundle* which replaces the script package concept in 1.1. An asset bundle is a collection of asset files (e.g. JavaScript files, CSS files, image files, etc.) under a directory. Each asset bundle is represented as a class extending [[yii\web\AssetBundle]]. By registering an asset bundle via [[yii\web\AssetBundle::register()]], you will be able to make the assets in that bundle accessible via Web, and the page registering the bundle will automatically contain the references to the JavaScript and CSS files specified in that bundle. Please refer to the [Managing Assets](output-assets.md) chapter for more details. Helpers ------- Yii 2.0 introduces many commonly used static helper classes, such as * [[yii\helpers\Html]] * [[yii\helpers\ArrayHelper]] * [[yii\helpers\StringHelper]] * [[yii\helpers\FileHelper]] * [[yii\helpers\Json]] * [[yii\helpers\Security]] Forms ----- Yii 2.0 introduces the *field* concept for building a form using [[yii\widgets\ActiveForm]]. A field is a container consisting of a label, an input, an error message, and/or a hint text. It is represented as an [[yii\widgets\ActiveField|ActiveField]] object. Using fields, you can build a form more cleanly than before: ```php field($model, 'username') ?> field($model, 'password')->passwordInput() ?>
``` Query Builder ------------- In 1.1, query building is scattered among several classes, including `CDbCommand`, `CDbCriteria`, and `CDbCommandBuilder`. Yii 2.0 represents a DB query in terms of a [[yii\db\Query|Query]] object which can be turned into a SQL statement with the help of [[yii\db\QueryBuilder|QueryBuilder]] behind the scene. For example: ```php $query = new \yii\db\Query(); $query->select('id, name') ->from('user') ->limit(10); $command = $query->createCommand(); $sql = $command->sql; $rows = $command->queryAll(); ``` Best of all, such query building methods can also be used when working with [Active Record](db-active-record.md). Please refer to the [Query Builder](db-query-builder.md) chapter for more details. Active Record ------------- Yii 2.0 introduces a lot of changes to [Active Record](db-active-record.md). Two most obvious ones are: query building and relational query handling. The `CDbCriteria` class in 1.1 is replaced by [[yii\db\ActiveQuery]] which extends from [[yii\db\Query]] and thus inherits all query building methods. You call [[yii\db\ActiveRecord::find()]] to start building a query. For example, ```php // to retrieve all *active* customers and order them by their ID: $customers = Customer::find() ->where(['status' => $active]) ->orderBy('id') ->all(); ``` To declare a relation, you simply define a getter method that returns an [[yii\db\ActiveQuery|ActiveQuery]] object. The property name defined by the getter represents the relation name. For example, the following code declares an `orders` relation (in 1.1, you would have to declare relations in a central place `relations()`): ```php class Customer extends \yii\db\ActiveRecord { public function getOrders() { return $this->hasMany('Order', ['customer_id' => 'id']); } } ``` You can use `$customer->orders` to access the customer's orders. You can also use the following code to perform on-the-fly relational query with customized query conditions: ```php $orders = $customer->getOrders()->andWhere('status=1')->all(); ``` When eager loading a relation, Yii 2.0 does it differently from 1.1. In particular, in 1.1 a JOIN query would be created to bring both the primary and the relational records; in 2.0, two SQL statements are executed without using JOIN: the first statement brings back the primary records and the second brings back the relational records by filtering with the primary keys of the primary records. Instead of returning [[yii\db\ActiveRecord|ActiveRecord]] objects, you may chain the [[yii\db\ActiveQuery::asArray()|asArray()]] method when building a query to return large number of records. This will cause the query result to be returned as arrays, which can significantly reduce the needed CPU time and memory if large number of records . For example, ```php $customers = Customer::find()->asArray()->all(); ``` There are many other changes and enhancements to Active Record. Please refer to the [Active Record](db-active-record.md) chapter for more details. User and IdentityInterface -------------------------- The `CWebUser` class in 1.1 is now replaced by [[yii\web\User]], and there is no more `CUserIdentity` class. Instead, you should implement the [[yii\web\IdentityInterface]] which is much more straightforward to implement. The advanced application template provides such an example. URL Management -------------- URL management is similar to 1.1. A major enhancement is that it now supports optional parameters. For example, if you have rule declared as follows, then it will match both `post/popular` and `post/1/popular`. In 1.1, you would have to use two rules to achieve the same goal. ```php [ 'pattern' => 'post//', 'route' => 'post/index', 'defaults' => ['page' => 1], ] ``` More details in the [Url manager docs](url.md). Using Yii 1.1 and 2.x together ------------------------------ If you have legacy Yii 1.1 code and you want to use it together with Yii 2.0, please refer to the [Using Yii 1.1 and 2.0 Together](extend-using-v1-v2.md) chapter.