it-swarm.com.de

get_posts/WP_Query Speichergröße von 134217728 Bytes erschöpft

Ich möchte alle Post-IDs meiner Produktseiten erhalten. Aber entweder der erste oder der zweite Weg sind erfolgreich ...

Ich bekomme immer:

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

Erster Weg:

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

Zweiter Weg:

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

Weiß jemand, wo mein Fehler ist und wie ich das beheben kann? Ich möchte nur alle Beitrags-IDs meiner Produktbeiträge erhalten.

Grüße und Danke!

4
Jan
  1. Wenn Sie lediglich die ID in einer Datei drucken möchten, können Sie eine benutzerdefinierte Abfrage dafür schreiben. Auf diese Weise können Sie einige interne Verarbeitungsschritte vermeiden, die WordPress durchführt.

  2. Viele Posts können Ihren RAM erschöpfen, obwohl ich nicht der Meinung bin, dass die Auswahl der ID von 2100 Posts wirklich 134 MB RAM verschlingen sollte. Rechnen Sie einfach nach, ID kann in nur 1 Byte gespeichert werden, aber sagen wir, es dauert 4 Byte. Immer noch 2100 x 4 = 8400 Bytes = 8,4 KB. Offensichtlich benötigt PHP mehr internen Speicher zum Verarbeiten, Erstellen von Objekten usw. Aber mit 134 MB Speicher könnte ich problemlos einige hunderttausend IDs verarbeiten. Also machst du offensichtlich woanders falsch.

Wie auch immer, aus welchem ​​Grund auch immer (möglicherweise müssen Sie alles aus product auswählen, nicht nur ID), können Sie die Abfrage mit Einschränkungen segmentieren. Wie der folgende CODE:

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

Auf diese Weise verarbeitet PHP nur die maximale Anzahl von $limit Zeilen, sodass das Speicherlimit nicht überschritten werden sollte.

Hinweis: Niemals verketten, um sehr lange Zeichenfolgen (wie MB long) zu erstellen. Schreiben Sie sofort in die Datei, bevor sie zu lang wird. Es kann zu einer gewissen E/A-Verzögerung kommen, erschöpft jedoch nicht die Speicherkapazität.

4
Fayaz