Yii Framework Forum: Tips, Snippets and Tutorials ( Japanese ) - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Tips, Snippets and Tutorials ( Japanese ) Yiiを使いこなすためのヒント、コツ、小技等を扱うトピックです Rate Topic: -----

#1 User is offline   jamband 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 75
  • Joined: 05-November 10

Posted 10 June 2011 - 02:40 PM

Yiiを使いこなすためのヒント、コツ、小技等を扱うトピックです
Yii初心者のための基本的なことまとめと同様、それぞれのTipsをリストアップしていきます

これは便利だと思う使い方や、こういう風に扱うとスマートになるなど
ささいなことでもかまわないので、遠慮なく書き込んでください
本家はこちら - Yii Framework Discussions Subforums - Tips, Snippets and Tutorials


( 最終更新日 2012-04-08 )
0

#2 User is offline   jamband 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 75
  • Joined: 05-November 10

Posted 10 June 2011 - 04:10 PM

CRUD操作の簡略化

それぞれのコントローラで
同じようなCRUDアクションを書くのに退屈しないために

まず、createと、updateはほぼ同じなので、components/actions/Save.phpにまとめます
<?php
class Save extends CAction {

	public function run($id=null)
	{
		$c = $this->getController(); // $cは各コントローラ内で使う$thisと同じ
		$m = ucfirst($c->getId()); // $mは各コントローラ内で使うモデル名
		$model = $id===null ? new $m : $m::model()->load($id); // GET['id']がnullならcreate処理, そうでないならupdate処理
	
		if (isset($_POST['confirm']))
		{
			$model->attributes = $_POST[$m];
			if ($model->validate())
			{
				$c->setPageState('x', $model->attributes);
				$c->render('confirm', array('model'=>$model));
				return;
			}
		}
		else if (isset($_POST['back']))
			$model->attributes = $c->getPageState('x');
		else if (isset($_POST['finish']))
		{
			$model->attributes = $c->getPageState('x');
			if ($model->save())
				$c->redirect(array('index'));
		}
		$c->render('save', array('model'=>$model)); // create, updateともにsave.php(view)でまとめています
	}
}

確認画面処理も追加しています。確認画面の操作はこちらなどを参考にしてください
続いて、components/actions/Delete.php:
<?php
class Delete extends CAction {

	public function run($id=null)
	{
		$c = $this->getController();
		$m = ucfirst($c->getId());
		
		$m::model()->load($id)->delete();
		$c->redirect(array('index'));
	}
}

$m::model()->load($id)はモデル内で次のように書いています
public function load($id)
{
	$model = $this->findByPk((int)$id);
	if ($model===null)
		throw new CHttpException(404,'データがありません');
	return $model;
}

create, update, deleteアクションの骨格はできたので
次に、components/Controller.phpに以下のコードを足します
public function actions()
{
	return array(
		'save'=>array(
			'class'=>'application.components.actions.Save',
		),
		'delete'=>array(
			'class'=>'application.components.actions.Delete',
		),
	);
}

あとは、Controller.phpを継承して各コントローラを書けば
自動的にcreate, update, deleteのアクションが作られるようになります

ttp://www.example.com/index.php?r=hoge/save にアクセスするとcreate処理
ttp://www.example.com/index.php?r=hoge/save&id=777 にアクセスするとupdate処理
ttp://www.example.com/index.php?r=hoge/delete&id=777 にアクセスするとdelete処理になります
( readも同じような流れだと思うので省きました )

補足:
Viewについてですが、create, updateの処理をviews/hoge/save.phpにまとめる形になるので
$model->isNewRecordなどを使って、少し表示に工夫が必要になるかもしれません

関連リンク
[Wiki] Actions code reuse with CAction
[Guide] コントローラ - 3.アクション
0

#3 User is offline   mocapapa 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 428
  • Joined: 04-January 09
  • Location:Tokyo, JAPAN

Posted 10 June 2011 - 07:39 PM

ページキャッシュノウハウ

開発はローカルで高速なサーバで、運用はリモートで遅いサーバで行っていますが、高速なYiiといえども、ページの表示に悪くすると1秒かかったりしています。これではとても見るに耐えないため、ガイドのキャッシュの項を参考にしてページ表示の超高速化に成功しました。

http://pugpug.lolipo...as-blog/post/89

遅いサーバでもキャッシュに入れば2msec程度で表示されるため、数百倍の超高速化が達成できました。
0

#4 User is offline   jamband 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 75
  • Joined: 05-November 10

Posted 11 June 2011 - 05:04 AM

ビヘイビアを使って、画像アップロード処理を簡単にする

再利用可能なコードはcomponentやbehaviorなどにまとめておくと便利です
今回は画像アップロード処理をbehaviorにまとめて
使用したいモデルのみでそれを利用するやり方を書いていきます

2011-12-03 更新
以前書いたものを参考にして
ブログで書き直してみました。ボリュームがありますが、よろしければ参考にしてください
http://livejamdb.blo...-framework.html
0

#5 User is offline   softark 

  • Keep It Simple
  • Yii
  • Group: Moderators
  • Posts: 2,112
  • Joined: 16-February 11
  • Location:Japan

Posted 11 June 2011 - 05:22 AM

複写して新規作成

CRUD 操作に「複写して新規作成」という操作を追加すると便利です。
機能的には、既存のエントリーの内容をコピーして、新規作成のフォームにペーストするものです。少し内容を変えただけの新規エントリーを登録したい場合に重宝します。

「複写して新規作成」は、Gii が自動生成した CRUD のコードをほんの少し拡張するだけで実装することが可能です。

1) コントローラに、モデルのデータを複製するメソッドを追加。
public function duplicateModel($id)
{
        $model = $this->loadModel($id);
        // 新規エントリーとするために、データを部分的にクリアする
        $model->id = null;   // PK をクリア ... たいていの場合に必須
        $model->foo = null;  // 例
        $model->bar = null;  // 例
        ....                 // 何をクリアすべきかは、モデルの設計によって異なる
                             // クリア操作は、モデルクラスでやる方が良いかも、、、
        $model->isNewRecord = true;    // 新規レコードとする ... 必須
        return $model;
}

2) コントローラの actionCreate() メソッドを修正して、PK をパラメータとして取るようにする。
public function actionCreate($id = null)
{
        $model = null;
        if ($id === null || isset($_POST['FooBar']))
                $model = new FooBar;
        else
                $model = $this->duplicateModel($id);

        // AJAX validation
        $this->performAjaxValidation($model);

        if (isset($_POST['FooBar']))
        {
                $model->attributes = $_POST['FooBar'];
                if ($model->save())
                        $this->redirect(array('view', 'id'=>$model->id));
        }
        $this->render('create',array(
                'model' => $model,
        ));
}

引数 `$id` は、デフォルト値として `null` を取ります。
`$id` が null の場合は、従来同様、"create" のアクションとして機能し、`$id` に有効な値が入っている場合は、「複写して新規作成」のアクションとして機能します。

3) ビュー・ファイルで、「複写して新規作成」を呼び出すリンクを作る。
例えば、view.php で、
// views/FooBar/view.php
....
<?php echo CHtml::link('複写して新規作成', array('create', 'id'=>$model->id)); ?>
....

または、admin.php で、
// views/FooBar/admin.php
....
$this->widget('zii.widgets.grid.CGridView', array(
        'id' => 'foo-bar-grid',
        'dataProvider' => $model->search(),
        'filter' => $model,
        'columns' => array(
                'foo',
                'bar',
                ....
                array(
                        'class' => 'CButtonColumn',
                ),
                array(
                        'header' => '複写して新規作成',
                        'type' => 'raw',
                        'value' => 'CHtml::link("複写して新規作成", array("create", "id"=>$data->id))',
                ),
        ),
));

たったこれだけです。お試しあれ。
0

#6 User is offline   jamband 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 75
  • Joined: 05-November 10

Posted 21 December 2011 - 02:36 AM

ユーザ関連の実装をモジュールで作る利点

ユーザ関連の実装をモジュールで作ってみたんですが
なかなか良かったので、メリット、デメリットなどをブログにまとめてみました
http://livejamdb.blo.../12/yii_20.html
0

#7 User is offline   mocapapa 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 428
  • Joined: 04-January 09
  • Location:Tokyo, JAPAN

Posted 06 January 2012 - 06:39 PM

Yiiコードリーディング

index.phpから追いかけようと思ったこと、ありますよね?普通はclass referenceに詳細な説明があるので、メソッドを追いかけるのにclass referenceを使うと思いますが、欠点がひとつあります。それはメソッド名を出すのに検索しなければならないことです。

先日、ひらメソッドという方法をみつけ、さっそくYiiのコードリーディングに応用できないかと思い、ためしたところ、ある程度うまく行ったので以下に記して置きます。

https://sites.google...iianalysis/home

ちなみに、ひらメソッドというのは自分がCPUになった気持ちで、完全にボトムアップにコードを読む方式です。
0

#8 User is offline   jamband 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 75
  • Joined: 05-November 10

Posted 06 February 2012 - 02:59 PM

ビューでウィジェットのコードをシンプルに書くいくつかの方法

どうしても長くなりがちなウィジェットのコードを、シンプルに書く方法をまとめてみました
わりと基本的な3つを紹介していますが、これらの他にもこういう方法があるよ、などの意見も聞ければ幸いです
http://livejamdb.blo...i.html?spref=tw
0

#9 User is offline   tanakahisateru 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 2
  • Joined: 20-September 11

Posted 07 February 2012 - 03:59 AM

CDetailView に複雑なHTMLを表示させたいとき

Yii の CDetailView に複雑なHTMLを表示させたいとき CController::renderPartial で value を埋める。

たとえば _complex_content.php というような、複雑なHTMLの中身をレンダリングするためのファイルを作り、そこでHTMLを構築するようにする。で、CDetailView のほうで特定のカラムの表示のみ詳細化し、type を raw に、そして value として CController::renderPartial メソッドを使う。
$this->widget('zii.widgets.CDetailView', array(
    'data'=>$model,
    'attributes'=>array(
        'id',
        'name',
        //'poor_content',  // 文字列表示じゃかっこ悪い
        array(
            'label'=>'Complex Content',
            'type'=>'raw',
            'value'=> $this->renderPartial('_complex_content', array(
                'data'=>$model,
            ), true), // ここ大事
        ),
),
));


CController::renderPartialメソッドはサブテンプレートに「出力」させるだけでなく、結果を文字列で得ることもできます。省略可能な第三引数は、サブテンプレートのレンダリング結果をいきなり表示するか、結果を文字列で得るかのオプションです。

これで、凝ったHTMLを表示させたいとき、いきなり CDetailView や CGridView の便利さを捨てて全部自前でデザインする必要がなくなりました。スキャフォルドで生成された、標準の機能を使うテンプレートの大部分を生かしつつ、かつ、部分的に独自のHTMLにすることができます。

テンプレートの外部化によって、CDetailView の直前でHTMLを得るために文字列結合処理するという汚いやり方を避けられます。また、本質的に複雑なものは自然に外出しファイルになってくれます。
0

#10 User is offline   jamband 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 75
  • Joined: 05-November 10

Posted 01 March 2012 - 12:14 AM

CLinkPagerの実装を拡張してシンプルにする

やや、強引な拡張の仕方ではありますが
CLinkPagerクラスを使って、ウィジェットの拡張方法を簡単にまとめてみました

http://livejamdb.blo...r.html?spref=tw
0

#11 User is offline   jamband 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 75
  • Joined: 05-November 10

Posted 07 April 2012 - 12:48 PM

3通りを簡単に切り替えられるログインの実装

  • ユーザ名 と パスワード
  • メールアドレス と パスワード
  • ユーザ名またはメールアドレス と パスワード

LoginForm部分のrules()で array('login, password', 'loginValidator'),
と指定しているのが、果たしてアリなのかがちょっと微妙です。誤作動はないですが、もしあれば言ってください

http://livejamdb.blo...ramework-3.html
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users