php - 如何在通过 andFilterWhere( ['like' , ...) 进行比较之前反序列化字段

标签 php mysql serialization yii yii2

在 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]); - 表示第一个元素带有“名称”键的数组

最佳答案

不幸的是,这是您的数据结构中的一个陷阱。存储序列化数据使得查询变得更加困难。 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));
});

改变结构

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

关于php - 如何在通过 andFilterWhere( ['like' , ...) 进行比较之前反序列化字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33694762/

相关文章:

java - 反序列化集合时不安全的泛型转换

javascript - getElementById() 不适用于动态分配的 id

php - if(!$variable) 和 if(isset($variable)) 有什么区别?

php - RESTful API 的 nginx 配置

mysql - MySQL 中的主键 : INT(n) or UUID as varchar(36)

c# - 避免使用不支持序列化的类

c++ - 将 Boost 序列化与前向声明类和继承一起使用

php - 如何在表中添加新条目并更改其他条目的排序顺序

mysql - 我不明白如何检查sql中的查询条件

mysql - 当列数据发生变化时如何获取行