wp search-replace

WordPressの引っ越しに便利な wp search-replace

WP-CLIアドベントカレンダーの2日目担当の @gatespace_k です。

今日は個人的に一番便利な機能 wp search-replace を取り上げます。

スポンサー

WordPressの引っ越し

私はお仕事でWordPressを使っていますので、WordPressサイトの引っ越しというよりも本番環境(あるいは開発環境)からローカル環境への移行が結構あります。
Web上のサイトからデータベースや必要なファイルをダウンロードしてきて、ローカル環境を構築します。

この時、URLの置換を行わないとログインしたダッシュボードが本番環境になってしまったり、画像が表示されなくなったり、ということが起こりえます。

この辺りは 日本語Codex「Moving WordPress」 に必要な手順が書いてありますが、要約すると「WordPress アドレス(URL)欄」「アドレス(URL)欄」だけでなく、本文中に入れている画像のURLの置換なども必要になってきます。

その昔は「ダウンロードしたsqlをエディタで開いて(あるいはphpMyAdmin上で)URLを検索置換」という方法が推奨されていましたが、Codexから記載が削除されたとおり、現在ではおすすめされる方法ではありません。
その理由が 「データベース内で保存されている内容がシリアライズされている可能性」 があるからです。

シリアライズされて保存されているデータ

WordPress本体のみではシリアライズされて保存されるデータにURLは含まれません(ただし執筆時4.0.1の場合)。
しかし、テーマオプションやプラグインなどでデータベースにシリアライズして保存する物もあり、そちらではURLを含んでいるものがあります。

例としてウィジェットに画像の設置を簡単にできる  「Image Widget」  を取り上げます(例はサイドバーエリアの画像)。

Image Widget 使用例
Image Widget 使用例

この情報がデータベースのどこに保存されているかというと、wp_options テーブルに option_name 「widget_widget_sp_image」として内容が保存されています。

その中身がこちらでシリアライズされています。

見づらいので画像のURLの部分だけ抜き出すと
s:78:"http://wordpress.local/wp-content/uploads/2013/03/image-alignment-150x1505.jpg";

となっています。

中身の意味は PHP: serialize – Manual あたりに詳しく書いてあるので省略しますが、上記の場合
「String型78バイトで値は http://wordpress.local/wp-content/uploads/2013/03/image-alignment-150×1505.jpg 」
となります。

このように「型」「サイズ」「値(value)」がセットで保存されているので、URLの一括置換などで「値(value)」のみを変えてしまいサイズ(この場合文字数)が変わってしまうと、アンシリアライズできなくなり、ImageWidgetであれば中身がなくなってしまいます。

こういった状況を考え、データベース内のテキストを置換する場合は一度データをアンシリアライズし、置換、再度シリアライズして保存、という手順が必要となります。

ここまで書くと「よく分からん」と思われる方もいるでしょうが、極論すると 「テキストエディタでそのまま置換するとマズイよ」 と覚えてもらえればOKです。

wp search-replace

前置きが長くなりましたが、ここでWP-CLIの登場です。

URLの置換だけに限りませんが、wp search-replace [old] [new] で置換と検索が行えます。
URLの場合であれば

のようにします。最後に / を入れないのがポイントです。

wp search-replace

先の例でURLを置換しデータを見ると
s:76:"http://example.local/wp-content/uploads/2013/03/image-alignment-150x1505.jpg"
となり、シリアライズされた部分も正常に置き換わります(バイト数が変わっています)。

もちろん、URLの置換以外に特定の文言の検索・置換もできますし、オプションをつければ投稿に関するテーブルのみを対象とすることもできます。
便利でしょ?


余談ですが、WP-CLI使えないわーという場合は、PHPスクリプトをサーバーにアップし、GUIで変換することも可能です。

明日は @tecking さんです。