通过 WordPress 获取随机帖子 API

Get random posts through WordPress API

我正在构建一个自测项目,它可以一次从问题列表中给出 10 个问题。我希望每次开始测试时这 10 个问题都应该不同。前端是 React,后端是 WordPress,使用 WordPress API。

之前我通过实现 plug-in

在查询中使用 orderby=rand
<?php

/**

 * Plugin Name: REST API - Post list randomize

 * Description: Randomize the content list in REST API passing `orderby=rand` as parameter.

 * Version:     1.0.0

 * Author:      Felipe Elia | Codeable

 * Author URI:  https://codeable.io/developers/felipe-elia?ref=qGTOJ

 */



/**

 * Add `rand` as an option for orderby param in REST API.

 * Hook to `rest_{$this->post_type}_collection_params` filter.

 *

 * @param array $query_params Accepted parameters.

 * @return array

 */

function add_rand_orderby_rest_post_collection_params( $query_params ) {

    $query_params['orderby']['enum'][] = 'rand';

    return $query_params;

}

add_filter( 'rest_post_collection_params', 'add_rand_orderby_rest_post_collection_params' );

它在 2 周前一直运行良好。没有修改任何代码,它就被破坏了。我是用Postman测试的,比如http://localhost/wp/wp-json/wp/v2/questions?per_page=10&orderby=rand。响应是

    "code": "rest_invalid_param",
        "message": "Invalid parameter(s): orderby",
        "data": {
            "status": 400,
            "params": {
                "orderby": "orderby is not one of author, date, id, include, modified, parent, relevance, slug, include_slugs, title."
            }
        }

两周前,如果我使用相同的查询,它可能会给我 10 个随机问题。看起来插件无法像以前一样在 WordPress 中成功添加 rand 作为 orderby 的参数。

顺便说一句,WP 中 orderby=rand 的功能没有被破坏,因为如果我在 WP 核心代码中手动添加 rand 作为参数,上述查询可以再次运行。

有人知道导致问题的插件或 WP 中的某些最新更新有什么问题吗?

另外,我看到一些文章在MySQL中提到ORDERBY = RAND() 会在数据库很大时严重影响性能。所以我想知道我是否应该在查询中使用 orderby=rand 来获得随机问题或考虑其他方法来完成这项工作。有人对此性能问题有任何建议吗?谢谢!

获取独特的问题:

table: wp_question_filter_list

id  ip_address question_list
1   1.21.23    1,2,3,4,5
2   1.21.24    1,4,6,7,8    
3   1.21.25    4,5,6,8,9    



function get_unique_questions($ip_address){
global $wpdb;
$table_name = $wpdb->prefix . 'question_filter_list'; 


$unique_id_list=$wpdb->get_results($wpdb->prepare("SELECT * FROM $table_name WHERE  ip_address=%d",$ip_address), ARRAY_A);


    if (count($unique_id_list) > 0) {
    $question_data=$unique_id_list[0];

    $arr_question=array();
    if(isset($question_data['question_list']) && $question_data['question_list']!=''){
        $arr_old_question_id_list=explode(",",$question_data['question_list']);
    }

$excludes = implode(',', $arr_old_question_id_list);
$arr_question_id_list=$wpdb->get_results($wpdb->prepare("SELECT * FROM $table_name WHERE ip_address='".$ip_address."' AND id NOT IN('".$excludes."') "), ARRAY_A);
set_unique_questions($ip_address,$arr_question_id_list);
}

function set_unique_questions($ip_address,$arr_question_id_list){
    global $wpdb;
    $table_name = $wpdb->prefix . 'question_filter_list'; 
    $unique_id_list=$wpdb->get_results($wpdb->prepare("SELECT * FROM $table_name WHERE  ip_address=%d",$ip_address), ARRAY_A);


    if (count($unique_id_list) > 0) {
    $question_data=$unique_id_list[0];

    $arr_question=array();
    if(isset($question_data['question_list']) && $question_data['question_list']!=''){
        $arr_old_question_id_list=explode(",",$question_data['question_list']);
    }

      if(is_array($arr_question_id_list) && !empty($arr_question_id_list)){     
           foreach($arr_question_id_list as $single_question){
               array_push($arr_question,$single_question);
          }
      }
      $str_question_id_list=implode(",",$arr_question);


   $wpdb->update($table_name, array(
        'question_list' => $str_question_id_list
    ), array(
        'ip_address' => $ip_address
    ));


    }else{

     $str_question_id_list=implode(",",$arr_question_id_list);
     $data = array(
        'ip_address' => $ip_address,
        'question_list' => $str_question_id_list,
    );
     $wpdb->insert($table_name, $data);

   }



$result = $wpdb->insert($table_name, $item);
}

$ip_address=$_SERVER['REMOTE_ADDR'];


$arr_question_list=get_unique_questions($ip_address);

echo "<pre>";
print_r($arr_question_list);

找到答案了。我需要将add_filter函数的第一个参数rest_post_collection_params设为对应的post类型。

rest_post_collection_params为WP默认posts类型。因为我使用ACF(Advanced Custom Fields,另一个创建自定义post类型的插件)来创建我自己的post类型,比如books,我需要将第一个参数更改为 rest_books_collection_params。如果您有更多自定义 post 类型,只需为每个类型创建多达 add_filter 个函数。

只是不知道为什么 3 周前我可以将 rest_post_collection_params 用于所有自定义的 post 类型,但现在不能。反正既然解决了,就别再费心了。我的项目更面向前端。 WP只是存储。

顺便说一句,可能有人注意到 rest_post_collection_params 是 WP 默认 post 类型 posts。在参数中它使用单数形式 post 作为复数形式 posts。这仅适用于 WP default post 类型。对于自定义类型,如果是books,参数应该是rest_books_collection_param;如果 个问题,那么 rest_ 个问题_collection_param。保持参数与post类型完全一致。