タグ: mysql

  • WordPress 4.2.x のマルチサイトトラブル…

    WordPress 4.2 より絵文字が使えるようになって、それを早速試してみたのですが、エラーが出る場合があったのでその対処法と苦闘?を備忘録として書きました。

    苦闘はどうでもいいからとりあえず試してみたい。 😥 という方は一番下までスクロールしてね。 😯

     

    エラーについて

    その時の環境は以下となります。

    • ローカル環境
    • Windows 8.1
    • XAMPP 1.8.1
    • Apache 2.4.3
    • PHP 5.4.7
    • MySQL 5.5.27

     

    まず、WordPress4.2.2をいつも通り、データベースを作成して新規インストール。

    https://codex.wordpress.org/Installing_WordPress

    インストールOK。wp-confing.php にてデバッグモードをtrue、デバッグログを trueにしておく。

    使ってみる。特にエラーは何もなし 😛

    絵文字を使ってみる。やっぱり何もエラーなし。 😎

    ※Windows 8.1 でノートパソコンをお使いの方は、下にある、アプリケーションや時間等が表示されている「ツールバー」を右クリックして、「ツールバー(T)」> 「タッチキーボード」を選択すると、ツールバーにキーボードが表示されると思うので、そのキーボードから絵文字は入力できるようになっています。

     

    で、問題はここから。

    Announce from the Dashboard 等マルチサイト対応のプラグイン等もあるため、マルチサイトに変更して動作を試してみました。

    Codexはこっち。http://codex.wordpress.org/Create_A_Network

    うん、とりあえずマルチサイトになりました。

    マルチサイト画面
    マルチサイト画面

    そして「サイト」>「サイトの作成」から、2つめのサイトを作成しようと思ったら…

    サイトの作成
    サイトの作成

    む? 😕 画面上にエラーが出ました。。

    Warning: preg_match() expects parameter 2 to be string, object given in wp-includes\formatting.php on line 3435
    Warning: preg_match() expects parameter 2 to be string, object given in wp-includes\formatting.php on line 3424
    Warning: preg_match() expects parameter 2 to be string, object given in wp-includes\formatting.php on line 3435
    Warning: strip_tags() expects parameter 1 to be string, object given in wp-includes\formatting.php on line 3407
    Warning: strip_tags() expects parameter 1 to be string, object given in wp-includes\formatting.php on line 3407
    Catchable fatal error: Object of class WP_Error could not be converted to string in wp-includes\kses.php on line 1038

    preg_matchに値が何も来ていないのかな?strip_tagsにも来ていないのかな?

    色々推測してみましたが、結局原因は分からないので、とりあえず画面を戻ってみると、

    サイト一覧
    サイト一覧

    サイトは作成できているっぽいです。細かいバグ?が何かあるのかな。

    と思いつつ、作成した2つ目のサイトのダッシュボードにアクセスすると、なぜか404エラー。

     

     

    ん?(´・ω・`)

     

    .htaccessの問題?.htaccessファイルを確認するも、特に問題は無さそう…
    さっきのエラー、多分関係あるな。。

    さて、どこから原因を探したほうがいいかな。。ワカンネ(´ー`)

     

    😕

     

    他に問題がないか調べてみようと思い、新しく作成したサイトのデータを編集画面(ネットワーク管理画面内)から見てみましたが、ユーザーがいない。。

    あれ、admin 足したけどな…WordPress4.2からブルートフォース対策とかでadminは足せないのかな?だとすると、初めからadminでユーザー作成できるのはおかしいから関係はないか。admin足せば問題ないのかな?

    でもユーザーがいないからって、404エラーはないか。 🙁

    細かいバグでは無さそう。。

    次にサイトの編集設定を見ると…

    サイト編集設定
    サイト編集設定

    設定できる項目が、サイトのアップロード領域のクォータ っていう項目しかない。。

    え?なにこれ?サイトが上手く作成できていない? 🙄

     

    他にエラーが無いか確認してみようと思い、次にwp-content/debug.logの中身を確認しました。

    すると、かなりのエラー。。 😳

    そして、画面を表示する度にこのエラー。

    WordPress データベースエラー: Table '42.wp_3_options' doesn't exist for query SELECT option_value FROM wp_3_options WHERE option_name = 'home' LIMIT 1 made by WP_List_Table->display, WP_List_Table->display_rows_or_placeholder, WP_MS_Sites_List_Table->display_rows, get_home_url, get_option

    doesn’t existって、テーブルが無いってこと?まさか~、そんな事今までにないよ?

    サイト一覧にちゃんと作ったサイトがあるんだし。

    で、phpMyAdminから確認してみました。

    phpMyAdmin
    phpMyAdmin

    😈

    うん。。。無いですね。(´・д・`)ゞ

    これで問題は分かったけど、原因は何だろう。

    今までこんなエラーは無かったので、WordPress4.2からのエラーかな。
    エラー内容を見る限りでは、文字コード系かな~と推測。。

    それからwp-config.phpの以下をにらめっこ。

    /** データベースのテーブルを作成する際のデータベースの文字セット */
    define(‘DB_CHARSET’, ‘utf8mb4’);

    WordPress4.2からのエラーというのが気になって、もしかして最初にCodexを参考にデータベースを作成した時の文字コード utf8_unicode_ci が4.2以降では違うのかなと思い、今度はデータベースを作成する際に、照合順序ってのを utf8mb4_general_ci で作成して、同じくマルチサイト環境でサイトを作成してみましたが、だめでした。

    しかも全く同じようなエラー。 😳

    じゃあ文字コードじゃないのかな。。

    ログファイルをにらめっこしていると、ほとんどのエラーが wp_2_****** のテーブルが無いよ!みたいなエラーだったので、そもそもテーブルが作れていない!?
    ようなので、そこだけ注意してみてみると、

    WordPress データベースエラー: COLLATION 'utf8_general_ci' is not valid for CHARACTER SET 'utf8mb4' for query CREATE TABLE wp_2_terms

    あ、create table でデータベースエラーなのね。。 😳

    utf8_general_ci is not valid ?え?どーゆーいみ?わっつ?( ´゚д゚)ン?

     

    🙄

    意味が分からなかったので、とりえあずサイト作成のコードを追う事にしました。

    まずはURLの通り、wp-admin/network/site-new.phpをざっくり見る。

    ざっくり見ると、分からない…なので、詳しく見る。 :mrgreen:

    エラーが発生しているっぽい怪しいコードを発見。その上と下でごにょごにょ。色々試した結果、wpmu_create_blog()内が問題っぽい。

    それをさらに追うと…insert_blog()はエラー無し。問題無さそう。
    install_blog()はどうだろう…あ、エラーか。

    またさらに追う。make_db_current_silent(‘blog’)直後にログにエラーが出る。

    もっと追うと、dbDelta()でquery()を実行した時にエラー。テーブル作る際のクエリ内に多分問題あるのかな。 😐

    クエリがたくさんあって、どれがエラーのクエリか分からないので、1つクエリを抜粋してphpMyAdminで試してみました。

    CREATE TABLE wp_2_terms (
    term_id bigint(20) unsigned NOT NULL auto_increment,
    name varchar(200) NOT NULL default '',
    slug varchar(200) NOT NULL default '',
    term_group bigint(10) NOT NULL default 0,
    PRIMARY KEY (term_id),
    KEY slug (slug(191)),
    KEY name (name(191))
    ) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8_general_ci

    あ、エラーなんだ。一旦、WordPressのエラーとデータベースのエラーのどちらなのかを判別するために、phpMyAdminにて直接クエリを実行。

    phpMyAdminのレスポンスは以下。

    #1253 - COLLATION 'utf8_general_ci' is not valid for CHARACTER SET 'utf8mb4' 

    クエリの文法エラーではなさそう。これはWordPressでもPHPのエラーでもなく、MySQLでのエラーっぽい。
    と、ここでやっとさっきのエラーの意味が少し分かりました。

    あ、utf8mb4のエラーじゃなくて、COLLATION の utf8_general_ci っていう文字コードのほうで、エラーなのね。 😳

    それで、COLLATIONってなに?で、ググってみましたが、、

    http://dev.mysql.com/doc/refman/5.5/en/charset-connection.html

    なるほど。。…ワカンネ(´ー`)

    で、お次。

    http://qiita.com/kazu56/items/6af85ffcf8d3954455ad

    おぉ、これは少し分かりやすい!COLLATIONは文字コードの設定ではなくて、ソートする際の文字コード(照合順序)、みたいな意味合いっぽいですね。

    で、問題は、そのソートする際の文字コードが is not valid かな。

    おそらく、照合順序に utf8_general_ci なんていうものは無い又は、何かのバリデーションに通らない、みたいな意味かな。not valid って、意味が大きいな。。

    さて、問題は何で not valid なんだろう。。 😐

    まず、utf8_general_ci があるかどうか確認するために、phpMyAdmin から選ぶことができる照合順序を確認してみました。

    ちゃんと utf8_general_ci はあるじゃん。スペル間違い?いや、そうでもない。

    あれ、ちょっと待てよ…。WordPress4.2からmb4だから、utf8_general_ci 自体、違うんじゃないかな。。それとも、別の原因かな。

    こういう時は、にらめっこ。 😎
    さっきのテーブル一覧をにらめっこしていると…

    phpMyAdmin
    phpMyAdmin

    😈

    あれ、全部、テーブルの照合順序が utf8mb4_general_ci じゃないか! 😈
    でもなんで新しいサイトのクエリは utf8_general_ci になる?
    あ、これが原因?少し解決できそうな予感…。 😮

    phpMyAdminから直接クエリを試してみます。
    さっきエラーのあったコードの一部、COLLATIONの値を utf8_general_ci からutf8mb4_general_ci に変えてやってみました。

    CREATE TABLE wp_2_terms ( term_id bigint(20) unsigned NOT NULL auto_increment, name varchar(200) NOT NULL default '', slug varchar(200) NOT NULL default '', term_group bigint(10) NOT NULL default 0, PRIMARY KEY (term_id), KEY slug (slug(191)), KEY name (name(191)) ) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci

    お!

    おぉ!

    うまくテーブルが作成できました。 🙂

    これが原因!?

    じゃあ、今度はWordPressで試してみようかと思い、COLLATION を指定しているところを探してみる。

    wp_get_db_schema()にてCOLLATEとしているみたい。

    もっと追ってみると、wp-includes/wp-db.php のinit_charset()にてCOLLATEを指定しているっぽい。

    今はテストなので、とりあえずwp-db.phpに直接、COLLATEが utf8mb4_general_ci になるよう変更して、サイトの作成を試してみました、、、

    🙂

     

    うまくいきました!エラーは特になし。あ~疲れた(まだ早い)。 😆

    テーブル一覧
    テーブル一覧

    うん、テーブルも上手く作成されているし、作ったサイトのダッシュボードにもいけますね。

    これは、なんとか解決できたっぽい。

    上手くサイトが作成できない時は、COLLATION (文字コードの照合順序)が違う為なのかな。

    サーバごとに、COLLATIONが違っていればを変えればいいのか。

    今はテストだからwp-db.phpに直書きだけど、簡単にサーバごとにCOLLATIONを変更するいい方法ないかな(´・ω・`)

    で、さっきの init_charset() を見ていると、

    } elseif ( defined( ‘DB_COLLATE’ ) ) {
    $this->collate = DB_COLLATE;
    }

    お、どこかでDB_COLLATEを定義できるんだ。ー(‘∀’)ゞ

    で、検索してみると…wp-config.phpにあるし。 👿
    いつもこの辺はWordPressが自動で作成するからスルーしていました。 😉

    /** データベースの照合順序 (ほとんどの場合変更する必要はありません) */
    define(‘DB_COLLATE’, ”);

    今まで一度も変更したことなかった。。こういう時に変更するんだね。 🙂

    ってことで、ためしにdefine(‘DB_COLLATE’, ‘utf8mb4_general_ci’);として変更してサイトを作成してみましたが、うまく動作しました。:-o

     

    念のため、もう一度試しました。

    さきほど、データベースを作成する際の、照合順序の文字コードを変えていたので、一旦 Codex と同じ照合順序 utf8_unicode_ci にてデータベースを作成。

    データベース作成
    データベース作成

    同じようにインストール&マルチサイト化。

    照合順序の文字コードはいまこんな状態。

    データベース: utf8_unicode_ci

    各テーブル: utf8mb4_general_ci (どのタイミングでutf8mb4_general_ciになるんだろう…) 😕 

    サイトを作成してみる。やっぱりエラー。

    wp-config.phpにて

    define(‘DB_COLLATE’, ‘utf8_unicode_ci‘);

    に変更してサイト作成を試してみる。

    同じようなエラー。ってことは、テーブルを作成する時の照合順序ではなくて、他のテーブルの照合順序と同じようにすればいいのかと思い、

    define(‘DB_COLLATE’, ‘utf8mb4_general_ci‘);

    で試すと上手くいきました。 🙂

     

    追記

    wp-config.phpのDB_CHARSETによって、utf8mb4_general_ciかどうかも変わるっぽいです。

    DB_CHARSETutf8mb4 だったら、utf8mb4_general_ci

    DB_CHARSETutf8 だったら、utf8_general_ciutf8_unicode_ci

     

     

    参考にされる方へ。

    同じようなエラーに遭遇した方は、wp-config.phpのDB_COLLATEを

    define(‘DB_COLLATE’, ‘作成済みのテーブル wp_options とかの照合順序の文字コード‘);

    みたいな感じで、一度試してみてください。

    🙂

     

    久しぶりにブログ更新… 😉