ブルーシュ

IT技術の勉強記録

ホーム > Tips > WordPress

WordPressのcsv読込・wp_insert_postが遅いとき

csv読み込みなどして、wp_insert_post()を動かしているとき。投稿数が増えるにつれて、遅くなってしまって困りました。

そんなとき見つけたこちらのページ。
wp insert post - Faster way to wp_insert_post & add_post_meta in bulk - WordPress Development Stack Exchange

【下書き】で投稿する

wp_insert_post()をするとき、post_statuspublishにすると、投稿スラッグを自動で付ける作業が発生するため、遅くなります。
※特に同じタイトルで何件も投稿する場合。

注意

あとから「公開」に変更する作業が必要なのはもちろんのこと、get_posts()で取得する場合にも注意が必要です。post_statusがデフォルトでpublishになっているため、下書き状態の投稿を取得するには

<?php
$args = array(
	"post_status" => "draft"
);
$posts = get_posts($args);

と明示する必要があります。

タームとコメントのカウント機能を一時的にオフにする

wp_defer_term_counting() | Function()
wp_defer_comment_counting() | Function()

trueにすると、タームとコメントのカウント機能をオフできます。処理プログラムの最初にtrueにして、最後にfalseにします。これにより、処理速度をスピードアップさせることできます。

サンプルコード

data.csvの例

p-0001,5000,すごい薬草
p-0002,7000,スーパー薬草
p-0003,9000,デラックス薬草
<?php
wp_defer_term_counting( true );
wp_defer_comment_counting( true );

//テーマフォルダ内のCSVファイルを読み込む
$file = new SplFileObject(get_theme_file_path("data.csv"));
$file->setFlags(SplFileObject::READ_CSV);

while(!$file->eof()) {

	//現在行データを取得
	list($product_id, $price, $product_name) = $file->current();

	//※データチェックする

	// 投稿オブジェクトを作成
	$my_post = array(
		'post_title'	=> '投稿タイトル',
		'post_content'	=> '本文',
		'post_status'	=> 'draft'
	);

	// 投稿をデータベースへ追加
	wp_insert_post( $my_post );

	$file->next();
}

wp_defer_term_counting( false );
wp_defer_comment_counting( false );

重複チェックをする場合

上のサンプルコードのように、例えば商品データを投稿しているとき、投稿IDとは別に商品IDを重複させたくない場合。
1件ずつget_posts()してチェックしてたんですが、投稿数が増えると時間がかかります。

<?php
wp_defer_term_counting( true );
wp_defer_comment_counting( true );

$file = new SplFileObject($csv_path);
$file->setFlags(SplFileObject::READ_CSV);

//50行ずつ処理する
$max = 50;

while(!$file->eof()) {
	//現在行
	$current_line = $file->key();

	//func関数内で50行ずつ処理
	func($file, $max);

	//50行進める
	$file->seek($current_line + $max);
}


function func($file, $max){

	$new_post_data = $product_ids = array();
	$cnt = 0;

	// ファイル取得してデータ作成
	while(!$file->eof() && $cnt < $max) {

		//何行進んだかカウント
		$cnt++;

		//現在行データを取得
		list($product_id, $price, $product_name) = $file->current();

		/*ここでデータチェックする*/

		//投稿用データを作成
		$new_post_data[$product_id] = array(
			"post_data"	=> array(
				"post_title"	=> $product_name,
				"post_content"	=> "",
				"post_status"	=> "draft"
			),
			"meta_data"	=> array(
				"product_id"	=> $product_id,
				"price"			=> $price
			)
		);

		//重複チェック用
		$product_ids[] = $product_id;

		$file->next();
	}

	//同じ商品IDを持つ投稿を探す
	$args = array(
		"post_status"	=> array("private", "draft"),
		"meta_key"		=> "product_id",
		"meta_value"	=> $product_ids,
		"meta_compare"	=> "IN"
	);
	if($posts = get_posts($args)){
		foreach($posts as $post){
			$exist_post_id = $post->ID;
			$exist_product_id = get_field("product_id", $exist_post_id);

			//この商品IDは投稿済みなので投稿用データから削除
			unset($new_post_data[$exist_product_id]);
		}
	}


	//投稿していく
	foreach($new_post_data as $product_id => $data){

		// 投稿をデータベースへ追加
		$new_post_id = wp_insert_post($data["post_data"]);
		if(!$new_post_id){
			continue;
		}
		//カスタムフィールドを更新
		foreach($data["meta_data"] as $key => $value){
			update_post_meta($new_post_id, $key, $value);
		}
	}
}

wp_defer_term_counting( false );
wp_defer_comment_counting( false );

50行ずつ読み込んで処理するとタイムアウトすることがなくなりました。

WordPressのcsv読込・wp_insert_postが遅いとき #WordPress #ウェブデザイン #ウェブ制作 #WEBデザイン #WEB制作 #csv

作者の似顔絵

プログラミング歴19年🌈調べたことをブログにまとめていきます。
記事の感想・質問・間違い指摘などはツイッター ( @blooshcompany ) へお願いします。

秋田のウェブ活用をサポート

ホームページを自作してコスト削減!秋田の事業者は無料で利用できます。
ネットショップ・WordPress・SEO対策などさまざまなお悩みをサポートします。

その他、フロントエンド案件のご依頼はインフォメーション

秋田市 レンタル着物 笹パンダ堂のバナーリンク