get_posts / WP_Query Tamaño de memoria de 134217728 bytes agotado

4

Quiero obtener todos los ID de publicación de las páginas de mis productos. Pero la primera o la segunda son exitosas ...

Siempre obtengo:

PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 8388616 bytes) in /var/www/vhosts/httpdocs/wp-includes/wp-db.php on line 1842

Primera forma:

if ( ! defined('ABSPATH') ) {
    /** Set up WordPress environment */
    require_once( dirname( __FILE__ ) . '/wp-load.php' );
}

$posts_array = get_posts(array(
            'post_type' => 'product',
            'posts_per_page' => -1
        ));

$myfile = fopen("wp_all_import.txt", "a");

foreach ($posts_array as $value) {
    fwrite($myfile, $posts_array . "\n");
}

fclose($myfile);

Segunda vía:

if ( ! defined('ABSPATH') ) {
    /** Set up WordPress environment */
    require_once( dirname( __FILE__ ) . '/wp-load.php' );
}

$products_IDs = new WP_Query( array(
            'post_type' => 'product',
            'posts_per_page' => -1
        ));
$myfile = fopen("wp_all_import.txt", "a");

while ($products_IDs->have_posts() ) : $products_IDs->the_post();
fwrite($myfile, get_the_ID() . "\n");
endwhile; wp_reset_query();

fclose($myfile);

¿Alguien sabe dónde está mi falla y cómo puedo solucionarlo? Solo quiero obtener todas las ID de las publicaciones de mis productos.

Saludos y gracias!

    
pregunta Jan 05.03.2017 - 13:23

1 respuesta

4
  1. Si todo lo que desea es imprimir ID en un archivo, puede escribir una consulta personalizada para ello. De esa manera, podrá evitar algunos procesamientos internos de WordPress.

  2. Muchas publicaciones pueden agotar tu RAM, aunque no creo que simplemente seleccionar ID de 2100 publicaciones realmente deba consumir 134 MB de RAM. Solo haga los cálculos, ID se puede guardar en solo 1 byte, pero digamos que toma 4 bytes. Aún así, 2100 x 4 = 8400 bytes = 8.4 KB. Obviamente, PHP necesita más memoria interna para procesar, crear objetos, etc. Pero con 134MB de memoria, podría fácilmente procesar unos cientos de miles de ID. Así que, obviamente, estás haciendo algo mal en otra parte.

De todas formas, por el motivo que sea (puede ser que necesite seleccionar todo desde product , no solo ID), puede segmentar la consulta con límites. Como el siguiente CÓDIGO:

if ( ! defined('ABSPATH') ) {
    /** Set up WordPress environment */
    require_once( dirname( __FILE__ ) . '/wp-load.php' );
}
// $limit determines how many rows you want to handle at any given time
// increase / decrease this limit to see how much your server can handle at a time 
$limit = 100;
$start = 0;

// open file handle
$myfile = fopen( dirname( __FILE__ ) . '/wp_all_import.txt', 'a' );

$qry = "SELECT ID FROM '$wpdb->posts' where post_type='post' AND post_status='publish' limit %d, %d";
while( $result = $wpdb->get_results( $wpdb->prepare( $qry, array( $start, $limit ) ) ) ) {
    $write_data = '';
    foreach ( $result as $row ) {
        $write_data = $write_data . $row->ID . "\n";
    }
    // Generally speaking, writing immidiately to the file is better than
    // string concatination, because depending on what you concat and how many times,
    // the generated string may become too big (like MB size string).
    // On the other hand, writing to files thousands of times in a single script may
    // cause I/O delays. So, here I've done a combination of the two to keep both
    // string size & I/O within limits.
    // Adjust this according to your own situation.
    fwrite( $myfile, $write_data );
    $start = $start + $limit;
}

// close file handle
fclose( $myfile );

De esta manera, PHP solo manejará el número máximo de filas $limit , por lo que el límite de memoria no debe cruzarse.

  

Nota: nunca concatene para formar cadenas muy largas (como MB), escriba inmediatamente en el archivo antes de que sea demasiado largo. Puede producir algún retraso de E / S, pero no agotará el límite de memoria.

    
respondido por el Fayaz 05.03.2017 - 15:02

Lea otras preguntas en las etiquetas