スポンサーリンク

WP-CLIを使って記事を自動投稿する(失敗談)の続き

前回の記事の件ですが、やはりwp-cliを使ってphpのバッチプログラムを作ること自体が誤っていました。wp-cliを使って記事を自動投稿するのであればphpは一切使用せずbashスクリプトとするべきかと思います。結局作成していた自動投稿バッチはwp-cliを一切使わない形に修正しました。
以下備忘録になります。

wp post createコマンドについて

wp post createコマンドで空記事を作成し出力からpost_idを抽出する件について。
ドキュメントを見直したらpost_idのみを返すという–porcelainというオプションがあることがわかりました。
もし、bashスクリプトで自動投稿のプログラムを作るとしたら以下のような感じになると思います。

POST_ID="$(wp post create --post_title=hoge --porcelain)"

なお、wp media importコマンドも同様の–porcelainオプションが存在するので以下のような感じで画像IDを取得できると思います。

ATTACHMENT_ID="$(wp media import [image file path] --porcelain)"

バッチ側からのDB接続について

DBへの接続についてwp-cliの方でもサポートされており、先日の時点では以下のような感じでDB内に独自に追加したproductsテーブルを検索していました。

/**
 * WordPress上で商品が登録済みかチェックする
 */
function check_product_exist($item) {

  // wp dbでテーブルを検索(枠線とカラム名を非表示にし、idの値のみ取得)
  unset($output, $return_var);
  exec("cd " . WP_DIR . " " . EXEC_AND . " wp db query \"select id from products where product_id='{$item['product_id']}'\" --silent --skip-column-names", $output, $return_var);

  // 商品が存在する場合はtrueを返す
  if (!empty($output)) {
    echo "product_id : " . $item['product_id']." is exists. skipping.\n";
    return true;
  }

  // 商品情報を追加して正常ステータスを返す
  unset($output, $return_var);
  exec("cd " . WP_DIR . " " . EXEC_AND . " wp db query \"insert into products (product_id, link) values ('{$item['product_id']}', '{$item['url']}')", $output, $return_var);
  return false;
}

これは以下のようにwpdbというクラスを呼び出すことでwp-cliを使わない形に修正できました。

/**
 * WordPress上で商品が登録済みかチェックする
 */
function check_product_exist($item) {
  global $wpdb;
  $other_wpdb = new wpdb($wpdb->dbuser, $wpdb->dbpassword, $wpdb->dbname, $wpdb->dbhost);

  // wpdbでテーブルを検索
  $results = $other_wpdb->get_results($wpdb->prepare("SELECT id FROM products WHERE product_id = %s", $item['product_id']));

  // 商品が存在する場合はtrueを返す
  if (!empty($results)) {
    echo "product_id : " . $item['product_id']." is exists. skipping.\n";
    return true;
  }

  // 商品情報を追加して正常ステータスを返す
  $insert_data = [
    'product_id' => $item['product_id'],
    'link' => $item['url'],
  ];
  $other_wpdb->insert("products", $insert_data);
  return false;
}

バッチ側からのカテゴリー登録について

WordPressにはカテゴリーを追加するwp_insert_categoryという関数がありますが、この関数はwp-load.phpを読み込んだだけだと使えませんでした。
taxonomy.phpというファイルの読み込みが必要でした。
php – Why wp_insert_category is not available inside My Custom Page? – Stack Overflow

if (file_exists (ABSPATH.'/wp-admin/includes/taxonomy.php')) {
  require_once (ABSPATH.'/wp-admin/includes/taxonomy.php');
}

画像のインポートにかかる時間について

プログラムからwp-cliを取り除く過程でwp-cliでコマンドラインから画像のインポートを行ったときと、画像の取り込みを行う関数を利用したときの処理時間を計測しました。
wordpressには標準で外部URLの画像をインポートする処理はなさそうでしたので、検索して見つけた以下のプログラムを使っています。
WP: Insert attachment from URL

$time_start = microtime(true);

// wp-cli
unset($output, $return_var);
exec("cd {$_(WP_DIR)} {$_(EXEC_AND)} wp media import {$url} --post_id={$post_id}", $output, $return_var);

$time = microtime(true) - $time_start;
var_dump($time);
// float(1.9746830463409)


$time_start = microtime(true);
// php function
crb_insert_attachment_from_url($url, $post_id);

$time = microtime(true) - $time_start;
var_dump($time);
// float(1.0672359466553)

結果はwp-cliで1.97秒、phpの関数の方は1.06秒という結果でした。wp-cliは実行したコマンドをパースしてwordpressの関数を呼び出しているので直でphpの関数を呼び出しているものに比べると当然遅くなりますが思ってたより差が大きかった。

その他

wp-cliを以前作成したLAMP環境を作成するAWSのCloudFormationのテンプレートに組み込むことで、スタック立ち上げ時にWordPressが使える状態になっている環境を作ったりできそう。

タイトルとURLをコピーしました