web-dev-qa-db-fra.com

get_posts/WP_Query Taille de la mémoire de 134217728 octets épuisés

Je souhaite obtenir tous les identifiants de publication de mes pages de produits. Mais soit la première façon, soit la deuxième manière sont réussies ...

Je reçois toujours:

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

Première manière:

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);

Deuxième manière:

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);

Est-ce que quelqu'un sait où est mon échec et comment je peux y remédier? Je souhaite simplement obtenir tous les identifiants de publication de mes publications de produit.

Salutations et merci!

4
Jan
  1. Si tout ce que vous voulez, c'est imprimer un identifiant dans un fichier, vous pouvez écrire une requête personnalisée pour celui-ci. De cette façon, vous pourrez éviter certains traitements internes que WordPress fait.

  2. Beaucoup de messages peuvent épuiser votre RAM, bien que je ne pense pas que le simple fait de choisir un ID de 2100 messages devrait vraiment engloutir 134 Mo de RAM. Faites juste le calcul, ID peut être sauvegardé dans seulement 1 octet, mais disons que cela prend 4 octets. Toujours, 2100 x 4 = 8400 octets = 8,4 KB. Évidemment, PHP a besoin de plus de mémoire interne pour traiter, créer des objets, etc. Mais avec 134 Mo de mémoire, je pourrais facilement traiter quelques centaines de milliers d’ID. Donc, évidemment, vous vous trompez ailleurs.

Quoi qu'il en soit, pour quelque raison que ce soit (vous devrez peut-être tout sélectionner dans product, pas seulement ID), vous pouvez segmenter la requête avec des limites. Comme le code suivant:

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 cette façon, PHP ne gérera que le nombre maximal de lignes $limit, de sorte que la limite de mémoire ne doit pas dépasser.

Remarque: ne jamais concaténer pour créer de très longues chaînes (comme MB long), écrivez immédiatement dans le fichier avant qu'il ne soit trop long. Cela peut produire un certain retard I/O, mais cela n'épuise pas la limite de mémoire.

4
Fayaz