【WP】自前のCSVインポート処理の決定版。大量データや多数のカスタムフィールドにも対応。ホームページ制作WORKS制作実績BLOGブログRECRUIT採用情報COMPANY会社概要CONTACTお問い合わせ03-6659-5220WordPress・レスポンシブが得意!ホームページ制作BLOG【WP】自前のCSVインポート処理の決定版。大量データや多数のカスタムフィールドにも対応。【WP】自前のCSVインポート処理の決定版。大量データや多数のカスタムフィールドにも対応。2019/10/07ツイートWordPressにCSVデータをインポートするために様々なプラグインがありますが、要件に応じた柔軟な対応は難しいものがあります。「社内で管理している商品番号をキーにしたい」や「基幹システムから出力したCSVを毎日自動で取り込みたい」や「管理画面から『上書き禁止』設定をしたものはCSVインポートで上書かない」などなど。いう要件に関してはプラグインをカスタマイズをするよりも、自前でのCSVインポート処理を作ってしまうのが良いと思います。そんなに難しくありませんし、とても柔軟に作ることが出来ます。この記事では以下の流れで解説します。比較的少量のデータや簡易な構成の場合は、上記の2の手順までで完結しますが、CSVデータが増えた時のことを考えると4の手順まで実装しておくと安心かもしれません。(4まで実装するとユーザーが使いやすいですし)1.CSVファイルのアップロード処理まずは、CSVファイルをアップロードする処理について書きます。基幹システムなどでサーバーに置く場合はこの部分は不要ですね。Pointsアップロード用固定ページ作成(非公開設定)アップロード処理について(必要なら)ファイル自体をUTF-8に変換インポート処理用PHPを呼び出して実行アップロード用固定ページ作成(非公開設定)CSVインポートする画面は管理者以外には使わせる必要はないので、非公開の固定ページを作成し、そこをCSVファイルをアップロードできる画面にします。type=”file>でファイルをアップロードできますが、<form>に「enctype=”multipart/form-data”」を指定する必要があります。ランダムな文字列をセットし、後で照合することにより、この後作成するプログラムの不正な使用を防ぐことができます。(アップロード用ページは非公開ページですのでここにkeyを書いちゃって大丈夫です)アップロード処理について<form>でファイルをアップロードしたら、それを受け取る処理を書く必要があります。アップロードしたファイルの情報は変数「$_FILES」に格納されます。それを利用して例えば以下のように処理を書きます。"をアップロードしました。"ファイルをアップロードできません。"をアップロードしました。"ファイルをアップロードできません。最近はエクセルでも「UTF-8」でCSV保存することが出来ますが、これにはまた別の罠があります。BOMなし」ですので、上記の場合は文字コードを変更する必要があります。『文字コードって何?』というクライアントもいますので、こちら側の処理で変更してあげたほうが良い場合が多いです。$filepath);インポート処理用PHPを呼び出して実行インポート処理を直接書いても良いのですが、それ用のPHPを作って呼び出したほうが後々便利なので、以下のようにしてPHPを呼び出します。【ランダムなキー】');しかし、この書き方では、外部処理にしたことをあまり有効に活かせていません。CSV処理が完了するまで、そのページは【処理中】となるからです。(時間のかかる処理ならブラウザの読み込み時間制限によりタイムアウトしてしまいます)ですので、以下のように記述します。&」という書き方がけっこう出てきますが、ログを取る場合は上記の書き方が良いです。これで、とりあえずCSVインポート処理用のプログラムを実行できました。次の部分ではプログラムの中身について書いていきます。2.インポート処理用のPHP作成WordPressで直接制御しないPHPを読み込んでいますので、WPの関数などが使えるように、まずはWPを読み込んでやります。('【WPのルートディレクトリ】/wp-load.php');このプログラムの中でどのような処理にするかは案件によって変わるわけですが、ポイントとケースをいくつか記載します。PointsCSVファイルを読み込んで配列に入れる分かりやすい配列の扱い方Casesカスタム投稿に投稿するカスタムフィールドに値をセットするタクソノミーをセットするCSVファイルを読み込んで配列に入れるCSVの取り込みには、「SplFileObject」を使うと便利です。処理}上記の「$line」という配列に、CSVの1行がさらに配列の形で入っています。それぞれのセルの値を取りたい場合は配列番号で指定できます。(画像1)分かりやすい配列の扱い方しかし、配列番号で今後の処理を書くのは、パッと見て何の項目か分からなくなり不具合の温床ともなります。そこで次のようにすると分かりやすいと思います。(これはただの提案です。良いやり方があるかもしれません。)CSVにはhead行をつけていると思いますので、このheadの項目名で扱えるととても便利です。head行を読み込んでそれを逆配列(キーと値を入れ替えた配列)にしておき、それを用いて各セルの値を指定します。「array_flip」という関数で可能です。12-13$i++;}ここから実際の処理を書いていくわけですが、ざっくりとよくあるケースの記述を書いていきます。カスタム投稿に投稿するこれが一番多いでしょうか。CSVの1行が1つのカスタム投稿になる、というものです。投稿を追加するのは「wp_insert_post」というWordPressの関数を使いますが、この関数はただ追加するだけです。CSVの中身を1度だけ入れる、というのならこれでポンポン入れていけば良いでしょうが、CSVで管理しているものを更新してそれを適宜インポートしたい、という場合はこのやり方ではだめです。WordPressは投稿をIDで管理していますが、WordPressの持つIDとCSVの一意なidが一致することは意図的にそうしない限り、ないでしょう。商品を管理するCSVでは品番で一意に管理しているかもしれませんが、これをそのままWordPressのIDにすることは無理です。CSVでの一意になる項目(複数のキーで一意になるのでも良い)で投稿を検索して、見つかったら更新(wp_update_post)し、見つからなかったら新規投稿(wp_insert_post)すれば良いわけです。↓上記の「画像1」で1列目をスラッグとして一意に管理している場合の書き方(※スラッグで管理するのは実際はお勧めしません。カスタムフィールドに値をセットするCSVでインポートしたい、なんて時にはだいたいカスタムフィールドに値を入れたいものです。「update_post_meta」を使って入れることが出来ます。「update_post_meta」は「update」なので更新専用と一瞬思いますが、対象が存在しないときは「add_post_meta」というカスタムフィールドを追加する処理を内部で行ってくれます。「update_post_meta」だけで完結出来ます。);...単一のデータを入れる場合はこれで良いですが、複数データ(繰り返しカスタムフィールド)を入れたいときには、一度消してから追加する、という流れです。CSVのセルにカンマ区切りで入っているデータを繰り返しフィールドの形でWPに入れたい場合は以下のように行います。タクソノミーをセットするタクソノミーをセットしたいことも多々あると思います。これも難しくありません。「wp_set_object_terms」を使うことができます。「追加」の処理になります。「追加」の処理になります。...ちなみに、タクソノミーにもメタ情報を持たせることが出来ます。「update_term_meta」を使えば「update_post_meta」と同じような感覚でタクソノミーのメタ情報をセットできます。補足ここまででCSVの中身をWPに入れる処理はたいてい出来ると思います。インポートしたメタ情報(カスタムフィールド)についての補足ですが、WPの初期状態では管理画面からは見えませんが情報としては確かに入っています。管理画面で視覚的に見るためにはカスタムフィールド用のプラグインなどを利用することが出来るでしょう。Fieldsは、WordPress自体が初期には繰り返しフィールドに対応していなかったので、独自のやり方で繰り返しフィールドに対応してくれていたのでこの形になったのですが)。3.大量のデータや処理でメモリが足りなくなるケース対応さて、CSVで管理しているデータはたいていそこそこ大容量です。CSVでインポートしたいと思うわけですが。10,000行くらいのCSVをインポートする場合など、環境によっては処理が完了せずにタイムアウトしてしまうことがあります。メモリ不足で落ちてしまうこともあります。『10,000件くらいで!?』と思うかもしれませんが、WPの関数「wp_update_post」や「update_post_meta」「update_term_meta」などは既存データの確認や排他処理などを裏で行っているため結構処理が重たいのです。そんなときには、1つのプロセスで処理するCSVの行数を制限して段階的に処理していけば大丈夫です。PHPは「exec」関数で、linuxの標準コマンドを実行できます。それを利用して非同期にPHPを実行します。);...これではただの非同期実行ですから、行数を制限していることにはなりません。実行時に標準引数を付けてやることにより、開始行数を設定するようにしましょう。自分を再帰的に呼び出します。(セキュリティ的なことは考慮していません。上記の3の書き方で非同期処理を行った場合、ユーザー(管理者)としては処理が完了したかどうか分かりません。いつ終わったのか、そもそも正常に終わったのか、気になることでしょう。そこで、書き込みしているログファイルを管理画面で見ることが出来れば便利だ!と気づきました。非公開のページを作り、そこでログファイルを読み込めば良いのです。ログファイルも結構なサイズになります。それを全部読み込むのは処理的に大変です。いう場合は、最後の数十行だけを表示すれば良いのです。linuxの標準コマンド「tail」を使うことにより簡単に実装出来ます。$output);...上記の「$output」に返ってきた値が入っていますので、それを適当に表示させてあげればOKです。WordPressのカスタマイズをしていくと、機能が多くなればなるほど管理画面がごちゃごちゃしてきます。標準エディターが変わる、という記事を書く側にとっての大きな変更になるWordPress5.0のアップデート。