You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Yii2实现单搜索框多列查询:calls表contact_number与contact_name

在Yii2中实现单个搜索框同时搜索两个字段的方案

嗨,这个需求在Yii2里实现起来很简单,咱们一步步来修改对应的三个文件就行:

1. 修改搜索模型:common\models\CallsSearch.php

首先要在搜索模型里新增一个用于全局搜索的属性,然后在搜索逻辑里添加对两个字段的模糊匹配:

<?php

namespace common\models;

use yii\base\Model;
use yii\data\ActiveDataProvider;
use common\models\Calls;

/**
 * CallsSearch represents the model behind the search form of `common\models\Calls`.
 */
class CallsSearch extends Calls
{
    // 新增全局搜索属性,用来接收单个搜索框的输入
    public $globalSearch;

    /**
     * {@inheritdoc}
     */
    public function rules()
    {
        return array_merge(parent::rules(), [
            // 给全局搜索字段添加安全验证规则,确保参数能被正常加载
            ['globalSearch', 'safe'],
        ]);
    }

    /**
     * {@inheritdoc}
     */
    public function scenarios()
    {
        // 跳过父类的scenarios实现,直接使用Model的默认逻辑
        return Model::scenarios();
    }

    /**
     * Creates data provider instance with search query applied
     *
     * @param array $params
     *
     * @return ActiveDataProvider
     */
    public function search($params)
    {
        $query = Calls::find();

        $dataProvider = new ActiveDataProvider([
            'query' => $query,
        ]);

        $this->load($params);

        if (!$this->validate()) {
            // 如果验证失败,返回空的数据集(也可以注释下面的代码返回全部数据)
            // $query->where('0=1');
            return $dataProvider;
        }

        // 核心逻辑:用or条件同时匹配contact_number和contact_name字段
        if (!empty($this->globalSearch)) {
            $query->orFilterWhere(['like', 'contact_number', $this->globalSearch])
                  ->orFilterWhere(['like', 'contact_name', $this->globalSearch]);
        }

        return $dataProvider;
    }
}

2. 修改搜索视图:views/calls/_search.php

把原来分别对应contact_number和contact_name的两个输入框,替换成单个全局搜索输入框:

<?php

use yii\helpers\Html;
use yii\widgets\ActiveForm;

/* @var $this yii\web\View */
/* @var $model common\models\CallsSearch */
/* @var $form yii\widgets\ActiveForm */
?>

<div class="calls-search">

    <?php $form = ActiveForm::begin([
        'action' => ['index'],
        'method' => 'get',
        'options' => [
            'data-pjax' => 1
        ],
    ]); ?>

    <!-- 单个全局搜索输入框,添加占位提示引导用户 -->
    <?= $form->field($model, 'globalSearch')->textInput([
        'placeholder' => '输入联系人号码或姓名进行搜索'
    ]) ?>

    <div class="form-group">
        <?= Html::submitButton('搜索', ['class' => 'btn btn-primary']) ?>
        <?= Html::resetButton('重置', ['class' => 'btn btn-outline-secondary']) ?>
    </div>

    <?php ActiveForm::end(); ?>

</div>

如果原来的视图里还有其他不需要的搜索字段,可以直接删掉,让界面更简洁。

3. 调整控制器(基本无需修改):controllers/CallsController.php

一般来说,默认的actionIndex方法不需要改动,只要它是Yii2标准的CRUD写法就行,比如:

<?php

namespace app\controllers;

use Yii;
use common\models\Calls;
use common\models\CallsSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;

/**
 * CallsController implements the CRUD actions for Calls model.
 */
class CallsController extends Controller
{
    // ... 其他过滤/初始化方法

    /**
     * Lists all Calls models.
     * @return mixed
     */
    public function actionIndex()
    {
        $searchModel = new CallsSearch();
        $dataProvider = $searchModel->search(Yii::$app->request->queryParams);

        return $this->render('index', [
            'searchModel' => $searchModel,
            'dataProvider' => $dataProvider,
        ]);
    }

    // ... 其他CRUD方法
}

这里的核心是确保搜索模型能接收到请求参数,而我们已经在CallsSearch里处理了globalSearch的逻辑,所以控制器保持默认即可。

小提示

  • 如果需要区分大小写的搜索,可以在like条件里添加第三个参数false,比如['like', 'contact_name', $this->globalSearch, false],不过Yii2默认是不区分大小写的,具体取决于你的数据库配置。
  • 要是想让搜索更智能,比如支持分词或复杂匹配,可以修改orFilterWhere里的条件,比如使用数据库的全文搜索函数或者CONCAT拼接字段。

内容的提问来源于stack exchange,提问作者Moutinho

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:03:51