【问题标题】:Custom WordPress SQL query to output metadata based on post ID - php, database (custom post type&fields)自定义 WordPress SQL 查询以根据帖子 ID 输出元数据 - php、数据库(自定义帖子类型和字段)
【发布时间】:2016-06-27 17:08:46
【问题描述】:

我正在从另一个 Wordpress 数据库运行数据库查询,因此使用标准 sql 查询而不是各种 wordpress 函数。

基本上,我想显示与 postID 关联的所有元值/数据。我已经使用自己的自定义字段(开始日期等)设置了一个客户帖子类型“事件”。

我几乎拥有我需要的一切,我只需要编写适当的 php 循环来输出每个帖子 ID 的数据(以显示帖子的元数据)。

Table Structure Image

注意:meta_values 可以为 null,以后可能会添加更多的 meta_keys。

$newdb = //already setup new db connection (don't worry about this)
$query =
                "
                    SELECT * 
                    FROM wp_posts, wp_postmeta
                    WHERE wp_posts.ID = wp_postmeta.post_ID
                    AND wp_postmeta.meta_key NOT LIKE '\_%'   
                    AND wp_posts.post_type='event' 
                    AND wp_posts.post_status = 'publish';
                " ;  


$events = $newdb->get_results($query, OBJECT);
//get_results() is a wordpress function, nearly equiv to my_sqli
//OBJECT - result will be output as an object.
//ARRAY_A - result will be output as an associative array.


foreach ( $events as $event ) {
echo $event->post_title;
echo $event->meta_value;    
}

当前结果:

Title_1,2016 年 11 月 2 日

Title_1,05:00

Title_1,2016 年 12 月 1 日

Title_2,2016 年 5 月 2 日


**期望结果:**(针对每个帖子)

(结构上):

post_ID: 1, post_title: Title_1, start_date: 11/02/2016, start_time: 05:00, end_date: 12/01/2016

$event->post_title;
$event->meta_value”;  //meta_key = start_date
$event->meta_value”;  //meta_key = end_time
$event->meta_value”; //meta_key = end_date

(视觉上)

标题_1, 2016 年 11 月 2 日, 05:00, 2016 年 12 月 1 日,

标题_2, 2016 年 5 月 2 日, 07:00, 2016 年 7 月 2 日,

【问题讨论】:

    标签: php mysql wordpress pivot-table associative-array


    【解决方案1】:

    我最终创建了自己的旋转 php 循环,它检查每个结果数组(来自 SQL 查询)并根据帖子的 ID 将其分组到另一个关联数组中。一切工作得非常好,我可以将每个帖子的元值放在要显示的适当 HTML 标记中。

    这是我选择自定义帖子类型(“事件”)和自定义字段(存储在元键值对中)的完整工作代码:

    //credentials can be found in your wp-config.php file
    $newdb = new wpdb('DB_USER', 'DB_PASSWORD', 'DB_NAME', 'DB_HOST');
    
    //sql query
    $querystr =
            "
            SELECT wp_posts.ID, wp_posts.post_title, wp_postmeta.meta_key, wp_postmeta.meta_value
            FROM wp_posts, wp_postmeta
            WHERE wp_posts.ID = wp_postmeta.post_ID
            AND wp_postmeta.meta_key NOT LIKE '\_%'
            AND wp_posts.post_type='event'
            AND wp_posts.post_status = 'publish';
            " ;
    
    //wordpress function that returns the query as an array of associative arrays
    $results = $newdb->get_results($querystr, ARRAY_A);
    
    //create an empty array
    $events = array();
    foreach ($results as $row) {
        //if row's ID doesn't exist in the array, add a new array
        if (!isset($events[$row['ID']])) {
            $events[$row['ID']] = array();
        }
        //add all the values to the array with matching IDs
        $events[$row['ID']] = array_merge($events[$row['ID']], array('post_title'=>$row['post_title']), array($row['meta_key']=>$row['meta_value']));
    }
    
    //extract data from each event
    foreach ($events as $event) {
        var_dump($event); //do something
        echo $event['start_date']; //can also echo specific metavalues etc.
    }
    

    【讨论】:

    • 很棒的解决方案!
    • 您还可以根据日期和时间对 $events 数组进行排序,只需将其放在用于提取数据的 foreach 循环之上:/*-------sort array based on event start date and time------*/ foreach ($events as $key => $row) { $start_date[$key] = $row['event_start_date']; $start_time[$key] = $row['event_start_time']; } array_multisort($start_date, SORT_ASC, $start_time, SORT_ASC, $events);
    【解决方案2】:

    您正在尝试做的是 SQL 中一个臭名昭著的痛苦,因为 wp_postmeta 是一个键值存储。 所有元数据是痛苦的部分。

    很难将键值存储项转换为结果集中它们自己的列,以允许在添加新键值时出现新列。

    专业提示:SELECT * 在尝试做这种事情时不是你的朋友。

    如果您提前了解元数据项会更容易。例如,如果您知道需要用于 startdate、endtime 和 enddate 的列,则可以这样做。

     SELECT wp_posts.*, 
            a.meta_value start_date, 
            b.meta_value end_time,
            c.meta_value end_date
       FROM wp_posts
       LEFT JOIN wp_postmeta a ON wp_posts.ID = a.post_ID AND a.meta_key='start_date'
       LEFT JOIN wp_postmeta b ON wp_posts.ID = b.post_ID AND a.meta_key='end_time'
       LEFT JOIN wp_postmeta c ON wp_posts.ID = c.post_ID AND a.meta_key='end_date'
      WHERE wp_posts.post_type = 'event' etc etc
    

    我在这里建议LEFT JOIN,因为如果您使用普通的内部JOIN,任何缺少元数据值的帖子都将从结果集中被抑制。 LEFT JOIN 允许它们以 NULL 值出现在结果集中。

    如果你必须做 所有元数据 的事情,你需要在你的 php 代码中做很多格式化。您首先要找出不同的元数据项:

     SELECT DISTINCT wp_metadata.meta_key
       FROM wp_posts
       JOIN wp_postmeta ON wp_posts.ID = wp_postmeta.post_ID
      WHERE wp_posts.post_type = 'event'  etc etc
    

    然后,您将在 php 中构建一个适合存储为每个 meta_key 值命名的列的数据结构。 (解释这超出了 SO 答案的范围)。

    接下来,您将运行与问题中类似的查询,并使用它在 php.ini 中填充您的数据表。最后,您将显示表格。

    这种通用操作类型的术语是旋转您的表。在一般情况下,在 MySQL 中很难做到。

    【讨论】:

    • Ollie 非常感谢您的详细回复!我将尝试 LEFT JOIN 方法并让你知道它是怎么回事。旋转看起来也很有希望。我发现找到不同元数据键的一种方法是使用: wp_postmeta.meta_key NOT LIKE '_%' (wordpress 每个元键创建 3 行,出于我的目的,2 个不必要的行以字符 _ 开头,因此在查询中排除它们) .
    猜你喜欢
    • 1970-01-01
    • 2014-03-17
    • 1970-01-01
    • 1970-01-01
    • 2018-08-02
    • 1970-01-01
    • 2017-01-03
    • 2023-04-03
    • 2013-06-11
    相关资源
    最近更新 更多