Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I want to loop all posts to do some processing, but one of my concern is there are many posts and it might used up my memory, so I want to loop posts with offset, something like paging.

e.g.

$posts = get_posts(array('post_status' => 'publish', 'posts_per_page' => -1));

foreach ($posts as $post) {
  // Huge memory requirement as $posts might be huge
}

Any recommended way to do it?

share|improve this question
1  
get_posts also accepts the offset parameter, just add it in your array along with post_status & posts_per_page, or maybe i didn't understand the question? –  Mridul Aggarwal Dec 16 '12 at 15:18
    
Yes we can, just want to check if there is standard way to handle large posts in wordpress before throwing out my own implementations. –  Howard Dec 19 '12 at 7:49

1 Answer 1

Call a external script: Your function look like this:

<?php    
function modify_posts() {
    $number_posts = 10;
    $offset = 0;
    $success = 'success';

    while ( 'success' === $success ) {

        $url = add_query_arg(
                array(
                    'num' => $number_posts,
                    'off' => $offset,
                    'abs' => urlencode( ABSPATH )
                    ),

                    plugins_url( 'remote_get.php', __FILE__ )

        );

        $response = wp_remote_get( $url );

        if ( ! is_wp_error( $response ) ) {

            $success = json_decode( $response['body'] );

            if ( 'success' != $success ) {
                // something went wrong in remote_get.php
            }

        } else {
            // wp_remote_get() throws an error...
        }

        $offset += $number_posts;

        printf( "%d -> %s<br>", $offset, $success );

    }

}

remote_get.php

<?php
$offset = filter_input( INPUT_GET, 'off', FILTER_SANITIZE_NUMBER_INT );
$number_posts = filter_input( INPUT_GET, 'num', FILTER_SANITIZE_NUMBER_INT );
$abspath = urldecode( filter_input( INPUT_GET, 'abs', FILTER_SANITIZE_URL ) );

require_once $abspath . 'wp-load.php';

$posts = get_posts(
        array(
                'post_status' => 'publish',
                'posts_per_page' => $number_posts,
                'offset' => $offset
                )
        );


if ( ! empty( $posts ) ) {

    foreach ( $posts as $post ) {

        // do wired things here

        $result = 'success';

    }

} else {

    $result = 'posts_ended';

}

header( 'Content-Type: application/json' );

die( json_encode( $result ) );
share|improve this answer
    
This is not a very good way because the remote_get.php file can be accessed from anywhere even for unauthorized people, the code will not show draft and private content because you don't pass cookies, and you use two apache processes to serve one request. –  Mark Kaplun Dec 17 '12 at 5:43
    
@MarkKaplun Your whole comment is pointless. Securing a plugin against unauthorized access is a basic knowledge. I did not explain the basics in every answer, I assume that every serious developer has this basic knowledge and know the four or five ways to make his plugin secure. Code snippets, and answers are such, should never be used unmodified in production enviroment. They are only starting points for developing or a step into the right direction. If you don't have sufficient knowledge about securing your plugin, please do not downvote an answer. –  Ralf912 Dec 17 '12 at 8:46
    
@MarkKaplun Every ajax request do the same. And i never heard that an ajax request is inefficient. The only thing I missed is to use define( 'SHORT_INIT', true ); Please read the question agian. Only published posts are requested. No drafts and no private posts. There is no need for cookies. If private posts or drafts are requested, the same code could be wrapped in an ajax request. BTW: I miss your answer. Wasting time with pointless critic did not help anyone. –  Ralf912 Dec 17 '12 at 8:54
    
if this is supposed to be ajax then you need to use the ajax API fully, no reason to put on the net not secured code without even commenting that this is just a not very secure idea. But it is not ajax really 1. because you lose the cookie based authentication that AJAX calls inherit by default 2. Your main thread is not running in a browser but on the server, so you have one apache process basically calling another and waiting till the other will finish. with AJAX the main process runs on the browser not your server. You could simply include remote_get.php with better results –  Mark Kaplun Dec 17 '12 at 9:37

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.