在 Yii 1.1 專案中,後台管理常需針對商品、訂單、會員等資料提供多欄位組合搜尋。本文記錄一個完整的「商品進階搜尋」實作流程,涵蓋 Model 搜尋邏輯、Controller 綁定、View 表單與狀態保持,供同好參考。
在 B2cGoods 模型中定義 search(),利用 CDbCriteria 動態組合 WHERE 條件,最後回傳 CActiveDataProvider 供 GridView/ListView 使用。
public function search()
{
$criteria = new CDbCriteria;
// 獨立高級搜尋區塊
if (isset($_GET['goods'])) {
// 商品貨號(模糊比對)
if (isset($_GET['goods']['goods_sn']) && $_GET['goods']['goods_sn'] !== '') {
$criteria->compare('goods_sn', $_GET['goods']['goods_sn'], true);
}
// 商品名稱(模糊比對)
if (isset($_GET['goods']['goods_name']) && $_GET['goods']['goods_name'] !== '') {
$criteria->compare('goods_name', $_GET['goods']['goods_name'], true);
}
// 商品分類(精確比對)
if (isset($_GET['goods']['cat_id']) && $_GET['goods']['cat_id'] !== '') {
$criteria->compare('cat_id', $_GET['goods']['cat_id'], true);
}
// 布林欄位:是否上架、精品、新品、熱銷
foreach (['is_on_sale', 'is_best', 'is_new', 'is_hot'] as $field) {
if (isset($_GET['goods'][$field]) && $_GET['goods'][$field] !== '') {
$criteria->compare($field, $_GET['goods'][$field]);
}
}
}
return new CActiveDataProvider($this, [
'criteria' => $criteria,
]);
}
關鍵點:
compare() 第三參數 true 表示使用 LIKE 模糊比對,適合字串欄位。AND 關係,符合典型後台篩選需求。public function actionGoodsList()
{
$model = new B2cGoods('search'); // 啟用 search 場景
$this->render('goodsList', ['model' => $model]);
}
傳入 'search' 場景可觸發模型中 rules() 定義的搜尋專用驗證規則(如安全屬性 safe)。
表單採用 GET 方法,欄位名稱統一前綴 goods[...],對應 Model 讀取 $_GET['goods']。
<div class="well">
<div class="search-box">
<form class="form-inline" method="get" action="">
<!-- 關鍵:隱藏路由參數,確保提交回正確 action -->
<input type="hidden" name="r" value="B2CShop/b2cGoods/goodsList/id/<?php echo $id ?>">
<div class="form-group">
<input name="goods[goods_sn]" type="text" class="form-control"
placeholder="商品貨號"
value="<?php echo isset($_GET['goods']['goods_sn']) ? htmlspecialchars($_GET['goods']['goods_sn']) : '' ?>">
</div>
<div class="form-group">
<input name="goods[goods_name]" type="text" class="form-control"
placeholder="商品名稱"
value="<?php echo isset($_GET['goods']['goods_name']) ? htmlspecialchars($_GET['goods']['goods_name']) : '' ?>">
</div>
<div class="form-group">
<?php echo CHtml::dropDownList(
'goods[cat_id]',
isset($_GET['goods']['cat_id']) ? $_GET['goods']['cat_id'] : '',
B2cCategory::listData($id),
['class' => 'form-control', 'empty' => '請選擇類型...', 'encode' => false, 'style' => 'width:140px']
); ?>
</div>
<!-- 布林欄位用 checkbox,刷新後保持勾選狀態 -->
<div class="checkbox">
<label>上架 <input type="checkbox" name="goods[is_on_sale]" value="1"
<?php echo (!empty($_GET['goods']['is_on_sale'])) ? 'checked="checked"' : '' ?> >
</label>
</div>
<div class="checkbox">
<label>精品 <input type="checkbox" name="goods[is_best]" value="1"
<?php echo (!empty($_GET['goods']['is_best'])) ? 'checked="checked"' : '' ?> >
</label>
</div>
<div class="checkbox">
<label>新品 <input type="checkbox" name="goods[is_new]" value="1"
<?php echo (!empty($_GET['goods']['is_new'])) ? 'checked="checked"' : '' ?> >
</label>
</div>
<div class="checkbox">
<label>熱銷 <input type="checkbox" name="goods[is_hot]" value="1"
<?php echo (!empty($_GET['goods']['is_hot'])) ? 'checked="checked"' : '' ?> >
</label>
</div>
<button type="submit" class="btn btn-default">
<span class="glyphicon glyphicon-search"></span> 搜尋
</button>
</form>
</div>
</div>
核心邏輯:<?php echo (!empty($_GET['goods']['is_hot'])) ? 'checked="checked"' : '' ?>
原理:表單送出後,$_GET 會保留勾選欄位的值(如 1),未勾選則不會出現在 $_GET 中。利用 empty() 判斷即可決定是否輸出 checked 屬性。
htmlspecialchars() 防 XSS。CActiveDataProvider 預設支援分頁,且分頁連結會自動帶上當前 $_GET 參數,無需額外處理。BETWEEN 條件,搭配 CJuiDatePicker 提升體驗。Yii 1.1 的 CActiveDataProvider + CDbCriteria 架構讓複雜搜尋變得清晰:Model 負責組裝條件、Controller 綁定場景、View 處理表單與狀態保持。掌握此模式,即可快速建構功能完整的後台搜尋介面。