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
相关产品推荐
相关产品推荐

