通过 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类型完全一致。
我正在构建一个自测项目,它可以一次从问题列表中给出 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类型完全一致。