4.1.2 へアップデート後、投稿記事の公開ができない
-
初めての投稿です。稀な状況だとは思いますが自分での解決ができなかったためご教授願います。
新規投稿時にPHPのエラー
Warning: Creating default object from empty value in /wp-admin/includes/post.php on line 581 Call Stack: 0.0000 246424 1. {main}() /var/www/vhosts/default/wp-admin/post-new.php:0 0.4185 12565952 2. get_default_post_to_edit() /wp-admin/post-new.php:71
が表示されて、公開ボタンの表示がレビュー待ち〜のになり公開ができませんでした。
プラグインはすべてOFFにした状態でも同様の現象です。
他に気になった点としては投稿画面のコメント欄に「不明なエラーが発生しました。」と表示されます。
テーマのアップデートも最新のものへ変更しました。・WordPress のバージョン
4.1.2
・使用しているプラグインとテーマの情報
プラグインはすべてOFFの状態 twentyfourteen
・PHP、MySQL のバージョン
PHP PHP 5.5.24 mysql 5.5.39-36.0
・サーバー環境(ホスティングサービス名、OS、ウェブサーバー等)
CentOS release 6.5,お名前.com vps nginx-1.6.1-1.
・ブラウザ
Chrome 42症状としてはこのトピックと同じです。
https://ja.forums.wordpress.org/topic/148982?replies=8同じサーバーの状態でやむなく4.1.1へ戻していますがこの現象は発生していません。
-
皆様ありがとうございます、結論から言いますと解決しました。
>kjmtsh様
詳細なアドバイス、ありがとうございます!
やっと時間ができたので試してみました条件に当てはまっておりましたので
>>wp-db.php の変更点。2479行目を下のように変更します。
該当箇所を1行書き換えるだけで、見事に改善しました。
本当にありがとうございます。しかし、このまま文字コードが混在した状態で
使い続けると、またこういったトラブルに見舞われる
可能性が常にあるのでしょうか…
さすがに10年近く描き溜めた1500件以上の記事量なので
根本的な改善を図るべきですよね。その場合>Daisuke Takahashi様
のおっしゃっておられた
>>pMAでSQLクエリを打つ
もしくは
>>DBをUTFで再作成
どちらかの方法になるのでしょうか?どちらも私にはハードルが高そうですが
記事の投稿が出来ないエラーは致命的なので
できれば再発は避けたい、と思っています。
ただ、UTF-8への変換はかなり以前に調べたものの
難しそうで断念した記憶もあります…このまま今回のように修正を行い使い続ける事は
やはりよろしく無いのでしょうか?
引き続き、アドバイスございましたらよろしくお願い致します。@ゆたか ちひろ さん
報告ありがとうございます。
私が実験したのと同じ事態が現れているとすると、WordPress の不具合となりそうです。開発者にはまだ伝わっていません。似たような例は報告されていますが、別の問題です。このまま放置すると、ずっと直らないままになってしまうので、次回リリースで修正されるように何とかリポートを出そうと思いますが、まだコードを読み切れていないのと、他の要素がからんでいる可能性を排除できないので、少し時間がかかるかもしれません。また、上の修正が最終的な解決方法というわけではないことも、ご承知願います。どちらかというと、弥縫策に近いです。また、別の不具合が生じていないかどうか、教えていただければ、助かります。
原因は、MySQL のサーバ文字コードと、データベース、テーブル、カラムの文字コードの違いが開発者にわかっていない、もしくは、勘違いしている、あるいは、想定から抜けている、といったところです。これらを同一視した結果、プログラムの中で混同が生じています。
以下、不安が解消されるかどうかはわかりませんが、状況を説明しておきます。
データベースが ujis (EUC-JP) になっているサイトがどのくらいあるかわかりませんが、WordPress の必要要件を考えると、そういうサイトでも、サーバとの通信には utf8 (UTF-8) を使っているはずです。OS の環境が UTF-8 になってしまっているということもあります。一方、古くから WordPress で運用しているサイトなら、これも高い確率で、EUC-JP のテーブルを使っているはずです。このとき、EUC-JP で表現できない文字が含まれていないなら、何もせずに UTF-8 で通信すれば、MySQL が内部で変換をしてくれます。
これは、「文字コードの混在」ではありませんし、MySQL にとっても別に異常な事態でもありません。こういう風にして使えるデータベースなのです。wp-db.php の今回の変更は、テーブルの文字コードで許容できない文字をあらかじめチェックしようというものです。文字コードの違いを利用した SQL インジェクションを予防するという目的もあるかもしれません (コア開発者の議論が読めないので想像です)。
EUC-JP テーブルを持った MySQL と WordPress との通信は、おおよそ下のようになっています。
+-------+ +-----------------+ +-------------+ | table | <- ujis -> | Database engine | <- utf8 -> | PHP library | +-------+ +-----------------+ +-------------+ ^ ^ ^ | | | +------ MySQL ------------+ WordPress
断言はできませんが、不具合は、テーブルの文字コードが ujis なら、WordPress と Database engine との通信も ujis のはずと決めてかかっていることからくるようです。ユーザにとっても内部の状況が掴みにくい状況であることは確かです。MySQL の文字コードを聞かれたときに、普通に外から見たら、utf8 と答えるでしょう。また、そう考えていて、問題はありません。通常ならば、と付け加えなければなりませんが。
あらためて述べると、「データベースの文字コード」と言ったときには、phpMyAdmin が使えるなら、データベースやテーブルをクリックして、そこに表示されているものを見る必要があります。wp-config.php の DB_CHARSET は、utf8 で問題ありません。ですが、これは「データベースの文字コード」ではありません。
さて、この状況でデータベースを utf8 に変換する必要があるかどうか、ですが、個人的な見解では、よくわからない場合には必要がない、と思っています。特に、現状の運用で問題がないなら、なおさらです。変換は、SQL 文を発行することでできますし、ujis から utf8 の変換は、その逆に比べれば容易ともいえますが、環境も調べず、バックアップも取らず、むやみに実行されても困るので、ここに書くのは控えます。ただ、変換することは、いつでもできると思ってもらってかまいません。
EUC-JP は、文字データを1バイトと2バイトで表現しますが、UTF-8 は、規格上では1~6バイト、現実には1~4バイトで表現します。4バイト文字は、今回のアップデートで WordPress にコードが追加されましたが、MySQL 5.5.3 以降でしか扱えません。PHP の正規表現で扱えない文字を判定するというところが、ちょっと危うい感じはしますが、とにかく、そうなっています。ご存知かもしれませんが、扱える文字の範囲は、
EUC-JP < UTF-8
となります。EUC-JP では扱えない文字が UTF-8 には大量に存在するわけですね。上の条件で、もし、EUC-JP で扱えない文字が MySQL に渡ったら、どうなるでしょうか? MySQL は、エラーを返しません。変換できない文字を ? に変えて、テーブルに保存します。変換できない文字が飛んでくるたびにエラーになったり、止まったりしていてはサーバとしての役割が果たせませんから、当然の仕様です。
EUC-JP で運用している WordPress サイトでこれがあまり問題にならないのは、たぶん、日本語しか入力されていないからです。通常使う現代日本語なら、EUC-JP で充分にカバーできてしまうのです。半角カタカナでさえ扱えます。広東語の「粵語」は「?語」となりますが、中文の「你好」やドイツ語の “Die fröhliche Wissenschaft” くらいなら、正しい文字が入力されます。
これで、問題になるのは、EUC-JP で表現できない文字が、入力に含まれる場合ということになります。どうしても、UTF-8 でしか表現できない文字を使いたい、たとえば、4バイト文字の絵文字をそのまま保存したい、というような場合は、当然ですが、データベースの変換が必要になります。そうではなくて、現状で満足ならば、無理をする必要はないと思うわけです。それよりは、バックアップをこまめにとることの方が重要だと思います (ダンプデータは UTF-8 で保存されます)。
また、データベースの変換を勧めたくない理由は、他にもあります。
別の問題で、バグリポートを処理した pento さんが、もう utf8 だけをサポートすればいいのではないか、と言われたときに、こう述べています。
utf8 が最良の解決策であることは認める (実際、WordPress サイトの大多数は utf8 を使っている) けれども、後方互換性を破壊して、それを使うように強いることは断じてありえない。何年も前に作られた多くのサイトがあって、それらは MySQL のユニコードサポートが不十分だったときに作られたものだ。WordPress をアップグレードするために、それら全てのサイトの文字コードを強制的に変更させることが、われわれの選択肢になることはない。
nacin さんをはじめ、WordPress の開発者たちは、ことあるごとに、この「後方互換性 (backward compatibility)」といいます。あるいは、「現在稼働している WordPress のインストールを破壊しない変更しか許さない」とも言って、PHP 5.2.4 をサポートするために、ある意味、プログラムのスピードアップも、コードの可読性をも犠牲にして、既存のサイトを守ろうとします。反対意見もたくさんありますが、彼らは、WordPress が新たな技術を試すための場ではない、ということを肝に銘じているようです。
私自身は、そういう開発者たちの姿勢を信頼していますし、Philosophy (心打たれる文章ですが、日本語訳がありません) に書かれた原則に則って行動しているとも思います。頑固さに辟易することもありますが、それだけに、現行のサイトが影響を受けるときには、互換性を維持しつつ、ゆるやかに時間をかけて移行するはずだと思っています。
だから、公式に utf8 以外のテーブルをサポートしないとアナウンスがあるまでは、ユーザにデータベースの変換をするように勧めたくはありません。ただ、変換をしたいというユーザを止めるつもりもありません。
もし、ゆたか ちひろ さんが、utf8 に変換したいということでしたら、あらためて、トピックを立て直してください。データベースの詳細がわかれば、協力できるかもしれません。あるいは、できないかもしれません。個々のケースによって、違いますから、一般的な解決策などというものはないと思ってください。
>kjmtsh様
とてもわかりやすい解説をありがとうございました。
これまで、EUC-JPのテーブルがあっても大丈夫だったのは
そう言ういきさつもあったのですね。
それならば開発の方々の「後方互換性」を信頼し
このまま下手にDBをいじらずに過ごしたいと思います。現在はWP4.2、PHP 5.4.35、MySQLは5.1.73でUTF-8の環境です
古いWPのテーブルはEUC-JPのままですが
現状で、不具合も改善し、他の不具合は出ておりません
WordTwit等投稿に関連のあるプラグインも
問題なく動作しております。今後のWPバージョンアップの際、様子を見て
同様の問題が出た場合は同じ修正を行い
それでも問題があるようであれば
トピックを立ててご相談させて頂くかも知れません。不具合も改善し、疑問も解消してスッキリ致しました
お時間頂きまして、重ねてありがとうございます。トピックを立てて下さった方や他の同様の症状の方も
改善すると良いですね。WordPress には MySQL の文字コード仕様を誤解したままで実装を行っていたという残念な過去があります。
https://core.trac.wordpress.org/ticket/3517当時 Ryan がこの問題を理解して適切な修正が本体で行われるまで丸1年かかりました。そしてその時にデータベースを UTF-8 に正常に変換できずにそのまま運用してきた方達、あるいは、同様の変則的な設定でたまたま動かせていた方達が今回のデータベース周りの改変に引っかかってしまった、ということですね。
utf8 が最良の解決策であることは認める (実際、WordPress サイトの大多数は utf8 を使っている) けれども、後方互換性を破壊して、それを使うように強いることは断じてありえない。何年も前に作られた多くのサイトがあって、それらは MySQL のユニコードサポートが不十分だったときに作られたものだ。WordPress をアップグレードするために、それら全てのサイトの文字コードを強制的に変更させることが、われわれの選択肢になることはない。
ということですが、これは後方互換というより、データベースの文字コードの変換が簡単でないゆえにやむなくそのまま運用を続けているサイトが存在してしまっているということであり、WordPress が UTF-8 データベースでの運用を念頭に開発されていること、また、それゆえ、データベースの文字コードを UTF-8 に変換することが今後のトラブルを回避するうえで最良の解決策であるということは間違いありません。
今後の対応のため気になっている点を列挙します。
UTF-8 以外の文字コード、あるいは、間違った設定のデータベースで WordPress を運用しているサイトについて:
- 現在どのくらいの数が存在しているのか?
- データベースの文字コードを UTF-8 に変換し正しい設定とすることが望ましいが、データベースの文字コードの変換は簡単ではない。問題のある設定には複数のパターンが存在し個々のケースで異なるため全体として決め打ちでこうやれば良い、という指南ができない。どのような対処をすすめるべきか?
コアコード・コア開発者について:
- 今回行われたデータベース周りの改変でバグや実装として望ましくない部分はないか?
- コア開発者の理解が至っていない、あるいは、見解に曖昧な部分はないか?
とりあえず、時間がないので、1点だけ。
今回行われたデータベース周りの改変でバグや実装として望ましくない部分はないか?
あります。
何行ものコードを通って、結局、どんな入力があっても、それと同じデータしか出力しない部分を見つけました。不正な入力を削除するという目的なのに、肝心のものが素通しです (\xC080 とか通っちゃいます)。どこかで見覚えがあると思ったら、RFC3629 のほぼコピペで…
MySQL が非常にエライので、後始末をしてくれています。まあ、何もしないのと同じコードなので、無駄なことをしているというだけなんですけど、修正案を出すために本気で実装となると、関数をそっくり書き換えになってしまうし、MySQL ができることを PHP でやることに意味があるのかどうか…思案中です。予想では、たくさんのプログラマが気づいていると思います。どうすればいいんでしょうねぇ?
とりあえずパッチが当てられfixedとしてマークされたようです。
テスト環境で再現できる方良ければ最新trunkで試してください。
この修正の4.2.2は2日以内にリリース見込みとのことです。(ミスリーディングしてるかも)このパッチは、環境によって、SHOW FULL COLUMNS の結果からテーブル名がうまく取れない不具合を直すので、テーブルの character set とは関係ありません。misleading というより、misunderstanding かもしれませんね。
別のところで出した報告に対して、数時間前に pento の変更が入ってますが、trunk または、4.2 branch でテストしてくれと言ってます。ゆたかちひろ さん、もしできるようしたら (読んでいてくれることを願いますが)、テストしていただけませんか? 今のところ、間違いなく、テーブルの character set が原因だとわかっているのは、ゆたかちひろさんだけなので (無理強いはしません)。
私もやってみますか、無理やり作った環境なので、ちゃんとした不具合の環境での(?)テスト結果がほしいです。
あーkjmtshさん報告のこれ(#32165)ですねスイマセンありがとうございます。
(フォーラムに話題に上がっている問題でチケット出した場合はそれをこっちにも貼っておいてもらえると嬉しいです。と言うか追いやすいです。)
相変わらずそのままだと、不具合の出てる状態です。
ここはずっとmailでチェックしています。やっと少し時間できたので、trunkのwp-db.phpを
4.2.1にアップデートした直後の状態(エラーが復活)
で上書きしてみましたが、全く同様のエラーでした。
今はtrunkからDLしたwp-db.phpに
先のアドバイスにあった「1行の変更」を加えた状態で
エラーを回避して利用しています。なんとか改善されると良いなと思っているので
またお役に立てることがあれば、テスト等いたします。おお、ゆたか ちひろさん、ありがとうございます。私も確認しました。以前の邪悪な処理はなくなったのですが、今度は問題が違うところに移っちゃいました。しかも、別の処理が追加されていて、混在した状態です。状況は厳しくて、前より修正が難しくなってます (一応、本意ではありませんが、上の1行の変更は今でも有効です)。
もう一度コードの読み直しになってしまったので、もう少し時間をください。人柱のようにしてしまって申し訳ありません。くれぐれも、こまめなバックアップを忘れずにお願いします。データベースのコンバートも視野に入れなければならないかもしれませんので (Kuraishi さんの言うとおり、これが最善であることは確かです)。
なんとか改善されると良いなと思っているので
またお役に立てることがあれば、テスト等いたします。泣けてきます、ありがとう。ご協力に感謝します、心から。
今朝、再びバグリポートを出しました。全力は尽くしましたが、理解されるかどうか、わかりません。
@ゆたか ちひろ さん
無理はされなくてけっこうですので、もしよろしければ、下の修正をテストしていただけますか? サイトを危険に晒すような変更ではありませんが、念のため、バックアップを取ってからお試しください。
上で述べた修正部分は削除して、wp-db.php の2686行目をご覧ください。
$queries[ $value['charset'] ][ $col ] = $this->prepare( "CONVERT( LEFT( CONVERT( %s USING binary ), %d ) USING {$value['charset']} )", $value['value'], $value['length']['length'] );
ここの、
%d
を%f
に、また、{$value['charset']}
を{$this->charset}
に書き換えます。同じく、2702行目。
if ( $charset !== $connection_charset ) { $connection_charset = $charset; $this->set_charset( $this->dbh, $charset ); }
この4行をコメントアウトして、実行されないようにします。以上です。
最初の
%d
に対する修正は、お使いの OS が64ビットで動作している場合は必要ないと思いますが、32ビットか64ビットかを知るのは難しい場合もあると思いますので、念のためです。32ビットの場合、そのままにすると、投稿本文の入力が0バイトになります。>kjmtsh
所用で遅くなりましたが、試してみました。まず4.2.2へアップデート→症状再現を確認
新規投稿しようとすると「新規投稿を追加」のすぐ上辺りにエラーが出ました
—–
object from empty value in /home/emoji/www/wp-admin/includes/post.php on line 627
新規投稿を追加
—–私は現在Win7 64bitですが、wp-db.php の2686行目、2702行目
を、指示通りに書き換え問題なく下書き保存、投稿等できています。
特に動作に不具合などは確認していません。レスポンス悪くて申し訳ないですが、これから暫くは多忙では無いはず、なので
もう少しお手伝いできるかと思います。
- トピック「4.1.2 へアップデート後、投稿記事の公開ができない」には新たに返信することはできません。