在Yii模型中实现模糊搜索需用andFilterWhere自动忽略空值,支持多字段OR组合、关联表joinWith、前缀匹配(禁用自动%)及全文索引(需手动判空)。

要在Yii模型中实现用户输入的模糊搜索功能,必须让空值参数自动被忽略,否则搜索框留空时会生成WHERE name = ''这种无效条件,导致查不到任何数据。
基础模糊匹配:andFilterWhere(['like', '字段名', 用户输入])
第一步:在SearchModel的search()方法里,用andFilterWhere替代andWhere。
第二步:传入三元数组['like', 'username', $this->username],其中第三个值允许为空——【如果这里用andWhere,当$this->username为空字符串时,SQL会变成WHERE username LIKE '',永远不命中】。
第三步:调用$query->andFilterWhere(['like', 'email', $this->email])追加第二个模糊条件,它会自动跳过$email为空的情况。
多字段联合模糊搜索(含中文分词兼容)
方法一:用OR组合多个like条件
$query->andFilterWhere(['or', ['like', 'username', $this->keyword], ['like', 'realname', $this->keyword], ['like', 'mobile', $this->keyword]]);
方法二:用MATCH AGAINST(仅MySQL全文索引可用)
$query->andFilterWhere(new \yii\db\Expression("MATCH(username, realname) AGAINST(:kw IN NATURAL LANGUAGE MODE)", [':kw' => $this->keyword]));
注意:此写法绕过andFilterWhere的空值过滤,需手动判断【$this->keyword不能为空字符串,否则会触发MySQL语法错误】。
关联表字段模糊搜索(如用户+所属部门名称)
第一步:在SearchModel中声明关联字段,例如public $department_name;
第二步:在rules()里给该字段加'safe'验证规则,否则load()时会被过滤掉。
第三步:在search()中显式joinWith('department'),再用andFilterWhere(['like', 'department.name', $this->department_name])。
这一步不能省略joinWith——【没join就直接引用department.name,SQL会报Unknown column错误】。
带前缀的模糊搜索(如手机号开头匹配)
使用andFilterWhere(['like', 'mobile', $this->mobile . '%'], false),第三个参数设为false表示禁用自动加%通配符。
这样输入138就会查出所有以138开头的手机号,而不是包含138的任意位置。
这比写['>=', 'mobile', $this->mobile]更精准,避免数字比较导致的前导零丢失问题。


















