控制器 PostController
public function actionView($id) {
$post = $this->loadModel($id);
$comment = $this->newComment($post); // 處理提交並返回表單模型
$this->render('view', ['model'=>$post, 'comment'=>$comment]);
}
protected function newComment($post) {
$comment = new Comment();
if (isset($_POST['Comment'])) {
$comment->attributes = $_POST['Comment'];
if ($post->addComment($comment)) { // 模型層處理保存邏輯
if ($comment->status == Comment::STATUS_PENDING)
Yii::app()->user->setFlash('commentSubmitted', '評論已提交,待審核顯示。');
$this->refresh(); // PRG 模式防重複提交
}
}
return $comment;
}
模型 Post.php
public function addComment($comment) {
$comment->status = Yii::app()->params['commentNeedApproval']
? Comment::STATUS_PENDING : Comment::STATUS_APPROVED;
$comment->post_id = $this->id;
return $comment->save();
}
視圖 post/view.php
<div id="comments">
<h3>發表評論</h3>
<?php if (Yii::app()->user->hasFlash('commentSubmitted')): ?>
<div class="flash-success"><?= Yii::app()->user->getFlash('commentSubmitted') ?></div>
<?php else: ?>
<?php $this->renderPartial('/comment/_form', ['model'=>$comment]); ?>
<?php endif; ?>
</div>
評論表單局部視圖 comment/_form.php
<?php $form=$this->beginWidget('CActiveForm', ['id'=>'comment-form']); ?>
<?= $form->errorSummary($model) ?>
<div class="row">
<?= $form->labelEx($model,'content') ?>
<?= $form->textArea($model,'content',['rows'=>6,'cols'=>50]) ?>
<?= $form->error($model,'content') ?>
</div>
<?php if (CCaptcha::checkRequirements()): ?>
<div class="row">
<?= $form->labelEx($model,'verifyCode') ?>
<?php $this->widget('CCaptcha'); ?>
<?= $form->textField($model,'verifyCode') ?>
<?= $form->error($model,'verifyCode') ?>
</div>
<?php endif; ?>
<div class="row buttons"><?= CHtml::submitButton('提交') ?></div>
<?php $this->endWidget(); ?>
關鍵設計模式
- PRG (Post-Redirect-Get):提交成功後
$this->refresh() 重定向到 GET 請求,防止刷新重複提交。
- Flash 訊息:
setFlash/getFlash 跨請求顯示一次性提示。
- 關聯封裝:
Post::addComment() 內部設置 post_id、狀態,控制器無需知曉細節。
- 局部視圖復用:
renderPartial('/comment/_form') 實現表單邏輯與展示分離。