intro-upgrade-from-v1.md 19.4 KB
Newer Older
Qiang Xue committed
1 2
Upgrading from Version 1.1
==========================
Qiang Xue committed
3

Qiang Xue committed
4 5 6 7
Because Yii 2.0 is a complete rewrite of the framework, upgrading from version 1.1 is not trivial.
We recommend you read through this guide before performing the upgrade. In this chapter, we will
summarize the major differences between 1.1 and 2.0. We hope this 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
8 9


Qiang Xue committed
10 11 12 13 14 15 16
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
17
You can use any core class without explicitly including that class file, thanks to the Yii
Qiang Xue committed
18 19 20
class loader.


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

24
Yii 2.0 breaks the `CComponent` class in 1.1 into two classes: [[yii\base\Object]] and [[yii\base\Component]].
Qiang Xue committed
25
The [[yii\base\Object|Object]] class is a lightweight base class that allows defining [object properties](basic-properties.md)
26
via getters and setters. The [[yii\base\Component|Component]] class extends from [[yii\base\Object|Object]] and supports
Qiang Xue committed
27
[events](basic-events.md) and [behaviors](basic-behaviors.md).
Qiang Xue committed
28 29

If your class does not need the event or behavior feature, you should consider using
Qiang Xue committed
30
[[yii\base\Object|Object]] as the base class. This is usually the case for classes that represent basic
Qiang Xue committed
31 32 33 34 35 36
data structures.


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

37 38
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
39
it can be properly configured:
Qiang Xue committed
40

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

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

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

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

60 61
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.
62
You can override the [[yii\base\Object::init()|init()]] method to do initialization work that should be done after
63
the configuration is applied.
Qiang Xue committed
64

65 66
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
67

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

Qiang Xue committed
76
More details about configurations can be found in the [Object Configurations](basic-configs.md) chapter.
77

Qiang Xue committed
78 79 80 81 82

Events
------

There is no longer the need to define an `on`-method in order to define an event in Yii 2.0.
Qiang Xue committed
83 84
Instead, you can use whatever event names. You can trigger an event by calling
the [[yii\base\Component::trigger()|trigger()]] method:
Qiang Xue committed
85

86
```php
Qiang Xue committed
87 88
$event = new \yii\base\Event;
$component->trigger($eventName, $event);
89
```
Qiang Xue committed
90

Qiang Xue committed
91
And to attach a handler to an event, you can use the [[yii\base\Component::on()|on()]] method:
92 93

```php
Qiang Xue committed
94 95 96
$component->on($eventName, $handler);
// To detach the handler, use:
// $component->off($eventName, $handler);
97 98
```

Qiang Xue committed
99
There are many enhancements to the event features. For more details, please refer to the [Events](basic-events.md) chapter.
Qiang Xue committed
100

101

Qiang Xue committed
102 103
Path Aliases
------------
104

Qiang Xue committed
105 106
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.
107
For example, the alias `@yii` refers to the Yii installation directory. Path aliases are
Qiang Xue committed
108
supported in most places in the Yii core code. For example, [[yii\caching\FileCache::cachePath]] can take
109 110 111
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
112
alias be defined for each root namespace so that you can use Yii the class autoloader without
113 114
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
115
such as Zend Framework, you may define a path alias `@Zend` which refers to its installation
ploaiza committed
116
directory and Yii will be able to autoload any class in this library.
117

Qiang Xue committed
118
More on path aliases can be found in the [Path Aliases](basic-aliases.md) chapter.
119

120

Qiang Xue committed
121 122
Views
-----
Qiang Xue committed
123

124
Yii 2.0 introduces a [[yii\web\View|View]] class to represent the view part of the MVC pattern.
Qiang Xue committed
125 126 127 128 129 130
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.

131 132 133 134 135 136 137
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
138 139 140 141
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:

142
```php
Qiang Xue committed
143 144
$content = Yii::$app->view->renderFile($viewFile, $params);
// You can also explicitly create a new View instance to do the rendering
145
// $view = new View();
Qiang Xue committed
146
// $view->renderFile($viewFile, $params);
147
```
Alexander Makarov committed
148

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

152 153
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
154
no longer supported. To use these template engines, you just need to use `tpl` as the file
155
extension for your Smarty views, or `twig` for Twig views. You may also configure the
156
[[yii\web\View::$renderers|View::$renderers]] property to use other template engines. See [Using template engines](template.md) section
157
of the guide for more details.
158

159 160
See [View section](view.md) for more details.

Qiang Xue committed
161 162 163 164

Models
------

165
A model is now associated with a form name returned by its [[yii\base\Model::formName()|formName()]] method. This is
166 167 168
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.

169
New methods called [[yii\base\Model::load()|load()] and [[yii\base\Model::loadMultiple()|Model::loadMultiple()]] are
Qiang Xue committed
170
introduced to simplify the data population from user inputs to a model. For example, to populate a single model,
171 172

```php
173
$model = new Post();
Qiang Xue committed
174 175 176 177
if ($model->load($_POST)) {
    // ...
}

178
// which is equivalent to:
Qiang Xue committed
179

180 181 182
if (isset($_POST['Post'])) {
    $model->attributes = $_POST['Post'];
}
Qiang Xue committed
183
```
184

Qiang Xue committed
185
and to populate multiple models (tabular inputs):
186

Qiang Xue committed
187
```php
Alexander Makarov committed
188
$postTags = [];
189
$tagsCount = count($_POST['PostTag']);
190
while ($tagsCount-- > 0) {
Alexander Makarov committed
191
    $postTags[] = new PostTag(['post_id' => $model->id]);
192
}
Qiang Xue committed
193
\yii\base\Model::loadMultiple($postTags, $_POST);
194
```
195

196 197
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
198
a list of scenarios and the corresponding attributes that need to be validated when
199
[[yii\base\Model::validate()|validate()]] is called. For example,
200

201
```php
202 203
public function scenarios()
{
Alexander Makarov committed
204 205 206 207
    return [
        'backend' => ['email', 'role'],
        'frontend' => ['email', '!name'],
    ];
208
}
209
```
Alexander Makarov committed
210

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

Qiang Xue committed
215
Because of the above change, Yii 2.0 no longer has the "unsafe" validator.
216

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

Qiang Xue committed
220
To learn more about Yii 2.0 models refer to the [Models](basic-models.md) chapter.
221

222

Qiang Xue committed
223 224 225
Controllers
-----------

226 227 228
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(...);`.
229

Qiang Xue committed
230
Please refer to the [Controllers](structure-controllers.md) chapter for more details.
231

232

233 234 235
Widgets
-------

236
Using a widget is more straightforward in 2.0. You mainly use the
Qiang Xue committed
237
[[yii\base\Widget::begin()|begin()]], [[yii\base\Widget::end()|end()]] and [[yii\base\Widget::widget()|widget()]]
238
methods of the [[yii\base\Widget|Widget]] class. For example,
239 240

```php
Qiang Xue committed
241 242 243
use yii\widgets\Menu;
use yii\widgets\ActiveForm;

244
// Note that you have to "echo" the result to display it
Qiang Xue committed
245
echo Menu::widget(['items' => $items]);
246

247
// Passing an array to initialize the object properties
Qiang Xue committed
248
$form = ActiveForm::begin([
249 250
    'options' => ['class' => 'form-horizontal'],
    'fieldConfig' => ['inputOptions' => ['class' => 'input-xlarge']],
Alexander Makarov committed
251
]);
Qiang Xue committed
252 253
... form input fields here ...
ActiveForm::end();
254 255
```

Qiang Xue committed
256
Please refer to the [Widgets](structure-widgets.md) chapter for more details.
257

258

Qiang Xue committed
259 260 261
Themes
------

ploaiza committed
262
Themes work completely different in 2.0. They are now based on a path map to "translate" a source
263
view into a themed view. For example, if the path map for a theme is
Alexander Makarov committed
264
`['/web/views' => '/web/themes/basic']`, then the themed version for a view file
265
`/web/views/site/index.php` will be `/web/themes/basic/site/index.php`.
266 267 268 269 270 271 272

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.

273 274
For more on themes see the [Theming section](theming.md).

275

Qiang Xue committed
276 277 278
Console Applications
--------------------

ploaiza committed
279
Console applications are now composed by controllers, like Web applications. In fact,
280 281 282
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
283
actions. You use the `yii <route>` command to execute a console command, where `<route>`
284 285
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
286
are treated as options declared in `options($id)`.
287 288 289

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

290 291
For more on console applications see the [Console section](console.md).

292

Qiang Xue committed
293 294 295
I18N
----

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

298 299
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
300
sources based on message categories. For more information, see the class documentation for [I18N](i18n.md).
301 302 303 304 305


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

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

311
```php
312 313
public function behaviors()
{
Alexander Makarov committed
314 315
    return [
        'access' => [
316
            'class' => 'yii\filters\AccessControl',
Alexander Makarov committed
317 318
            'rules' => [
                ['allow' => true, 'actions' => ['admin'], 'roles' => ['@']],
319 320 321
            ],
        ],
    ];
322
}
323
```
Alexander Makarov committed
324

325
For more on action filters see the [Controller section](controller.md#action-filters).
Qiang Xue committed
326 327 328 329 330


Assets
------

ploaiza committed
331
Yii 2.0 introduces a new concept called *asset bundle*. It is similar to script
332 333 334
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.)
335 336
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
337 338
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.
339

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

Qiang Xue committed
342 343 344
Static Helpers
--------------

345 346 347 348 349 350 351 352
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
353
are usually hard to extend because of the fixed class name references. But Yii 2.0
354
introduces the class map (via [[Yii::$classMap]]) to overcome this difficulty.
355 356


357 358
ActiveForm
----------
Qiang Xue committed
359

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

365
```php
366
<?php $form = yii\widgets\ActiveForm::begin(); ?>
367 368 369 370 371
    <?= $form->field($model, 'username') ?>
    <?= $form->field($model, 'password')->passwordInput() ?>
    <div class="form-group">
        <?= Html::submitButton('Login') ?>
    </div>
372
<?php yii\widgets\ActiveForm::end(); ?>
373
```
Alexander Makarov committed
374

375

Qiang Xue committed
376 377 378
Query Builder
-------------

379
In 1.1, query building is scattered among several classes, including `CDbCommand`,
380 381
`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:
382

383
```php
384
$query = new \yii\db\Query();
385
$query->select('id, name')
386
      ->from('user')
387 388 389 390 391
      ->limit(10);

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

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

Qiang Xue committed
397 398 399 400

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

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

406
```php
407 408
class Customer extends \yii\db\ActiveRecord
{
409 410 411 412
    public function getOrders()
    {
        return $this->hasMany('Order', ['customer_id' => 'id']);
    }
413
}
414
```
Alexander Makarov committed
415

416 417 418 419 420 421 422 423 424 425 426 427
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
428
use the [[yii\db\ActiveRecord::find()|find()]] method:
429

430
```php
431 432
// to retrieve all *active* customers and order them by their ID:
$customers = Customer::find()
433 434 435
    ->where(['status' => $active])
    ->orderBy('id')
    ->all();
436
// return the customer whose PK is 1
Alexander Makarov committed
437
$customer = Customer::findOne(1);
438
```
Alexander Makarov committed
439

440

441 442
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]].
443

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

448
```php
449
$customers = Customer::find()->asArray()->all();
450
```
451

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

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

458 459
See [active record docs](active-record.md) for more details.

460

461 462 463 464
Auto-quoting Table and Column Names
------------------------------------

Yii 2.0 supports automatic quoting of database table and column names. A name enclosed
465 466
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
467
the database driver being used:
468

469
```php
470 471
$command = $connection->createCommand('SELECT [[id]] FROM {{posts}}');
echo $command->sql;  // MySQL: SELECT `id` FROM `posts`
472
```
Alexander Makarov committed
473

474 475 476 477
This feature is especially useful if you are developing an application that supports
different DBMS.


478 479
User and IdentityInterface
--------------------------
Qiang Xue committed
480

481 482 483
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.
484 485


Qiang Xue committed
486 487 488
URL Management
--------------

489 490 491 492 493
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.

494
```php
Alexander Makarov committed
495
[
496 497 498
    'pattern' => 'post/<page:\d+>/<tag>',
    'route' => 'post/index',
    'defaults' => ['page' => 1],
Alexander Makarov committed
499
]
500
```
Alexander Makarov committed
501

502
More details in the [Url manager docs](url.md).
503

Qiang Xue committed
504
Response
505 506
--------

507 508
TBD

509 510 511
Extensions
----------

512 513
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).
514

515 516 517
Integration with Composer
-------------------------

518 519 520
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.
521

surek committed
522
In order to learn more refer to [composer](composer.md) and [installation](installation.md) sections of the guide.
523 524 525 526 527

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.