PHPのMVCフレームワークの中では、Githubリポジトリのスターの数がLaravel, CodeIgniter, Symfonyに次いでくらい多いのに、国内では書籍でも紹介されることがないマイナーなフレームワークYii。
最近2.0がリリースされてモダンになったらしいので、雰囲気を掴むためにプロジェクトのセットアップからScaffoldingツール GiiによるCRUDコードの生成を試してみました。
Yiiの特徴としては、まずOracleにやMongoDBなど他のフレームワークでは対応していないDBまでサポートしていることがあります。
SQLServerは最近どのフレームワークでも対応してきましたが、Oracleでちゃんと動くのはYiiとSymfonyくらいではないでしょうか。
また、これからフレームワークを選定するならLaravelとの比較になると思いますが、LaravelはフロントエンドにAngularJSやReactJSなどのSPAフレームワークと組み合わせて使うことを考慮しているのに対して、どちらかというとYiiは昔ながらのMVCフレームワークでシンプルです。
また、Scaffoldingツール Giiが便利で、ささっとDBのフロントアプリを立ち上げたいとかに向いてそうです。
インストール
Vagrantを利用して環境を構築してみます。
Ubuntu 14.04のVagrant boxにLAMPをインストールし、Yii 2.0のプロジェクトを生成、動作を確認するところまでまず解説していきます。
Vagrant環境のセットアップ
プロジェクト用ディレクトリyii2-hello
を作成して、Ubuntu 14.04のVagrant環境を用意
$ mkdir yii2-hello && cd yii2-hello
$ vagrant init ubuntu/trusty64
Vagrantfileを以下のように設定します。
# Vagrantfile
Vagrant.configure(2) do |config|
config.vm.box = ";ubuntu/trusty64";
config.vm.network ";forwarded_port";, guest: 80, host: 8080
config.vm.synced_folder ";.";, ";/var/www/html";, group: ";www-data";, mount_options: [";dmode=775,fmode=664";]
config.vm.provision ";shell";, inline: <<-SHELL
sudo apt-get update
sudo apt-get install tasksel -y
sudo tasksel install lamp-server
SHELL
end
Vagrantfileの各設定については以下の通り
ホストからのApacheへのアクセスはポートフォワードを利用
config.vm.network ";forwarded_port";, guest: 80, host: 8080
Vagrantfileに共有ディレクトリを/var/www/html
に設定して、Apacheから参照できるように権限を付与
config.vm.synced_folder ";.";, ";/var/www/html";, group: ";www-data";, mount_options: [";dmode=775,fmode=664";]
Vagrantのフォルダ共有についてはこちらが参考になります: Synced Folders
プロビジョンで、LAMPをインストール
config.vm.provision ";shell";, inline: <<-SHELL
sudo apt-get update
sudo apt-get install tasksel -y
sudo tasksel install lamp-server
SHELL
Vagrantfileが用意出来たら、Vagrantを起動します。
$ vagrant up
Yii 2.0プロジェクトの作成
Installing YiiにしたがってYii2プロジェクトを作成していきます。
まずVagrantにログイン
$ vagrant ssh
Yii2はプロジェクトの生成にComposerを利用します。
以下のコマンドでインストール
$ curl -s http://getcomposer.org/installer | php
$ sudo mv composer.phar /usr/local/bin/composer
ComposerでYiiのプロジェクトを作成します。
たいていの場合はGithubのTokenのプロンプトが表示されるので、https://github.com/settings/tokensよりトークンを発行して指定する必要があります。
$ cd /var/www/html
$ composer global require ";fxp/composer-asset-plugin:~1.1.1";
$ composer create-project --prefer-dist yiisoft/yii2-app-basic basic
...
Could not fetch https://api.github.com/repos/RobinHerbots/jquery.inputmask/commits/d180082aa1ba98c85f85b2c4eebbfa195fd25613, please create a GitHub OAuth token to go over the API rate limit
Head to https://github.com/settings/tokens/new?scopes=repo&description=Composer+on+vagrant-ubuntu-trusty-64+2015-06-15+1326
to retrieve a token. It will be stored in ";/home/vagrant/.composer/auth.json"; for future use by Composer.
Token (hidden):
...
Apacheの設定
次はWebサーバーの設定です。
Apacheをインストールしたので、Recommended Apache ConfigurationのとおりにApacheを設定してみます。
ApacheのDocumentRootを/var/www/html/basic/web
に設定
# /etc/apache2/sites-available/000-default.conf
DocumentRoot /var/www/html/basic/web
(※ Rewriteの設定については後述)
設定ファイルをリロードします。
$ sudo service apache2 reload
動作確認
Vagrantで8080にポートフォワードしているのでhttp://localhost:8080でアクセスして以下のページが表示されればOKです。
ScaffoldingツールGiiを試す
動作が確認できたら、次にScaffoldingツールGiiを試してみます。
Giiは、データベースに定義されたテーブルからカラムを参照してモデルのコードを生成します。
これはこれで、データベースを設計するエンジニアがプログラマーとは別に居たりするプロジェクトなどは便利ですし、
普通にマイグレーションを利用してコードでテーブルを管理することもできます。
データベース接続設定
まず、データベース接続の準備をします。
設定はconfig/db.php
に記述
<?php
// config/db.php
return [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=yii2basic',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
];
動作確認用なので、デフォルト設定のままデータベース yii2basic
を作成してみます。
mysql> create database yii2basic;
Giiの表示
Giiへのアクセスは、デフォルトでは制限されています。
Vagrantからは、ホストからのアクセスは10.0.2.2に見えるので、allowedIPsに設定します。
// confit/web.php
// ...
$config['modules']['gii'] = [
'class' => 'yii\gii\Module',
'allowedIPs' => ['127.0.0.1', '10.0.2.2'] // adjust this to your needs
];
設定後、http://localhost:8080/index.php?r=gii
にアクセスすると以下のページが表示されます。
モデルの生成
モデルの基になるサンプルテーブルをデータベースに定義します。
CREATE TABLE articles (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
title VARCHAR(255) NOT NULL,
text TEXT,
PRIMARY KEY(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
[Model Generator]を開き、[Table Name]作成したテーブル名を、[Model Class]にモデルのクラス名を入力します。
[Preview]をクリックして生成されるファイルを確認後、[Generate]ボタンをクリックすると以下のようにテーブル情報を読み込んで自動でモデルのコードが生成されます
<?php
// models/Article.php
namespace app\models;
use Yii;
/**
* This is the model class for table ";articles";.
*
* @property integer $id
* @property string $title
* @property string $text
*/
class Article extends \yii\db\ActiveRecord
{
/**
* @inheritdoc
*/
public static function tableName()
{
return 'articles';
}
/**
* @inheritdoc
*/
public function rules()
{
return [
[['title'], 'required'],
[['text'], 'string'],
[['title'], 'string', 'max' => 255]
];
}
/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'title' => 'Title',
'text' => 'Text',
];
}
}
バリデーションルールなども自動で追加されて気が利いていますね。
CRUD画面の生成
CRUDの画面は、対象のモデル(上記で作成したもの)を指定し、CRUDアクションを含むコントローラーと各アクションに対応するビューを生成します。
[CRUD Generator]を開き以下のように設定します。
Model Class
作成してモデルを完全修飾(名前空間付)クラス名で指定する
テーブルに主キーが定義されていない場合は、モデルに主キーの定義が必要
モデルにprimaryKey
メソッドを追加しておく
Search Model Class
検索フォーム用モデルを完全修飾クラス名で入力
Controller Class
コントローラのクラス名を完全修飾クラス名で入力
View Path
[View Path]は、ディレクトリを指定、区切り文字は’\’じゃなくて’/’なので注意。
[Controller Class]に入力したコントローラ名が例えば”BookCategoryController”のように途中に大文字を含む場合は、”@app/views/book-category”のようにハイフンを入れて指定します。
参照: Controller IDs、Controller Class Naming
[Preview]をクリックすると、以下のファイルが生成されることが確認できます。
http://localhost:8080?r=article/index
にアクセスすると以下のように表形式のビューが表示されます。
ルーティング
ここまで説明してきて、ルーティングが?r=<コントローラID>/<アクションID>
(Controllers Routes)なのが気になると思います。
ルーティングについては、Handring RequestのRouting and URL Creationに説明されていますので、それにしたがって設定してみます。
config/web.php
への設定
デフォルトの?r=<コントローラID>/<アクションID>
といったパラメータ形式のルーティングを/<コントローラID>/<アクションID>
といったURL形式にするには、components
にurlManager
を追加し、enablePrettyUrl
をtrue
にします。
<?php
$params = require(__DIR__ . '/params.php');
$config = [
'id' => 'basic',
'basePath' => dirname(__DIR__),
'bootstrap' => ['log'],
'components' => [
...
'urlManager' => [
'enablePrettyUrl' => true,
],
],
]
これで、まず先ほど作成したArticleControllerに/index.php/article/index
のようにアクセスできるようになります。
ApacheにRewriteの設定を追加
さらにエントリースクリプトの/index.php
も消したい場合は、ApacheにRewriteの設定を追加する必要があります。
# /etc/apache2/sites-available/000-default.conf
<Directory ";/var/www/html/basic/web";>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)\?*$ index.php/$1 [L,QSA]
</Directory>
mod_rewriteを有効にして、Apache2をリスタートします。
$ sudo a2enmod rewrite
$ sudo service apache2 restart
以下の通り/article/index
でアクセス可能になりました。
参考
Envato Tuts+ Code Tutorial
– How to Program with Yii2: Getting Started
– How to Program With Yii2: Working With the Database and Active Record