1 フォロワー

バージョン 1.1 からのアップグレード

Yii のバージョン 1.1 と 2.0 の間には多くの違いがあります。フレームワークは 2.0 用に完全に書き直されたためです。その結果、バージョン 1.1 からのアップグレードは、マイナーバージョン間のアップグレードほど簡単ではありません。このガイドでは、2 つのバージョン間の主な違いについて説明します。

Yii 1.1 を以前に使用したことがない場合は、このセクションをスキップして、「入門」に直接進んでも構いません。

Yii 2.0 には、この概要で説明されている以上の新機能が導入されていることに注意してください。すべてを学ぶために、完全ガイド全体を読むことを強くお勧めします。以前は自分で開発する必要があった機能が、コアコードの一部になっている可能性があります。

インストール

Yii 2.0 は、事実上の PHP パッケージマネージャーである Composer を完全に採用しています。コアフレームワークと拡張機能のインストールは、Composer を通じて処理されます。Yii 2.0 のインストール方法については、「Yii のインストール」セクションを参照してください。新しい拡張機能を作成したり、既存の 1.1 拡張機能を 2.0 互換の拡張機能に変換したりする場合は、ガイドの「拡張機能の作成」セクションを参照してください。

PHP の要件

Yii 2.0 は PHP 5.4 以上を必要とします。これは Yii 1.1 で必要だった PHP 5.2 から大きく改善された点です。その結果、言語レベルで注意すべき多くの違いがあります。以下は PHP に関する主な変更点の概要です。

名前空間

Yii 2.0 で最も明らかな変更点は、名前空間の使用です。ほとんどすべてのコアクラスが名前空間化されています。例: yii\web\Request。「C」接頭辞はクラス名で使用されなくなりました。命名規則はディレクトリ構造に従うようになりました。例えば、yii\web\Request は、対応するクラスファイルが Yii フレームワークフォルダ下の web/Request.php であることを示しています。

(Yii クラスローダーのおかげで、クラスファイルを明示的にインクルードせずに、任意のコアクラスを使用できます。)

Component と Object

Yii 2.0 では、1.1 の CComponent クラスが yii\base\BaseObjectyii\base\Component の 2 つのクラスに分割されました。BaseObject クラスは、getter および setter を介して オブジェクトプロパティを定義できる軽量な基本クラスです。Component クラスは BaseObject を拡張し、イベントビヘイビアをサポートします。

クラスにイベントやビヘイビア機能が必要ない場合は、BaseObject を基本クラスとして使用することを検討してください。これは通常、基本的なデータ構造を表すクラスの場合です。

オブジェクト構成

BaseObject クラスは、オブジェクトを構成するための統一された方法を導入しています。BaseObject のすべての子孫クラスは、正しく構成できるように、コンストラクタ (必要な場合) を次の方法で宣言する必要があります。

class MyClass extends \yii\base\BaseObject
{
    public function __construct($param1, $param2, $config = [])
    {
        // ... initialization before configuration is applied

        parent::__construct($config);
    }

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

        // ... initialization after configuration is applied
    }
}

上記の例では、コンストラクタの最後のパラメータは、コンストラクタの最後にプロパティを初期化するための名前と値のペアを含む構成配列を受け取る必要があります。init() メソッドをオーバーライドして、構成が適用された後に行う必要のある初期化作業を行うことができます。

この規約に従うことで、構成配列を使用して新しいオブジェクトを作成および構成することができます。

$object = Yii::createObject([
    'class' => 'MyClass',
    'property1' => 'abc',
    'property2' => 'cde',
], [$param1, $param2]);

構成の詳細については、構成セクションを参照してください。

イベント

Yii 1 では、イベントは on メソッド (例: onBeforeSave) を定義することで作成されていました。Yii 2 では、任意のイベント名を使用できるようになりました。trigger() メソッドを呼び出すことでイベントをトリガーします。

$event = new \yii\base\Event;
$component->trigger($eventName, $event);

イベントにハンドラをアタッチするには、on() メソッドを使用します。

$component->on($eventName, $handler);
// To detach the handler, use:
// $component->off($eventName, $handler);

イベント機能には多くの機能強化があります。詳細については、イベントセクションを参照してください。

パスエイリアス

Yii 2.0 では、パスエイリアスの使用がファイル/ディレクトリパスと URL の両方に拡張されました。Yii 2.0 では、エイリアスと通常のファイル/ディレクトリパスまたは URL を区別するために、エイリアス名が @ 文字で始まる必要があります。たとえば、エイリアス @yii は Yii のインストールディレクトリを参照します。パスエイリアスは Yii コアコードのほとんどの場所でサポートされています。たとえば、yii\caching\FileCache::$cachePath はパスエイリアスと通常のディレクトリパスの両方を受け入れることができます。

パスエイリアスはクラスの名前空間にも密接に関連しています。各ルート名前空間に対してパスエイリアスを定義し、それによって追加の設定なしで Yii クラスオートローダーを使用できるようにすることをお勧めします。たとえば、@yii は Yii のインストールディレクトリを参照するため、yii\web\Request のようなクラスを自動ロードできます。Zend Framework のようなサードパーティライブラリを使用する場合は、そのフレームワークのインストールディレクトリを参照するパスエイリアス @Zend を定義できます。それを行えば、Yii は Zend Framework ライブラリ内のすべてのクラスを自動ロードできるようになります。

パスエイリアスの詳細については、エイリアスセクションを参照してください。

ビュー

Yii 2 のビューに関する最も重要な変更点は、ビュー内の特殊変数 $this が現在のコントローラまたはウィジェットを参照しなくなったことです。代わりに、$this は 2.0 で導入された新しい概念である *view* オブジェクトを参照します。 *view* オブジェクトは yii\web\View 型で、MVC パターンのビュー部分を表します。ビューでコントローラまたはウィジェットにアクセスする場合は、$this->context を使用できます。

別のビュー内で部分ビューをレンダリングするには、$this->renderPartial() ではなく $this->render() を使用します。render の呼び出しも明示的にエコーする必要があります。これは、render() メソッドがレンダリング結果を直接表示するのではなく、返すためです。例:

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

PHP を主要なテンプレート言語として使用するだけでなく、Yii 2.0 は 2 つの人気のあるテンプレートエンジンである Smarty と Twig の公式サポートも備えています。Prado テンプレートエンジンはサポートされなくなりました。これらのテンプレートエンジンを使用するには、View::$renderers プロパティを設定して、view アプリケーションコンポーネントを構成する必要があります。詳細については、テンプレートエンジンセクションを参照してください。

モデル

Yii 2.0 では、1.1 の CModel と同様に、yii\base\Model が基本モデルとして使用されます。クラス CFormModel は完全に削除されました。代わりに、Yii 2 では yii\base\Model を拡張してフォームモデルクラスを作成する必要があります。

Yii 2.0 では、サポートされているシナリオを宣言し、どのシナリオで属性を検証する必要があるか、安全と見なすことができるかなどを示すための scenarios() という新しいメソッドが導入されています。例:

public function scenarios()
{
    return [
        'backend' => ['email', 'role'],
        'frontend' => ['email', '!role'],
    ];
}

上記の例では、backendfrontend の 2 つのシナリオが宣言されています。backend シナリオでは、email 属性と role 属性の両方が安全で、大量に割り当てることができます。frontend シナリオでは、email は大量に割り当てることができますが、role はできません。emailrole の両方をルールを使用して検証する必要があります。

rules() メソッドは、検証ルールを宣言するために引き続き使用されます。scenarios() の導入により、unsafe バリデーターはなくなっていることに注意してください。

ほとんどの場合、rules() メソッドが既存のシナリオを完全に指定し、unsafe 属性を宣言する必要がない場合は、scenarios() をオーバーライドする必要はありません。

モデルの詳細については、モデルセクションを参照してください。

コントローラ

Yii 2.0 では、Yii 1.1 の CController と同様に、yii\web\Controller が基本コントローラクラスとして使用されます。yii\base\Action はアクションクラスの基本クラスです。

これらの変更がコードに及ぼす最も明らかな影響は、コントローラアクションが、エコーするのではなく、レンダリングするコンテンツを返す必要があることです。

public function actionView($id)
{
    $model = \app\models\Post::findOne($id);
    if ($model) {
        return $this->render('view', ['model' => $model]);
    } else {
        throw new \yii\web\NotFoundHttpException;
    }
}

コントローラの詳細については、コントローラセクションを参照してください。

ウィジェット

Yii 2.0 では、Yii 1.1 の CWidget と同様に、yii\base\Widget が基本ウィジェットクラスとして使用されます。

IDE でのフレームワークのサポートを向上させるために、Yii 2.0 ではウィジェットを使用するための新しい構文が導入されています。静的メソッド begin()end()widget() が導入されました。以下のように使用されます。

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();

詳細については、ウィジェットセクションを参照してください。

テーマ

2.0 ではテーマの動作が完全に異なります。テーマは、ソースビューファイルのパスをテーマのビューファイルのパスにマッピングするパスマッピングメカニズムに基づいています。たとえば、テーマのパスマップが ['/web/views' => '/web/themes/basic'] である場合、ビューファイル /web/views/site/index.php のテーマ化されたバージョンは /web/themes/basic/site/index.php になります。このため、テーマは、コントローラまたはウィジェットのコンテキスト外でレンダリングされるビューファイルであっても、任意のビューファイルに適用できるようになりました。

また、CThemeManager コンポーネントはなくなりました。代わりに、themeview アプリケーションコンポーネントの構成可能なプロパティです。

詳細については、テーマ設定セクションを参照してください。

コンソールアプリケーション

コンソールアプリケーションは、Web アプリケーションのようにコントローラとして構成されるようになりました。コンソールコントローラは、1.1 の CConsoleCommand と同様に、yii\console\Controller から拡張する必要があります。

コンソールコマンドを実行するには、yii <route> を使用します。ここで、<route> はコントローラルート (例: sitemap/index) を表します。追加の無名引数は対応するコントローラアクションメソッドのパラメータとして渡されます。一方、名前付き引数は yii\console\Controller::options() の宣言に従って解析されます。

Yii 2.0 は、コメントブロックからのコマンドヘルプ情報の自動生成をサポートしています。

詳細については、コンソールコマンドセクションを参照してください。

I18N

Yii 2.0 では、PECL intl PHP モジュールを優先して、組み込みの日付フォーマッタと数値フォーマッタの部分が削除されています。

メッセージ翻訳は、i18n アプリケーションコンポーネントを介して実行されるようになりました。このコンポーネントは、メッセージカテゴリに基づいて異なるメッセージソースを使用できるメッセージソースのセットを管理します。

詳細については、国際化セクションを参照してください。

アクションフィルタ

アクションフィルタは、ビヘイビアを介して実装されるようになりました。新しいカスタムフィルタを定義するには、yii\base\ActionFilter から拡張します。フィルタを使用するには、フィルタクラスをビヘイビアとしてコントローラにアタッチします。たとえば、yii\filters\AccessControl フィルタを使用するには、コントローラに次のコードを使用します。

public function behaviors()
{
    return [
        'access' => [
            'class' => 'yii\filters\AccessControl',
            'rules' => [
                ['allow' => true, 'actions' => ['admin'], 'roles' => ['@']],
            ],
        ],
    ];
}

詳細については、フィルタリングセクションを参照してください。

アセット

Yii 2.0 では、Yii 1.1 にあったスクリプトパッケージの概念を置き換える、*アセットバンドル*という新しい概念が導入されています。

アセットバンドルとは、ディレクトリ内のアセットファイル(例:JavaScriptファイル、CSSファイル、画像ファイルなど)の集まりです。各アセットバンドルは、yii\web\AssetBundleを拡張するクラスとして表現されます。yii\web\AssetBundle::register()を通じてアセットバンドルを登録することにより、そのバンドル内のアセットをWeb経由でアクセス可能にします。Yii 1とは異なり、バンドルを登録したページには、そのバンドルで指定されたJavaScriptファイルとCSSファイルへの参照が自動的に含まれます。

詳細については、アセットの管理セクションを参照してください。

ヘルパー

Yii 2.0では、以下を含む、一般的に使用される多くの静的ヘルパークラスが導入されています。

詳細については、ヘルパーの概要セクションを参照してください。

フォーム

Yii 2.0では、yii\widgets\ActiveFormを使用してフォームを構築するためのフィールドの概念が導入されています。フィールドは、ラベル、入力、エラーメッセージ、および/またはヒントテキストで構成されるコンテナです。フィールドは、ActiveFieldオブジェクトとして表現されます。フィールドを使用することで、以前よりもクリーンなフォームを構築できます。

<?php $form = yii\widgets\ActiveForm::begin(); ?>
    <?= $form->field($model, 'username') ?>
    <?= $form->field($model, 'password')->passwordInput() ?>
    <div class="form-group">
        <?= Html::submitButton('Login') ?>
    </div>
<?php yii\widgets\ActiveForm::end(); ?>

詳細については、フォームの作成セクションを参照してください。

クエリビルダー

1.1では、クエリの構築は、CDbCommandCDbCriteria、およびCDbCommandBuilderを含むいくつかのクラスに分散していました。Yii 2.0では、DBクエリを、バックグラウンドでQueryBuilderの助けを借りてSQLステートメントに変換できるQueryオブジェクトとして表現します。例えば

$query = new \yii\db\Query();
$query->select('id, name')
      ->from('user')
      ->limit(10);

$command = $query->createCommand();
$sql = $command->sql;
$rows = $command->queryAll();

何よりも、このようなクエリ構築メソッドは、Active Recordを操作する場合にも使用できます。

詳細については、クエリビルダーセクションを参照してください。

アクティブレコード

Yii 2.0では、Active Recordに多くの変更が加えられています。最も明確な2つの変更点は、クエリ構築とリレーショナルクエリの処理に関連しています。

1.1のCDbCriteriaクラスは、Yii 2ではyii\db\ActiveQueryに置き換えられています。このクラスはyii\db\Queryから拡張されているため、すべてのクエリ構築メソッドを継承します。クエリの構築を開始するには、yii\db\ActiveRecord::find()を呼び出します。

// To retrieve all *active* customers and order them by their ID:
$customers = Customer::find()
    ->where(['status' => $active])
    ->orderBy('id')
    ->all();

リレーションを宣言するには、ActiveQueryオブジェクトを返すゲッターメソッドを定義するだけです。ゲッターによって定義されたプロパティ名は、リレーション名を表します。たとえば、次のコードはordersリレーションを宣言します(1.1では、リレーションをrelations()という中心的な場所に宣言する必要がありました)。

class Customer extends \yii\db\ActiveRecord
{
    public function getOrders()
    {
        return $this->hasMany('Order', ['customer_id' => 'id']);
    }
}

これで、関連テーブルから顧客の注文にアクセスするために$customer->ordersを使用できます。また、次のコードを使用して、カスタマイズされたクエリ条件でオンザフライのリレーショナルクエリを実行することもできます。

$orders = $customer->getOrders()->andWhere('status=1')->all();

リレーションのイーガーローディングを行う場合、Yii 2.0は1.1とは異なる方法で行います。具体的には、1.1では、プライマリレコードとリレーショナルレコードの両方を選択するためにJOINクエリが作成されます。Yii 2.0では、JOINを使用せずに2つのSQLステートメントが実行されます。最初のステートメントはプライマリレコードを返し、2番目のステートメントはプライマリレコードのプライマリキーでフィルタリングすることによりリレーショナルレコードを返します。

ActiveRecordオブジェクトを返す代わりに、多数のレコードを返すためにクエリを構築するときにasArray()メソッドをチェーンすることができます。これにより、クエリ結果が配列として返され、多数のレコードの場合、必要なCPU時間とメモリを大幅に削減できます。例えば

$customers = Customer::find()->asArray()->all();

もう1つの変更点は、パブリックプロパティを介して属性のデフォルト値を定義できなくなったことです。必要な場合は、レコードクラスのinitメソッドで設定する必要があります。

public function init()
{
    parent::init();
    $this->status = self::STATUS_NEW;
}

1.1では、ActiveRecordクラスのコンストラクターをオーバーライドすることにいくつかの問題がありました。これらは、バージョン2.0には存在しません。コンストラクターにパラメーターを追加する場合は、yii\db\ActiveRecord::instantiate()をオーバーライドする必要がある場合があることに注意してください。

Active Recordには他にも多くの変更と拡張機能があります。詳細については、Active Recordセクションを参照してください。

アクティブレコードビヘイビア

2.0では、ベースビヘイビアクラスCActiveRecordBehaviorを削除しました。Active Recordビヘイビアを作成する場合は、yii\base\Behaviorから直接拡張する必要があります。ビヘイビアクラスがオーナーのイベントに応答する必要がある場合は、次のようにevents()メソッドをオーバーライドする必要があります。

namespace app\components;

use yii\db\ActiveRecord;
use yii\base\Behavior;

class MyBehavior extends Behavior
{
    // ...

    public function events()
    {
        return [
            ActiveRecord::EVENT_BEFORE_VALIDATE => 'beforeValidate',
        ];
    }

    public function beforeValidate($event)
    {
        // ...
    }
}

ユーザーとIdentityInterface

1.1のCWebUserクラスは、yii\web\Userに置き換えられ、CUserIdentityクラスはなくなりました。代わりに、使用がはるかに簡単なyii\web\IdentityInterfaceを実装する必要があります。高度なプロジェクトテンプレートには、そのような例が用意されています。

詳細については、認証認可、および高度なプロジェクトテンプレートセクションを参照してください。

URL管理

Yii 2のURL管理は、1.1のURL管理に似ています。大きな拡張機能は、URL管理がオプションのパラメータをサポートするようになったことです。たとえば、次のようにルールが宣言されている場合、post/popularpost/1/popularの両方に一致します。1.1では、同じ目標を達成するために2つのルールを使用する必要がありました。

[
    'pattern' => 'post/<page:\d+>/<tag>',
    'route' => 'post/index',
    'defaults' => ['page' => 1],
]

詳細については、Url managerドキュメントセクションを参照してください。

ルートの命名規則における重要な変更点は、コントローラーとアクションのキャメルケース名が、各単語がハイフンで区切られた小文字に変換されるようになったことです。例えば、CamelCaseControllerのコントローラーIDはcamel-caseになります。詳細については、コントローラーIDおよびアクションIDに関するセクションを参照してください。

Yii 1.1と2.xを一緒に使用する

Yii 2.0と一緒に使用したいレガシーYii 1.1コードがある場合は、Yii 1.1と2.0を一緒に使用するセクションを参照してください。

タイプミスを見つけたり、このページを改善する必要があると思われる場合は?
Githubで編集する !