3

csv ファイルからエントリをインポートし、それらをワードプレスのカスタム投稿として挿入するスクリプトに問題があります (各行は単一の投稿です)。 ...私が収集したものから、問題はグローバル変数がキャッシュされておらず、インスタンスを呼び出すたびに、プロセスがメモリを使い果たしてクラッシュするまで、より多くのメモリが消費されることでした...そのため、クラスを削除して設定しました以下のコードで説明されているように、インポート機能をアップします。

このセットアップで、最大 17,000 の投稿で問題なく動作するようになりましたが、それよりも多くの投稿をインポートしようとすると、エラーなしでドロップアウトします (私の php エラーログまたはwordpress debug.log ファイル)

スクリプトは、エコー情報を出力する 17k の投稿を正常に挿入し、「残りの XXX アイテム」で途中で停止し、その時点で何も出力せずにページの読み込みを終了します...最終echo "Done!";ステートメントに到達することはありません.. .

これは、localhost 開発環境とホストされた開発サーバーの両方で発生します。私はメモリ使用量に注意を払っていましたが、ローカルホストで 60% を超えることはなく (~50% から開始)、メモリリークを示す段階的なメモリ上昇は見られません...

また、 ini_set('memory_limit', '64M'); を使用しようとしました。および set_time_limit(0);

これに関する他の同様の質問で私が読んだことから、

  • SQL 20k エントリは大したことではないはずです
  • サーバーが十分に強力な場合、ワードプレスもこれを処理できるはずです

このスクリプトをこの規模で機能させるには、以下のコードに対してどのような最適化/改善を行うことができますか?

または、おそらくワードプレスの組み込み機能をスキップし、fancypants here で言及されているように LOAD DATA INFILE ですべてを処理します

提供されたワードプレス機能を介してデータを処理したいと思います。

csv ファイルは 1 メガバイトまでです...

コード:


これらの関数は独自のファイル - import.php にあります。

function fileupload_process() {
  ini_set('memory_limit', '64M');
  set_time_limit(0);
  $uploadfiles = $_FILES['uploadfiles'];
  if (is_array($uploadfiles)) {
    foreach ($uploadfiles['name'] as $key => $value) {
      // look only for uploaded files
      if ($uploadfiles['error'][$key] == 0) {
        $filetmp = $uploadfiles['tmp_name'][$key];
        if (($handle = fopen($filetmp, "r")) !== FALSE) {
          $flag = true;
          $songs = explode("\n",file_get_contents($filetmp));
          $count = count( $songs );
          unset($songs);
          echo "Total item count: " . $count . "<BR />";
          // typical entry: If You Have To Ask,Red Hot Chili Peppers,0:03:37, Rock & Alternative,1991,on
          // using a generous 1000 length - will lowering this actually impact performance in terms of memory allocation?
          while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
            // Skip the first entry in the csv containing colmn info
            if($flag) {
                      $flag = false; 
              echo "<BR />"; 
              $count--; 
              continue; 
            }
            // insert the current post and relevant info into the database
            $currently_processed = process_custom_post($data, $count);
            $count--;
          }
          echo "Done!";
          fclose($handle);
        }
        unlink($filetmp); // delete the temp csv file
      }
    }
  }
} // END: file_upload_process()
function process_custom_post($song, $count) {
  $track =  (array_key_exists(0, $song) && $song[0] != "" ?  $song[0] : 'N/A');
  $artist = (array_key_exists(1, $song) && $song[1] != ""  ?  $song[1] : 'N/A');
  $length = (array_key_exists(2, $song) && $song[2] != ""  ?  $song[2] : 'N/A');
  $genre = (array_key_exists(3, $song) && $song[3] != ""  ?  $song[3] : 'N/A');
  $year = (array_key_exists(4, $song) && $song[4] != ""  ?  $song[4] : 'N/A');
  $month = (array_key_exists(5, $song) && $song[5] != ""  ?  $song[5] : 'N/A');
  $playlist = (array_key_exists(6, $song) && $song[6] != ""  ?  $song[6] : '');
  $custom_post = array();
  $custom_post['post_type'] = 'songs';
  $custom_post['post_status'] = 'publish';
  $custom_post['post_title'] = $track;
  echo "Importing " . $artist  . " - " . $track . " <i> (" . $count ." items remaining)...</i><BR />";
  $post_id = wp_insert_post( $custom_post );
  $updated = update_post_meta($post_id, 'artist_name', $artist);
  $updated = update_post_meta($post_id, 'song_length', $length);
  $updated = update_post_meta($post_id, 'song_genre', $genre);
  $updated = update_post_meta($post_id, 'song_year', $year);
  $updated = update_post_meta($post_id, 'song_month', $month);
  $updated = update_post_meta($post_id, 'sample_playlist', $playlist);
  return true;
} // END: process_custom_post()
function import_page () {
//HTML for the import page + the file upload form
  if (isset($_POST['uploadfile'])) {
    fileupload_process();
       }
}

import.php は、プラグインのクラス外の wordpress プラグインに含まれています

つまり、インポートページでスクリプトを取得する方法に関する関連情報は次のとおりです。

define( 'MY_PLUGIN_ROOT' , dirname(__FILE__) );
include_once( MY_PLUGIN_ROOT . 'import.php');
class my_plugin () {
 function __construct() {
  add_action( 'init', array( &$this, 'admin_menu_init' ) );
 }
 function admin_menu_init() {
   if(is_admin()) {
     //Add the necessary pages for the plugin
     add_action('admin_menu', array(&$this, 'add_menu_items'));
   }
 }
 function add_menu_items() {
  add_submenu_page( 'edit.php?post_type=songs', 'Import Songs', 'Import Songs',  'manage_options', 'import-songs', 'import_page' );
 }
}

ご意見、ご感想、ご提案をいただければ幸いです。

4

1 に答える 1