WordPressでwp_insert_post()を使って記事データを一括投稿する方法

WordPressでwp_insert_post()を使って記事データを一括投稿する方法

Photo Andreas Rønningen via Unsplash

WordPressで記事データを一括投稿するにはいくつか方法があります。

まず思いつくのはSQLでデータベースに直接投稿する方法です。しかし、WordPressの投稿データは複数のテーブルに分かれているため、更新するテーブルが多岐にわたり、それなりに面倒な作業になります。

プラグインを使った方法としては「WP All Import」などが有名ですが、一部機能が有料だったり、柔軟性に欠けます。

そこで、覚えておきたいのが、WordPressの関数wp_insert_post()を使う方法です。

WordPressには記事データ投稿用の関数wp_insert_post()が用意されており、この関数を使うことで簡単に記事データの一括投稿が可能になります。

WordPress中級者以上の方は、wp_insert_post()を使った記事データの一括投稿を覚えておくと、大量の記事データを投稿したり、サイトを移転、統合するときに便利です。

WordPress一括操作系の便利テクニック

WordPressでwp_insert_post()を使って記事データを一括投稿する方法

記事データは下記のような配列で用意します。postmetaはカスタムフィールドを使用している場合などに設定します。

// 記事データを用意
$posts_data = array(
  // 1記事目
  array(
    'title' => 'テストタイトル1', // 記事タイトル
    'content' => 'テスト本文1', // 記事本文
    'post_name' => 'スラッグ名1', // スラッグ
    'category' => array(1,2), // カテゴリID(配列)
    'tags' => array('タグ1','タグ2'), // タグの名前(配列)
    'status' => 'publish', // 公開ステータス
    // postmetaのキーと値
    'postmeta' => array(
      array('key1', '値1'),
      array('key2', '値2')
    )
  ),
  // 2記事目
  array(
    'title' => 'テストタイトル2', // 記事タイトル
    'content' => 'テスト本文2', // 記事本文
    'post_name' => 'スラッグ名2', // スラッグ 
    'category' => array(1,2), // カテゴリID(配列)
    'tags_input' => array('タグ1','タグ2'), // タグの名前(配列)
    'status' => 'publish', // 公開ステータス
    // postmetaのキーと値
    'postmeta' => array(
      array('key1', '値1'),
      array('key2', '値2')
    )
  )
);

PHPファイル全体は下記のようになります。

記事データ「$posts_data」ごとに展開し、wp_insert_post()関数で記事データを作成し、update_post_meta()関数で作成した記事のpostmetaをセットします。

<?php
require_once( dirname( __FILE__ ) . '/wp-load.php' );

//実行時間の制限値を解除する
set_time_limit(0);

// ユーザーID
$post_author = 1;

// 記事データを用意
$posts_data = array(
  // 1記事目
  array(
    'title' => 'テストタイトル1', // 記事タイトル
    'content' => 'テスト本文1', // 記事本文
    'post_name' => 'スラッグ名1', // スラッグ 
    'category' => array(1,2), // カテゴリID(配列)
    'tags' => array('タグ1','タグ2'), // タグの名前(配列)
    'status' => 'publish', // 公開ステータス
    // postmetaのキーと値
    'postmeta' => array(
      array('key1', '値1'),
      array('key2', '値2')
    )
  ),
  // 2記事目
  array(
    'title' => 'テストタイトル2', // 記事タイトル
    'content' => 'テスト本文2', // 記事本文
    'post_name' => 'スラッグ名2', // スラッグ 
    'category' => array(1,2), // カテゴリID(配列)
    'tags_input' => array('タグ1','タグ2'), // タグの名前(配列)
    'status' => 'publish', // 公開ステータス
    // postmetaのキーと値
    'postmeta' => array(
      array('key1', '値1'),
      array('key2', '値2')
    )
  )
);

//カウント
$i = 0;

// 記事データごとに展開
foreach($posts_data as $key => $post){

  //投稿日時(日本時刻に合わせて投稿ごとに1秒ずつずらす)
  $date = date('Y-m-d H:i:s', strtotime('+'.$i + (9 * 60 * 60).'second'));

  // 記事データを作成
  $post_value = array(
    'post_author' => $post_author, // 投稿者のID
    'post_title' => $post[title],// 投稿のタイトル
    'post_name' => $post[slug], // スラッグ 
    'post_content' => $post[content], // 投稿の本文
    'post_category' => $post[category], // カテゴリーID(配列)
    'tags_input' => $post[tags], // タグの名前(配列)
    'post_status' => $post[status], // 公開ステータス
    'post_type' => 'post', // 投稿タイプ
    'post_date' => $date // 投稿の作成日時
  );
  $insert_id = wp_insert_post($post_value); //$insert_idには投稿のID(「wp_posts」テーブルの「ID」)が入る。 投稿に失敗した場合は0が返る。

  if($insert_id) {
    // postmetaデータごとに展開
    foreach($post[postmeta] as $key => $postmeta){
      // post_metaを作成
      update_post_meta($insert_id, $postmeta[0], $postmeta[1]);
    }// postmetaのループ終了

    // 記事データの作成に成功した場合の処理
    echo ($i + 1).'件目の記事データの作成に成功しました。 '.$post[title].' '.$date.'<br>';

  } else {
    // 記事データの作成に失敗した場合の処理
    echo ($i + 1).'件目の記事データの作成に失敗しました。 '.$post[title].' '.$date.'<br>';
  }

  $i++;

} // 記事データのループ終了

?>

上記のPHPファイルを、WordPressをインストールしているディレクトリにアップロードします。アップロードしたURLにアクセスすると、記事データの投稿が実行されます。投稿に成功した場合は「1件目の記事データの作成に成功しました。 記事タイトル 2017-05-11 18:16:09」のようなメッセージが表示されます。

先頭のrequire_once( dirname( __FILE__ ) . '/wp-load.php' );でWordPress関数を使う準備をしています。

set_time_limit(0);」を設定しておかないと、件数が多い場合に(感覚的には2000件以上)、途中で記事のインサートが止まってしまうことがあります。

$post_author」には投稿者のユーザーIDを設定します。

$date」で投稿日時を記事ごとに1秒ずつずらしています。投稿日時が重複してしまうと、記事を一覧表示した時の並び順やページネーションがおかしくなることがあるためです。

※投稿日時を1秒ずつ未来にして記事を登録するため、記事数が多いと一部の記事は「予約投稿」状態になります。時間が過ぎても予約投稿が上手く動作しない場合は、SQLでデータベースの投稿ステータスを直接「公開」状態に変更してしまいます。

SELECT文で「投稿状態(post_status)」が「予約投稿(future)」の記事を一覧表示します。

SELECT *
FROM wpx_posts
WHERE post_status = 'future'

UPDATE文で「投稿状態(post_status)」の「予約投稿(future)」を「公開(publish)」に変更します。

UPDATE wpx_posts
SET post_status = 'publish'
WHERE post_status = 'future'

WordPressの公式リファレンスではより細かなオプションも紹介されています。wp_insert_post()を使いこなせると、かなりの時間の節約になるので、大量の記事データを投稿するときは試してみてください。

 参考