【问题标题】:How to unserialize field before compare by andFilterWhere(['like', ...)如何在通过 andFilterWhere(['like', ...) 进行比较之前反序列化字段
【发布时间】:2015-11-13 14:15:15
【问题描述】:

在 yii2 我有搜索模型:

public function search($params)
{
    $query = MyModel::find();

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

    $this->load($params);

    if (!$this->validate()) {
        return $dataProvider;
    }

    $query->andFilterWhere(['like', 'passengers', $this->passengers]);

    return $dataProvider;
}

passengers 是 mysql 表中包含序列化数组的 TEXT 字段。

问: 如何告诉andFilterWhere() 函数反序列化并通过数组中的任何元素进行比较?像这样的东西:$query->andFilterWhere(['like', unserialize('passengers')[0]['name'], $this->passengers]); - 表示数组的第一个元素,带有 'name' 键

【问题讨论】:

  • 查询特征方法转换为 SQL。假设通过序列化您指的是 phps serialize() 方法,MYSQL 无法使用它。你需要规范你的数据库

标签: php mysql serialization yii yii2


【解决方案1】:

不幸的是,这是您的数据结构中的一个问题。存储序列化数据使查询变得更加困难。 andFilterWhere 方法只产生 SQL 级别的过滤,你真的需要代码级别的过滤,因为 SQL 不知道 PHP 序列化是什么。有两种方法可以解决这个问题:

后查询过滤器

根据您的表有多大,您可以返回搜索查询的所有结果,然后使用一个简单的循环来反序列化并删除不在乘客列表中的值。

伪代码是:

$result = MyModel::search(...);
$filteredResult = array_filter($result->toArray(), function ($el) {
    $availablePassengers = unserialize($el['passengers']);
    return count(array_intersect($availablePassengers, $this->passengers));
});

改变你的结构

最好的解决方案可能是更改您的数据结构,以便以多对多关系存储乘客。这将允许您使用数据库查询执行这种过滤,并使您的数据正确规范化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-10
    • 1970-01-01
    • 2013-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多