スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Yiiで、ビヘイビアを使ってみる

簡単な説明

ビヘイビアっていうのは、PHPだとmixinと同義に扱われている。
CakePHPなんかでもほとんどおんなじ機能があって、要するに「クラスを継承しないで、メソッドを実装したい」
もしくは「PHPでも多重継承をしたい」っていう場合に使う機能のこと。

超簡単なサンプル

まあ、百聞は一見にしかず。簡単なサンプル。作るファイルは二つ

まずはBehaviorそのもの
protected/components/ExampleBehavior.php
<?php

class ExampleBehavior extends CBehavior{
  public function hoge(){
    echo "hoge";
  }
}
?>
次はこいつを使うクラス。今回は簡単のためコントローラ
protected/controllers/HogeController.php

class HogeController Extends CController {
  // CComponentの子クラスでは、behaviors()メソッドをオーバーライドすることで、
  // ビヘイビアの実装が可能
  public function behaviors(){
    return array(
      'hoge' => array(
        'class' => 'application.components.ExampleBehavior',
      ),
    );
  }

  public function actionIndex(){
    // このクラスはhoge()メソッドを持っていないにもかかわらず、
    // ビヘイビアクラスから継承したかのように実行できる
    $this->hoge();
  }
}

このコントローラにアクセスしてみると、

hoge

と表示される。

具体的な使用例

実際にはCActiveRecordBehaviorを継承して使うことが圧倒的に多いんじゃないんだろうか。
実は自分もこの使い方しかしたことがない。

CActiveRecordBehaviorを継承して、以下のメソッドをオーバーライドすることで、モデルの処理とかにいろんな悪さが出来る。

beforeSave() / afterSave() → save()の前後。afterSaveが一番使うかも
beforeValidate() / afterValidate() → バリデーションの前後。入力データを書き換えたりするならここかも
beforeFind() / afterFind() → find()の前後

具体的な実装例はzii.behaviors.CTimestampBehaviorがいいかも。
これをbehaviors()メソッドをオーバーライドして実装すると、create_timeという列に作成日時を、update_timeという列に更新日時を勝手に設定してくれる。

使用例はいくらでも考えられるだろうけれど

afterSave()を使って、データを更新したときに、更新ログを残す
バリデーションされるたびに、エラーになったデータを別のテーブルに記録する

など色々考えられると思う。
スポンサーサイト

Yii環境構築をゼロからやってみた

はじめに

Yii 1.1.4 がリリースされた。
今回のリリースでは大幅な機能追加とか、変更とかなさそう。
いいことではないんですが、、半年くらい、同じ開発環境をコピーしたり使いまわしたりしてのをゼロから構築しなおしてみた。

半ば備忘録だけれど、どうせなんで簡単なテーブルを作ってcrudできるところまでやってみる。

・目標はApache+MySQL+PHPの非常に一般的な環境
・URLは/controller/view/id/1 とかのダサくないURLでアクセス出来るように
・yii-dbmigrationsというエクステンションを使用してDBを管理する。
・環境はMac OS X。MacPortsでインストールしたのを使用したけど、他の環境でも大差ないはず

ApacheやMySQLの設定は終わっていることを前提とする。

1. ダウンロード

まずフレームワーク本体をダウンロード。SVNでtrunkからexportしたら、1.1.5の開発版になってしまったのでやり直し、
http://www.yiiframework.com/download/
からtar.gzファイルを普通にダウンロードして解凍。
frameworkとrequirementsのディレクトリを残してほかは全部削除。
reuierementsも本当は必要ないけれど、なんかトラブルが起きた時のために使うかもってことで、残してる。

2. Webアプリケーションの作成


appという名前のアプリケーションを作成する。
面倒だと思ったことはないんだけれど、この手順って面倒。手元にCLI環境持ってない人とかも、PHPerには結構いるだろうに。
カラのアプリケーションとか入れといてくれたらいいのにね
以下のコマンドで作成
$ ./framework/yiic webapp app

これでappというディレクトリができた。

3. config/main.phpの設定

設定ファイル類の設定する。
編集するのはdbの設定と、urlManagerの設定だけでOKかと。
以下はほぼそのままの例


return array(
    'basePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..',
    'name'=>'My Web Application',

    // preloading 'log' component
    'preload'=>array('log'),

    // autoloading model and component classes
    'import'=>array(
        'application.models.*',
        'application.components.*',
    ),

    'modules'=>array(
    ),

    // application components
    'components'=>array(
        'user'=>array(
            // enable cookie-based authentication
            'allowAutoLogin'=>true,
        ),
        // uncomment the following to enable URLs in path-format
        'urlManager'=>array(
      'showScriptName' => false, // リンクするときにindex.phpが表示されなくなる
             'urlFormat'=>'path',
            'rules'=>array(
                '<controller:\w+>/<id:\d+>'=>'<controller>/view',
                '<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
                '<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
            ),
        ),

    'db'=>array(
            'connectionString' => 'mysql:host=localhost;dbname=mydb',
            'emulatePrepare' => true,
            'username' => 'root',
            'password' => '',
            'charset' => 'utf8',
        ),
        'errorHandler'=>array(
            // use 'site/error' action to display errors
            'errorAction'=>'site/error',
        ),
    'log'=>array(
            'class'=>'CLogRouter',
            'routes'=>array(
                array(
                    'class'=>'CFileLogRoute',
                    'levels'=>'error, warning',
                ),
            ),
        ),
    ),
);

4. httpd.confやmod_rewriteの設定


あとはApacheでローカル8080ボートのルートディレクトリが来るようにしてみる。
以下はhttpd.confの追記の例

Listen 8080
<VirtualHost *:8080>
    DocumentRoot "/Users/takakino/htdocs/app"
</VirtualHost>


コントロラーラ系の設定として最後は.htaccessでmod_rewriteを設定する。
以下の例だと「パス上に実際に存在するファイルはそのまま表示し、ないものはYiiに渡す」という例。

RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ index.php

5. データベースの設定の作成

まずは普通にデータベース作成。MySQLにコマンドラインでつないで
mysql> create database mydb default character set utf8;
Query OK, 1 row affected (0.00 sec)

普通のYiiの開発手順だと、ここでテーブルを作成してしまうんだけれど、今回はyii-dbmigrationsを使うのでMySQLのコマンドラインはここまで。

protected/config/main.phpを編集。MySQLをみに行くようにする

//'db'=>array(
//'connectionString' => 'sqlite:'.dirname(__FILE__).'/../data/testdrive.db',
//),
// uncomment the following to use a MySQL database
'db'=>array(
'connectionString' =>  'mysql:host=localhost;dbname=mydb',
'emulatePrepare' => true,
'username' => 'root',
'password' =>>'',
'charset' => 'utf8',
),


6. yii-dbmigrationsの設定

Railsライクなmigration機能を提供するエクステンション。
正直そんなに完成度が高いわけでもないけれど、それでもあったほうがずっと便利かも。

http://www.yiiframework.com/extension/yii-dbmigrations/ ここからダウンロードして、中身のファイルを

protected/extensions/yii-dbmigrations/

というディレクトリを作成して展開する。
展開したら、コンソールアプリにこのコマンドを使うことを知らせてやる必要がる。

protected/config/console.php
を編集する。
return array(
  'basePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..',
  'name'=>'My Console Application',
  // コマンドの設定
  'commandMap' => array(
      'migrate' => array(
          'class'=>'application.extensions.yii-dbmigrations.CDbMigrationCommand',
      ),
  ),
  // 普通は不要。なぜかyii-dbmigrasionsに必要
  'components'=>array(
    'db'=>array(
      'connectionString' => 'mysql:host=localhost;dbname=mydb',
      'emulatePrepare' => true,
      'username' => 'root',
      'password' => '',
      'charset' => 'utf8',
    ),
  ),
);

yiicをオプションなしで実行して以下のように表示されればとりあえず設定成功
$ ./protected/yiic 
Yii command runner (based on Yii v1.1.4)
Usage: ./protected/yiic  [parameters...]

The following commands are available:
 - message
 - migrate
 - shell
 - webapp

To see individual command help, use the following:
   ./protected/yiic help 




後の方のDB設定をここで行わなくてはいけない理由は謎。普通のyiicだけで作るなら、省略して全く問題ない。

7. テーブル作成


今回はマイグレーションを使ってテーブルを作成する。
面倒な人は、普通にSQL書いてテーブル作るんでも問題ない。

今回はただのcrudのテストなので簡単なメモアプリケーションを作る。

まずカラのマイグレーションを作成する。

$ ./protected/yiic migrate create CreateMemo
Migrations directory: protected/migrations/

Created migration: m20100907165713_CreateMemo.php


最後の引数は省略可能で、UntitledMigrationって名前で作る。
とくに意味はないんだけれど、メンテナンスのためには分かりやすい名前を付けるといい。

で、できたてのmigrationのファイルを開いて、up()とdown()の中身を実装してやる。

class m20100907165713_CreateMemo extends CDbMigration {
    
  public function up() {
    $t = $this->newTable('memo', 'Engine=InnoDB');
    $t->primary_key('id');

    $t->string('author');    // 作者名
    $t->string('title');     // タイトル
    $t->text('content');     // 本文
    $t->integer('priority'); // 重要度

    $t->datetime('create_time'); // 作成日時

    $this->addTable($t);
  }

  public function down() {
    $this->removeTable('memo');
  }
}

マイグレーションファイルができたら、migrateコマンドを実行する。
$ ./protected/yiic migrate
Migrations directory: protected/migrations/

Creating initial schema_version table
=== Applying: m20100907165713_CreateMemo =======================================
    >> Creating table: memo
=== Marked as applied: m20100907165713_CreateMemo ==============================


memoというテーブルができていればOK。

8. modelとcrudの作成


あとは、modelとcrudを一発コマンドするだけ。

$ ./protected/yiic shell
Yii Interactive Tool v1.1 (based on Yii v1.1.4)
Please type 'help' for help. Type 'exit' to quit.
>> model Memo memo
   generate models/Memo.php
   generate fixtures/memo.php
   generate unit/MemoTest.php

The following model classes are successfully generated:
    Memo

If you have a 'db' database connection, you can test these models now with:
    $model=Memo::model()->find();
    print_r($model);

>> crud Memo memo
   generate MemoController.php
   generate MemoTest.php
      mkdir /Users/takakino/htdocs/app/protected/views/memo
   generate create.php
   generate update.php
   generate index.php
   generate view.php
   generate admin.php
   generate _form.php
   generate _view.php
   generate _search.php

Crud 'memo' has been successfully created. You may access it via:
http://hostname/path/to/index.php?r=memo



9. テストしてみる


http://localhost:8080/memo

でcrudが表示されるはず。デフォルトでのログインはadmin/adminでOK。
memo_crud meme_crud_update
できたー。
長かったけれど、一回作れば、長くコピペでいけるはずだし、migrationの設定ははしょって構わない。
本当はもうちょっといじるところがあるのだけれど、そこはまた後日機会があれば。

テーマ : プログラミング
ジャンル : コンピュータ

Yiiでクラスが見つからないと怒られるとき

Yii::import( "some.path.to.Class" );

要するに、これだけ。

遭遇したのがCTimeStampBehaviorをちょっくらいじくって小クラスを作ろうとしたとき、

include(CTimestampBehavior.php) [function.include]: failed to open stream: No such file or directory

なんて怒られた。
最初は該当するファイルを直接パスを書いてrequireして解決したのだけれど、きれいじゃないので調べてみたら解決策は、簡単に見つかった。

 
Yii::import( 'zii.behaviors.CTimestampBehavior');
 
class CTimestampBehaviorEx extends CTimestampBehavior {
  // 中身は略	
}

としただけ。
なんだかんだで、Yiiを使い出して半年以上。
すべてに満足というわけではないけれど、なかなか面白いです。

Yiiのモジュール内でのCRUD

正直、あんまり現状のYiiのCRUDは賢くない。
けれど文字通り足場(scaffoldってそういう意味らしい)を作ると考えるのなら、ないより全然いい!。
のだけれど、モジュールを作ってから、モジュール内にcurdコマンドがエラーだらけらになったので、自分の為に手順メモ。

1. moduleコマンドでモジュールを作成
2. 一旦yiicを終了して、configを修正。モジュールを読み込むようにする。← ここが抜けてた。
3. modelコマンドでモデルを作成。
4. crudコマンドでCRUSを作成。

わかれば簡単!

とりあえずテーブル作成

前提として。
 DB接続とか、基本的な設定はできているものとします。
 環境は Yii 1.1.0 + MySQL 5.1。OSはUbuntu 9.10を使ってます。
 モジュール名は kokyaku にしてみます。英語苦手。
まずはテーブル作成。
create table customers( 
  id int primary key auto_increment, 
  name varchar(255), 
  zip varchar(7), 
  tel varchar(30), 
  address varchar(255), 
  email varchar(255), 
  birthday datetime 
) Engine=InnoDB;


モジュールの作成


Yiiのルートディレクトリで以下のコマンドを叩く
$ ./protected/yiic shell
Yii Interactive Tool v1.1 (based on Yii v1.1.0)
Please type 'help' for help. Type 'exit' to quit.
>> module kokyaku
      mkdir /home/nakano/yii/testdrive/protected/modules
      mkdir /home/nakano/yii/testdrive/protected/modules/kokyaku
      mkdir /home/nakano/yii/testdrive/protected/modules/kokyaku/views
      mkdir /home/nakano/yii/testdrive/protected/modules/kokyaku/views/default
   generate views/default/index.php
      mkdir /home/nakano/yii/testdrive/protected/modules/kokyaku/views/layouts
      mkdir /home/nakano/yii/testdrive/protected/modules/kokyaku/controllers
   generate controllers/DefaultController.php
      mkdir /home/nakano/yii/testdrive/protected/modules/kokyaku/messages
      mkdir /home/nakano/yii/testdrive/protected/modules/kokyaku/components
      mkdir /home/nakano/yii/testdrive/protected/modules/kokyaku/models
   generate KokyakuModule.php

Module 'kokyaku' has been created under the following folder:
    /home/nakano/yii/testdrive/protected/modules/kokyaku

You may access it in the browser using the following URL:
    http://hostname/path/to/index.php?r=kokyaku

Note, the module needs to be installed first by adding 'kokyaku'
to the 'modules' property in the application configuration.

>> exit

ここで一旦閉じて次へ。

configファイルの設定

configファイル(普通は YII_ROOT/config/main.php )を編集する
name の下とかわかりやすいところに
	'name'=>'test app',
	'modules'=> array( 'kokyaku' ), // この行を追加する。複数モジュールを使う場合には array()の中に列挙

あとはmodelとcrudの作成

$ ./protected/yiic shell
Yii Interactive Tool v1.1 (based on Yii v1.1.0)
Please type 'help' for help. Type 'exit' to quit.
>> model kokyaku.models.Customer customers
   generate models/Customer.php
   generate fixtures/customers.php
   generate unit/CustomerTest.php

The following model classes are successfully generated:
    Customer

If you have a 'db' database connection, you can test these models now with:
    $model=Customer::model()->find();
    print_r($model);

>> crud kokyaku.models.Customer 
   generate CustomerController.php
   generate CustomerTest.php
      mkdir /home/nakano/yii/testdrive/protected/modules/kokyaku/views/customer
   generate create.php
   generate update.php
   generate index.php
   generate view.php
   generate admin.php
   generate _form.php
   generate _view.php

Crud 'customer' has been successfully created. You may access it via:
http://hostname/path/to/index.php?r=kokyaku/customer


こんなで完成。
前のエントリのスクリーンショットが実はここで作ったもの。

・・・失敗しまくった理由

モジュールを作った直後にhelp modelコマンドで、でてくる
 * Generates the Post model which should belong to module 'admin':
        model admin.models.Post
という記述を当てにして、configの設定をまったくしないまま、何度も
>> model kokyaku.Customer customers 
とかやるも全部エラー。。。
実はちゃんと日本語の説明もあるのに気づかずに30分くらい、無駄に格闘してたわけです・・。

テーマ : プログラミング
ジャンル : コンピュータ

PHPのフレームワーク「Yii」

Yiiに出会うまで

実はここ数カ月、フレームワークジプシーとでもいうべき生活をしていた。
Railsは素晴らしい!。とは思うんだけれど、Rubyは嫌い。自分のRuby嫌いは、PHP/FIとかの時代からのもので、多分治らないだろう。

で、PHPを主に使ってきた身としては、やっぱりPHPがいい。
CakePHPが人気らしいけれど、どうも好きになれない。
Code Igniterは実際ある程度使い込んでみて、いいとは思うんだけれど、「小さいアプリを素早く作る」ことに特化している感じで、限界がある。

そんな中、最近見つけたすごく新しいフレームワークがYii。なんかゲーム機みたいな名前たけれど、ドキュメントを見る限り良く出来ている感じ。

http://www.yiiframework.com/

主観的なYiiの特長

「生産性が高い」とか「○分でアプリが作れる」とか「多彩なヘルパー」とか、そういうありきたりなことは、やめといて、他と比べてなにがいいのかってところをまとめてみると。
PHP5専用である
いまさらPHP4に対応する理由がわからない。そのために、APIが汚くなるなんて言語道断。
ドキュメントが充実している。
英語しかないけれど、すごくよみやすく、新しいフレームワークなのにサンプルも豊富。
APIがとにかくきれい。
「慎重に設計されたAPI」という言葉が、Yiiのドキュメントにはよく出てくるけれど、よく考えられている印象。
後発の利を生かして、他のフレームワークの良いところをどん欲に取り入れてまとめた感じ。
デフォルトのテンプレートがきれい
どうでもいいことのように思えて、すごく嬉しいこと。
うるさくないユーザーにはscaffoldで生成したまま納入していいかもってくらいきれい。

まったくいじってないデフォルトのままのスクリーンショット(クリックするとフルサイズが見れます)
いくらなんでもRailsの真っ白なあれは納入できないしね。「ちょっとCSSを整えれば・・・」てのもナシ。手間は少ないほうがいいんです
ActiveRecordが高機能っぽい * 未検証 *
そんなに使い込んでないのでわからないけれど、バリデーションやアソシエーションとか、欲しい機能が揃っている感じ。
モジュールによる、コードの再利用ができそう *未検証*
もっとも注目している点。
基本的に普通のMVCフレームワークなんだけれど、「アプリケーション」と「モジュール」という考え方があって
通常は、
 application1
  - controllers
  - models
  - views
という構成なんだけれど、モジュールを作ると
 application1
  - controllers
  - models
  - views
  - modules
   - module1
    - controllers
    - models
    - views
   - module2
    - controllers
    - models
    - views
という構成にできる。アプリケーションに直接MVCを実装するんじゃなくて、モジュールとしてそれぞれMVCをひとまとめにすることによって、よく使う機能を再利用しやすくできるんじゃないかと。
まあ、正直これは未検証。ディレクトリ階層が深くなるってデメリットはあるので、やってみないとわからない。
エクステンションが探しやすい
http://www.yiiframework.com/extensions/?sort=download
ホントに探しやすい。

Yiiのよろしくないところ

いいことばっかり書いてもあれなので、いじってみてよくないところも列挙。
実績がない
1.0.0が2008年12月3日らしい。文句なく実績は全然ない。
あ、でも、自分が人柱になる気満々です。3か月くらいしたら、なにか報告できるんじゃないかと思います。
環境を選ぶ
実績の次に壁になりそうな点。
PDOが必須らしいし、mcryptもあったほうがいい。なんてことを考えるとレンサバな人にはきついかも。
テスト機能もまだまだな感じ
今年に入ってリリースされた1.1.0でようやくテストが標準搭載。
ユニットテストは結構いい感じだけれど、コントローラーのテストはSelenium必須とか。ハイパワーなPCでないと、おそくてたまんなそう。
不安定なところもあるかも
Railsやsymfonyみたいにコマンドラインツールとかがついてるんだけれど、こいつらがバンバンWarning出たりする。そりゃぁ完成度がそこまで高いってわけではない。
クラスの命名規則がMFCっぽくて気持ち悪い
どうでもいいことだけれど、CControllerとか、CActiveRecordとか、Windowsでプログラムしなくてはならなかった時代のいやな記憶が蘇ります。
他のフレームワークのライブラリを読み込んでもクラス名がかぶらないようにって、配慮の意味もあらるしいけれど・・・

まだまだあるけれど、こんなところかなぁ。。。それでもCodeIgniter以来の「使ってみたいフレームワーク」なので、色々やってみようと思います。

テーマ : ホームページ・ブログ制作
ジャンル : コンピュータ

プロフィール

takakino

Author:takakino
長いことPHPとかJavaとか、その昔はPerlとか。Webのシステム屋をずーっとやってきました。
最近Scalaにはまっています。

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
Yii (5)
カレンダー
08 | 2017/09 | 10
- - - - - 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Twitter
Twitterこそこそやってます
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QRコード
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。