【问题标题】:Search for occurences of multiple variables stored in an array using Wordpress wp_query使用 Wordpress wp_query 搜索存储在数组中的多个变量的出现
【发布时间】:2016-02-17 22:29:39
【问题描述】:

这应该很容易解决,我认为与我使用 LIKE 有关,但我就是只见树木不见森林!

我定义了一个名为 COURSES 的自定义帖子类型 (CPT)。使用高级自定义字段 (ACF),COURSES CPT 有一个名为 TEACHERS 的列。 ACF 在 TEACHERS 列中存储了大量数据,包括每位教师的唯一 ID。

$_SESSION['search_teachers'] 由表单中的多选字段填充,并包含我要搜索 TEACHERS 列的教师 ID。它可以包含任意数量的教师 ID。

这是我目前所拥有的:

$teachers = implode($_SESSION['search_teachers'],',');

$args_courses = array(
            'post_type' => 'courses',
            'posts_per_page' => 9999,
            'meta_query' => array(
                array(
                    'key' => 'active',
                    'value' => 1,
                    'compare' => '='
                ),
                array(
                    'key' => 'teachers',
                    'value' => $teachers,
                    'compare' => 'LIKE'
                )
            ),
            'orderby' => 'course_name',
            'order'   => 'ASC'
        );

请注意我正在使用:

'key' => 'active', 'value' => 1, 'compare' => '='

在我的 WP_query 中过滤课程是否当前处于活动状态。

如果 $_SESSION['search_teachers'] 仅包含 1 个教师 ID,我的 WP_query 工作正常。当 $_SESSION['search_teachers'] 包含多个教师 ID 时,如何使其工作?

提前感谢您的帮助!

编辑: 这是我的教师专栏中包含的内容:

a:3:{i:0;s:3:"509";i:1;s:3:"511";i:2;s:3:"514";}

这就是我的 $_SESSION['search_teachers'] 中包含的内容:

Array ( [0] => 511 [1] => 514 )

【问题讨论】:

  • 想想你的查询会做什么:它会生成WHERE .. teachers LIKE 'teacher1,teacher2'。你可能想要IN
  • 或者,您可以尝试使用EXISTS
  • @Kenney:这种事情有find_in_set(),但效率不高。

标签: php mysql wordpress session sql-like


【解决方案1】:

参见wp-includes/meta.php 中的WP_Meta_Query 类,引用自wp-includes/query.php

$teachers = $_SESSION['search_teachers'];   // keep as array

...
          array(
                'key' => 'teachers',
                'value' => $teachers,      // an array of strings
             // 'compare' => 'IN'          // this is default if $teachers is an array
          )

更新

给定教师列的值为

a:3:{i:0;s:3:"509";i:1;s:3:"511";i:2;s:3:"514";}

这是serialized 数据, 没有可靠的方法可以使用 SQL 进行查询。此类数据旨在用于 PHP 级别,而不是由数据库使用。最好简单地使用多个 postmeta 条目,这与我上面给出的解决方案配合得很好。

您可以尝试通过以下方式“破解”它,但 1) 我不推荐这样做,因为如果更改序列化数据的结构可能会产生误报,并且 2) 这是不可能的:

'meta_query' => array_merge(
    array(
        'key' => 'active',
        'value' => 1,
        'compare' => '='
    ),

    // TODO: 'OR'
    array_map( function($teacher_id) {
        return array(
            'key' => 'teachers',
            'value' => "%\"$teacher_id\"%",
            'compare => 'LIKE'
        );
    } )
),

如你所见,我们需要以某种方式将其变成

WHERE ... 
  (active = 1 AND (
      teachers LIKE '%"ID_1"%'
   OR teachers LIKE '%"ID_2"%'
   OR teachers LIKE '%"ID_3"%'
  ))

但是this is not possible with meta_query.

正如我之前所说,您应该使用多值元,如下所示:

table wp_postmeta:

meta_id | post_id | meta_key    | meta_value
--------+---------+-------------+------------
 1000   |  20000  | teacher     | 509
 1001   |  20000  | teacher     | 511
 1002   |  20000  | teacher     | 514

【讨论】:

  • 感谢 Kenny,但比较 => IN 也返回 0 个结果。我已经调整了问题,以便更清楚地了解我在寻找什么。
  • 啊,那是serialize数据;您不能真正在 SQL 中安全地使用它,因为当结构更改和添加数字时,您会得到误报。此外,以这种方式很难在 SQL 中的多个位置找到多个字符串。我会用解决方案更新问题,但我不建议这样做。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-27
  • 2022-11-14
  • 1970-01-01
相关资源
最近更新 更多