Wp_Query中的最大数组长度post__not_in参数

时间:2019-11-10 19:23:28

标签: wordpress post

我正在WordPress上使用一个页面向本地php文件发出发布请求,以方便无限滚动。每次WP_query的参数如下:

$args =  array(
            'post_status' => 'publish',
            'post_type' =>  array( 'post'),
            'post__not_in' => $_POST["LoadedIDs"],
            'posts_per_page' => $numberofResources,
            'orderby'  => 'rand',
            'meta_query' => array(
                array(
                 'key' => 'shares',
                 'value' => 100,
                 'compare' => '>=',
                 'type' => 'numeric',
                ),
            )
    );

LoadedIDs是已获取的ID的列表,因此自然而然地,在每次请求之后,它会变得更长。最终,我注意到我收到了重复的照片。我认为这是由于post__not_in数组长度的限制。有人知道那是什么吗?

2 个答案:

答案 0 :(得分:2)

您应该将此文件配置为查看所需时间。如果您有大量的帖子(比如说5-50k),那么查询可能要花一些时间才能执行,但是对已经加载的帖子进行测试也会很耗时。

此外,我假设加载的ID是从客户端发送的。如果是这种情况,并且帖子数量很多,那么您可能会遇到与将数据从客户端传输到服务器有关的问题。您应该检查$ _POST以确保所有ID都存在。如果ID过多,则可能必须采取诸如在会话中存储加载的ID之类的方法,但是如果处理不当,则会变得混乱。

无论如何,尝试:

$exclude = is_array( $_POST['LoadedIDs'] ) ? $_POST['LoadedIDs'] : [];

// use array keys for faster lookup
$_exclude = array_flip( $exclude );

$all_posts = get_posts( [
    'post_status'    => 'publish',
    'post_type'      => [ 'post' ],
    'posts_per_page' => - 1,
    'orderby'        => 'rand',
    'meta_query'     => array(
        array(
            'key'     => 'shares',
            'value'   => 100,
            'compare' => '>=',
            'type'    => 'numeric',
        ),
    )
]);

// get the next X number of posts.
$next_posts = array_slice( array_filter( $all_posts, function ( $p ) use( $_exclude ){
    return ! isset( $_exclude[$p->ID] );
} ), 0, $numberofResources );

答案 1 :(得分:2)

  

我认为这是由于数组长度的限制   发表__not_in。有人知道那是什么吗?

我不这么认为,在一个包含1700多个帖子+页面的网站上进行的书面基本测试来测试此案,并且没有发现重复项

这是我的代码:

add_action('wp_footer', function() {
    $allPosts = get_posts([
        'post_status'    => 'publish',
        'post_type'      => ['post', 'page'],
        'posts_per_page' => -1,
        'orderby'        => 'rand'
    ]);
    $totalPostCount = count($allPosts);

    $duplicatesFound = false;
    $loadedIds = [];
    while (!$duplicatesFound && count($loadedIds) < $totalPostCount) {
        $args = array(
                'post_status' => 'publish',
                'post_type' =>  array('post', 'page'),
                'post__not_in' => $loadedIds,
                'posts_per_page' => 100,
                'orderby'  => 'rand',
        );

        $posts = get_posts($args);
        $postIds = wp_list_pluck($posts, 'ID');

        $loadedIds = array_merge($loadedIds, $postIds);
        $uniqueIds = array_unique($loadedIds);
        if (count($uniqueIds) < count($loadedIds)) {
            $duplicatesFound = true;
        }
    }


    var_dump($duplicatesFound);
    var_dump($totalPostCount);
    var_dump(count($loadedIds));
    var_dump(count($uniqueIds));
    var_dump($loadedIds);
    var_dump($uniqueIds);
    die();
});

如果您有1700多个帖子,则可能不足以在我的测试中重现该问题,在这种情况下,我建议您自己运行上面的代码来确定。

假设您已经验证$_POST["LoadedIDs"]包含有效的ID数组(不是逗号分隔的字符串)。 我最好的猜测是您的数据在POST中丢失/中断,为验证这一点,您可以尝试Joal M's solution。如果那不能解决您的问题,这将确认您的数据已在POST中丢失。

要解决此问题,您可以尝试增加一些ini设置:

max_post_size = 100M
max_input_vars = 3000
suhosin.post.max_vars = 3000
suhosin.request.max_vars = 3000

max_input_vars很可能是罪魁祸首,因为默认情况下此限制为1000。

另一种选择是不将ID的内容从客户端传递回来,而是将它们存储在服务器上,也许也像Joal M那样在会话中存储,但是我将其保存作为最后的手段。