upgrade-from-v1.md 19.9 KB
Newer Older
Qiang Xue committed
1 2 3 4 5 6 7 8
Upgrading from Yii 1.1
======================

In this chapter, we list the major changes introduced in Yii 2.0 since version 1.1.
We hope this list will make it easier for you to upgrade from Yii 1.1 and quickly
master Yii 2.0 based on your existing Yii knowledge.


Qiang Xue committed
9 10 11 12 13 14 15
Namespace
---------

The most obvious change in Yii 2.0 is the use of namespaces. Almost every core class
is namespaced, e.g., `yii\web\Request`. The "C" prefix is no longer used in class names.
The naming of the namespaces follows the directory structure. For example, `yii\web\Request`
indicates the corresponding class file is `web/Request.php` under the Yii framework folder.
ploaiza committed
16
You can use any core class without explicitly including that class file, thanks to the Yii
Qiang Xue committed
17 18 19
class loader.


Qiang Xue committed
20 21 22
Component and Object
--------------------

23 24 25
Yii 2.0 breaks the `CComponent` class in 1.1 into two classes: [[yii\base\Object]] and [[yii\base\Component]].
The [[yii\base\Object|Object]] class is a lightweight base class that allows defining class properties
via getters and setters. The [[yii\base\Component|Component]] class extends from [[yii\base\Object|Object]] and supports
Qiang Xue committed
26 27 28
the event feature and the behavior feature.

If your class does not need the event or behavior feature, you should consider using
br0sk committed
29
`Object` as the base class. This is usually the case for classes that represent basic
Qiang Xue committed
30 31
data structures.

32 33
More details about Object and component can be found in the [Basic concepts section](basics.md).

Qiang Xue committed
34 35 36 37

Object Configuration
--------------------

38 39
The [[yii\base\Object|Object]] class introduces a uniform way of configuring objects. Any descendant class
of [[yii\base\Object|Object]] should declare its constructor (if needed) in the following way so that
40
it can be properly configured:
Qiang Xue committed
41

42
```php
Qiang Xue committed
43
class MyClass extends \yii\base\Object
Qiang Xue committed
44
{
Alexander Makarov committed
45
    public function __construct($param1, $param2, $config = [])
Qiang Xue committed
46
    {
47 48
        // ... initialization before configuration is applied

Qiang Xue committed
49 50 51 52 53 54
        parent::__construct($config);
    }

    public function init()
    {
        parent::init();
55 56

        // ... initialization after configuration is applied
Qiang Xue committed
57 58
    }
}
59
```
Alexander Makarov committed
60

61 62
In the above, the last parameter of the constructor must take a configuration array
which contains name-value pairs for initializing the properties at the end of the constructor.
63
You can override the [[yii\base\Object::init()|init()]] method to do initialization work that should be done after
64
the configuration is applied.
Qiang Xue committed
65

66 67
By following this convention, you will be able to create and configure a new object
using a configuration array like the following:
Qiang Xue committed
68

69
```php
Alexander Makarov committed
70
$object = Yii::createObject([
Qiang Xue committed
71 72 73
    'class' => 'MyClass',
    'property1' => 'abc',
    'property2' => 'cde',
Qiang Xue committed
74
], [$param1, $param2]);
75
```
Alexander Makarov committed
76

77 78
More on configuration can be found in the [Basic concepts section](basics.md).

Qiang Xue committed
79 80 81 82 83

Events
------

There is no longer the need to define an `on`-method in order to define an event in Yii 2.0.
84 85
Instead, you can use whatever event names. To attach a handler to an event, you should now
use the `on` method:
Qiang Xue committed
86

87
```php
Qiang Xue committed
88 89 90
$component->on($eventName, $handler);
// To detach the handler, use:
// $component->off($eventName, $handler);
91
```
Alexander Makarov committed
92

Qiang Xue committed
93 94 95 96

When you attach a handler, you can now associate it with some parameters which can be later
accessed via the event parameter by the handler:

97
```php
Qiang Xue committed
98
$component->on($eventName, $handler, $params);
99
```
Alexander Makarov committed
100

Qiang Xue committed
101 102 103 104

Because of this change, you can now use "global" events. Simply trigger and attach handlers to
an event of the application instance:

105
```php
Qiang Xue committed
106 107 108 109
Yii::$app->on($eventName, $handler);
....
// this will trigger the event and cause $handler to be invoked.
Yii::$app->trigger($eventName);
110
```
Qiang Xue committed
111

112 113 114
If you need to handle all instances of a class instead of the object you can attach a handler like the following:

```php
Qiang Xue committed
115
Event::on(ActiveRecord::className(), ActiveRecord::EVENT_AFTER_INSERT, function ($event) {
116
    Yii::trace(get_class($event->sender) . ' is inserted.');
117 118 119 120
});
```

The code above defines a handler that will be triggered for every Active Record object's `EVENT_AFTER_INSERT` event.
Qiang Xue committed
121

122 123 124
See [Event handling section](events.md) for more details.


125 126 127 128 129 130 131 132 133 134
Path Alias
----------

Yii 2.0 expands the usage of path aliases to both file/directory paths and URLs. An alias
must start with a `@` character so that it can be differentiated from 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, `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
ploaiza committed
135
alias be defined for each root namespace so that you can use Yii the class autoloader without
136 137
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
138
such as Zend Framework, you may define a path alias `@Zend` which refers to its installation
ploaiza committed
139
directory and Yii will be able to autoload any class in this library.
140

141 142
More on path aliases can be found in the [Basic concepts section](basics.md).

143

Qiang Xue committed
144 145 146
View
----

147
Yii 2.0 introduces a [[yii\web\View|View]] class to represent the view part of the MVC pattern.
Qiang Xue committed
148 149 150 151 152 153
It can be configured globally through the "view" application component. It is also
accessible in any view file via `$this`. This is one of the biggest changes compared to 1.1:
**`$this` in a view file no longer refers to the controller or widget object.**
It refers to the view object that is used to render the view file. To access the controller
or the widget object, you have to use `$this->context` now.

154 155 156 157 158 159 160
For partial views, the [[yii\web\View|View]] class now includes a `render()` function. This creates another significant change in the usage of views compared to 1.1:
**`$this->render(...)` does not output the processed content; you must echo it yourself.**

```php
echo $this->render('_item', ['item' => $item]);
```

Qiang Xue committed
161 162 163 164
Because you can access the view object through the "view" application component,
you can now render a view file like the following anywhere in your code, not necessarily
in controllers or widgets:

165
```php
Qiang Xue committed
166 167
$content = Yii::$app->view->renderFile($viewFile, $params);
// You can also explicitly create a new View instance to do the rendering
168
// $view = new View();
Qiang Xue committed
169
// $view->renderFile($viewFile, $params);
170
```
Alexander Makarov committed
171

172
Also, there is no more `CClientScript` in Yii 2.0. The [[yii\web\View|View]] class has taken over its role
Qiang Xue committed
173 174
with significant improvements. For more details, please see the "assets" subsection.

175 176
While Yii 2.0 continues to use PHP as its main template language, it comes with two official extensions
adding support for two popular template engines: Smarty and Twig. The Prado template engine is
Qiang Xue committed
177
no longer supported. To use these template engines, you just need to use `tpl` as the file
178
extension for your Smarty views, or `twig` for Twig views. You may also configure the
179
[[yii\web\View::$renderers|View::$renderers]] property to use other template engines. See [Using template engines](template.md) section
180
of the guide for more details.
181

182 183
See [View section](view.md) for more details.

Qiang Xue committed
184 185 186 187

Models
------

188
A model is now associated with a form name returned by its [[yii\base\Model::formName()|formName()]] method. This is
189 190 191
mainly used when using HTML forms to collect user inputs for a model. Previously in 1.1,
this is usually hardcoded as the class name of the model.

192 193
New methods called [[yii\base\Model::load()|load()] and [[yii\base\Model::loadMultiple()|Model::loadMultiple()]] are
introduced to simplify the data population from user inputs to a model. For example,
194 195

```php
196
$model = new Post();
197 198 199 200 201 202 203 204
if ($model->load($_POST)) {...}
// which is equivalent to:
if (isset($_POST['Post'])) {
    $model->attributes = $_POST['Post'];
}

$model->save();

Alexander Makarov committed
205
$postTags = [];
206
$tagsCount = count($_POST['PostTag']);
207
while ($tagsCount-- > 0) {
Alexander Makarov committed
208
    $postTags[] = new PostTag(['post_id' => $model->id]);
209 210 211
}
Model::loadMultiple($postTags, $_POST);
```
212

213 214
Yii 2.0 introduces a new method called [[yii\base\Model::scenarios()|scenarios()]] to declare which attributes require
validation under which scenario. Child classes should overwrite [[yii\base\Model::scenarios()|scenarios()]] to return
215
a list of scenarios and the corresponding attributes that need to be validated when
216
[[yii\base\Model::validate()|validate()]] is called. For example,
217

218
```php
219 220
public function scenarios()
{
Alexander Makarov committed
221 222 223 224
    return [
        'backend' => ['email', 'role'],
        'frontend' => ['email', '!name'],
    ];
225
}
226
```
Alexander Makarov committed
227

228 229

This method also determines which attributes are safe and which are not. In particular,
230
given a scenario, if an attribute appears in the corresponding attribute list in [[yii\base\Model::scenarios()|scenarios()]]
231 232
and the name is not prefixed with `!`, it is considered *safe*.

233
Because of the above change, Yii 2.0 no longer has "unsafe" validator.
234

235
If your model only has one scenario (very common), you do not have to overwrite [[yii\base\Model::scenarios()|scenarios()]],
236 237
and everything will still work like the 1.1 way.

238 239
To learn more about Yii 2.0 models refer to [Models](model.md) section of the guide.

240

Qiang Xue committed
241 242 243
Controllers
-----------

244 245 246
The [[yii\base\Controller::render()|render()]] and [[yii\base\Controller::renderPartial()|renderPartial()]] methods
now return the rendering results instead of directly sending them out.
You have to `echo` them explicitly, e.g., `echo $this->render(...);`.
247

248
To learn more about Yii 2.0 controllers refer to [Controller](controller.md) section of the guide.
249

250

251 252 253
Widgets
-------

254 255 256 257 258
Using a widget is more straightforward in 2.0. You mainly use the
[[yii\base\Widget::begin()|begin()]],
[[yii\base\Widget::end()|end()]] and
[[yii\base\Widget::widget()|widget()]]
methods of the [[yii\base\Widget|Widget]] class. For example,
259 260 261

```php
// Note that you have to "echo" the result to display it
Alexander Makarov committed
262
echo \yii\widgets\Menu::widget(['items' => $items]);
263

264
// Passing an array to initialize the object properties
Alexander Makarov committed
265
$form = \yii\widgets\ActiveForm::begin([
266 267
    'options' => ['class' => 'form-horizontal'],
    'fieldConfig' => ['inputOptions' => ['class' => 'input-xlarge']],
Alexander Makarov committed
268
]);
269 270 271 272 273 274 275
... form inputs here ...
\yii\widgets\ActiveForm::end();
```

Previously in 1.1, you would have to enter the widget class names as strings via the `beginWidget()`,
`endWidget()` and `widget()` methods of `CBaseController`. The approach above gets better IDE support.

276 277
For more on widgets see the [View section](view.md#widgets).

278

Qiang Xue committed
279 280 281
Themes
------

ploaiza committed
282
Themes work completely different in 2.0. They are now based on a path map to "translate" a source
283
view into a themed view. For example, if the path map for a theme is
Alexander Makarov committed
284
`['/web/views' => '/web/themes/basic']`, then the themed version for a view file
285
`/web/views/site/index.php` will be `/web/themes/basic/site/index.php`.
286 287 288 289 290 291 292

For this reason, theme can now be applied to any view file, even if a view rendered outside
of the context of a controller or a widget.

There is no more `CThemeManager`. Instead, `theme` is a configurable property of the "view"
application component.

293 294
For more on themes see the [Theming section](theming.md).

295

Qiang Xue committed
296 297 298
Console Applications
--------------------

ploaiza committed
299
Console applications are now composed by controllers, like Web applications. In fact,
300 301 302
console controllers and Web controllers share the same base controller class.

Each console controller is like `CConsoleCommand` in 1.1. It consists of one or several
303
actions. You use the `yii <route>` command to execute a console command, where `<route>`
304 305
stands for a controller route (e.g. `sitemap/index`). Additional anonymous arguments
are passed as the parameters to the corresponding controller action method, and named arguments
306
are treated as options declared in `options($id)`.
307 308 309

Yii 2.0 supports automatic generation of command help information from comment blocks.

310 311
For more on console applications see the [Console section](console.md).

312

Qiang Xue committed
313 314 315
I18N
----

316
Yii 2.0 removes date formatter and number formatter in favor of the PECL intl PHP module.
Qiang Xue committed
317

318 319
Message translation is still supported, but managed via the "i18n" application component.
The component manages a set of message sources, which allows you to use different message
320
sources based on message categories. For more information, see the class documentation for [I18N](i18n.md).
321 322 323 324 325


Action Filters
--------------

326
Action filters are implemented via behaviors now. You should extend from [[yii\base\ActionFilter]] to
327
define a new filter. To use a filter, you should attach the filter class to the controller
328
as a behavior. For example, to use the [[yii\filters\AccessControl]] filter, you should have the following
329 330
code in a controller:

331
```php
332 333
public function behaviors()
{
Alexander Makarov committed
334 335
    return [
        'access' => [
336
            'class' => 'yii\filters\AccessControl',
Alexander Makarov committed
337 338
            'rules' => [
                ['allow' => true, 'actions' => ['admin'], 'roles' => ['@']],
339 340 341
            ],
        ],
    ];
342
}
343
```
Alexander Makarov committed
344

345
For more on action filters see the [Controller section](controller.md#action-filters).
Qiang Xue committed
346 347 348 349 350


Assets
------

ploaiza committed
351
Yii 2.0 introduces a new concept called *asset bundle*. It is similar to script
352 353 354
packages (managed by `CClientScript`) in 1.1, but with better support.

An asset bundle is a collection of asset files (e.g. JavaScript files, CSS files, image files, etc.)
355 356
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
357 358
the assets in that bundle accessible via Web, and the current page will automatically
contain the references to the JavaScript and CSS files specified in that bundle.
359

360
To learn more about assets see the [asset manager documentation](assets.md).
361

Qiang Xue committed
362 363 364
Static Helpers
--------------

365 366 367 368 369 370 371 372
Yii 2.0 introduces many commonly used static helper classes, such as
[[yii\helpers\Html|Html]],
[[yii\helpers\ArrayHelper|ArrayHelper]],
[[yii\helpers\StringHelper|StringHelper]].
[[yii\helpers\FileHelper|FileHelper]],
[[yii\helpers\Json|Json]],
[[yii\helpers\Security|Security]],
These classes are designed to be easily extended. Note that static classes
ploaiza committed
373
are usually hard to extend because of the fixed class name references. But Yii 2.0
374
introduces the class map (via [[Yii::$classMap]]) to overcome this difficulty.
375 376


377 378
ActiveForm
----------
Qiang Xue committed
379

380
Yii 2.0 introduces the *field* concept for building a form using [[yii\widgets\ActiveForm]]. A field
Qiang Xue committed
381
is a container consisting of a label, an input, an error message, and/or a hint text.
382 383
It is represented as an [[yii\widgets\ActiveField|ActiveField]] object.
Using fields, you can build a form more cleanly than before:
384

385
```php
386
<?php $form = yii\widgets\ActiveForm::begin(); ?>
387 388 389 390 391
    <?= $form->field($model, 'username') ?>
    <?= $form->field($model, 'password')->passwordInput() ?>
    <div class="form-group">
        <?= Html::submitButton('Login') ?>
    </div>
392
<?php yii\widgets\ActiveForm::end(); ?>
393
```
Alexander Makarov committed
394

395

Qiang Xue committed
396 397 398
Query Builder
-------------

399
In 1.1, query building is scattered among several classes, including `CDbCommand`,
400 401
`CDbCriteria`, and `CDbCommandBuilder`. Yii 2.0 uses [[yii\db\Query|Query]] to represent a DB query
and [[yii\db\QueryBuilder|QueryBuilder]] to generate SQL statements from query objects. For example:
402

403
```php
404
$query = new \yii\db\Query();
405
$query->select('id, name')
406
      ->from('user')
407 408 409 410 411
      ->limit(10);

$command = $query->createCommand();
$sql = $command->sql;
$rows = $command->queryAll();
412
```
Alexander Makarov committed
413

414
Best of all, such query building methods can be used together with [[yii\db\ActiveRecord|ActiveRecord]],
415 416
as explained in the next sub-section.

Qiang Xue committed
417 418 419 420

ActiveRecord
------------

421
[[yii\db\ActiveRecord|ActiveRecord]] has undergone significant changes in Yii 2.0. The most important one
ploaiza committed
422
is the relational ActiveRecord query. In 1.1, you have to declare the relations
423
in the `relations()` method. In 2.0, this is done via getter methods that return
424
an [[yii\db\ActiveQuery|ActiveQuery]] object. For example, the following method declares an "orders" relation:
425

426
```php
427 428
class Customer extends \yii\db\ActiveRecord
{
429 430 431 432
    public function getOrders()
    {
        return $this->hasMany('Order', ['customer_id' => 'id']);
    }
433
}
434
```
Alexander Makarov committed
435

436 437 438 439 440 441 442 443 444 445 446 447
You can use `$customer->orders` to access the customer's orders. You can also
use `$customer->getOrders()->andWhere('status=1')->all()` to perform on-the-fly
relational query with customized query conditions.

When loading relational records in an eager way, Yii 2.0 does it differently from 1.1.
In particular, in 1.1 a JOIN query would be used to bring both the primary and the relational
records; while 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.


Yii 2.0 no longer uses the `model()` method when performing queries. Instead, you
448
use the [[yii\db\ActiveRecord::find()|find()]] method:
449

450
```php
451 452
// to retrieve all *active* customers and order them by their ID:
$customers = Customer::find()
453 454 455
    ->where(['status' => $active])
    ->orderBy('id')
    ->all();
456
// return the customer whose PK is 1
Alexander Makarov committed
457
$customer = Customer::findOne(1);
458
```
Alexander Makarov committed
459

460

461 462
The [[yii\db\ActiveRecord::find()|find()]] method returns an instance of [[yii\db\ActiveQuery|ActiveQuery]]
which is a subclass of [[yii\db\Query]]. Therefore, you can use all query methods of [[yii\db\Query]].
463

464
Instead of returning ActiveRecord objects, you may call [[yii\db\ActiveQuery::asArray()|ActiveQuery::asArray()]] to
465
return results in terms of arrays. This is more efficient and is especially useful
ploaiza committed
466
when you need to return a large number of records:
467

468
```php
469
$customers = Customer::find()->asArray()->all();
470
```
471

472
By default, ActiveRecord now only saves dirty attributes. In 1.1, all attributes
ploaiza committed
473
are saved to database when you call `save()`, regardless of having changed or not,
474 475
unless you explicitly list the attributes to save.

476
Scopes are now defined in a custom [[yii\db\ActiveQuery|ActiveQuery]] class instead of model directly.
477

478 479
See [active record docs](active-record.md) for more details.

480

481 482 483 484
Auto-quoting Table and Column Names
------------------------------------

Yii 2.0 supports automatic quoting of database table and column names. A name enclosed
485 486
within double curly brackets i.e. `{{tablename}}` is treated as a table name, and a name enclosed within
double square brackets i.e. `[[fieldname]]` is treated as a column name. They will be quoted according to
ploaiza committed
487
the database driver being used:
488

489
```php
490 491
$command = $connection->createCommand('SELECT [[id]] FROM {{posts}}');
echo $command->sql;  // MySQL: SELECT `id` FROM `posts`
492
```
Alexander Makarov committed
493

494 495 496 497
This feature is especially useful if you are developing an application that supports
different DBMS.


498 499
User and IdentityInterface
--------------------------
Qiang Xue committed
500

501 502 503
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.
504 505


Qiang Xue committed
506 507 508
URL Management
--------------

509 510 511 512 513
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.

514
```php
Alexander Makarov committed
515
[
516 517 518
    'pattern' => 'post/<page:\d+>/<tag>',
    'route' => 'post/index',
    'defaults' => ['page' => 1],
Alexander Makarov committed
519
]
520
```
Alexander Makarov committed
521

522
More details in the [Url manager docs](url.md).
523

Qiang Xue committed
524
Response
525 526
--------

527 528
TBD

529 530 531
Extensions
----------

532 533
Yii 1.1 extensions are not compatible with 2.0 so you have to port or rewrite these. In order to get more info about
extensions in 2.0 [referer to corresponding guide section](extensions.md).
534

535 536 537
Integration with Composer
-------------------------

538 539 540
Yii is fully inegrated with Composer, a well known package manager for PHP, that resolves dependencies, helps keeping
your code up to date by allowing updating it with a single console command and manages autoloading for third party
libraries no matter which autoloading these libraries are using.
541

surek committed
542
In order to learn more refer to [composer](composer.md) and [installation](installation.md) sections of the guide.
543 544 545 546 547

Using Yii 1.1 and 2.x together
------------------------------

Check the guide on [using Yii together with 3rd-Party Systems](using-3rd-party-libraries.md) on this topic.