普段使ってるサーバーのPHPに php-develが入っていない という割と致命的なことに気づいたので魔が差してそれならPHPもアップデートしちゃえと思った結果がコレだよ!!
- IRC で導入しているBot がDB に接続できなくなった。
- Zend_Date にフォーマットが'Y-m-d H:i:s' のデータを突っ込んだら? Fatal error: Call to undefined function simplexml_load_file() が発生した。
- PHPとZendframework1(以下ZF1) の相互製の問題ならZF1 の最新版入れたらいいんじゃね→テーブルのカラムにない計算結果をエイリアス化してるところがどうやってもエラーになる
土日しか殆ど作業する時間とれないので暫定対応残しておきます。
#BOTのPDO対策
PDO なにか変わったのかなー(特にプリペアードステートメントに関して) と思ってBot の発言でトレースしようと思ったらあ、配列は喋ってくれないのね
ということでver_dump で生成されたSQLとバインドするパラメータをターミナルから確認する。
うぅ…ノイズ(Botの流すログ) が多くて見づらい…
PHP5.6 になって配列に変更あったらしいので
http://qiita.com/rana_kualu/items/206d786a2be7942c6dc3
を確認。
うん、別に今のコーディングに影響あるのものはないことを確認。
SQLServer みたいにバインドする時は 「?と整数」じゃないとダメってことにもなってない。
というわけでver_dump で生成されたSQL とバインドしたい値を手でくっつけてターミナルからMySQL にログインして実行→正常終了
んじゃ自分で書いたPDO 接続プログラムの問題じゃないなあ。
と思いながらログを追っていたらエラー出力発見、やったぜ。
Warning: PDO::__construct(): The server requested authentication method unknown to the client [mysql_old_password] in
全然気にしたことなかったけど、確かにBot で使わせているMySQL のアカウント、古い形式(16バイト) でした。
root とかWeb アプリケーションで使ってるのは41バイトだから確かに違う。
というわけで
http://www.natzworks.com/digital/2010/423.html
この通りに処置したらBot がちゃんとDB読みに行くようになってくれました。
ハッピーなのはここまで。
#Zend_Date対応(追加調査中)
2の原因がいまいち把握しきれてない。
Fatal エラーなのでログぶった切られてしまってるので
var_dump とexit(); で行単位でトレースした結果Zend_Date に'Y-m-d H:i:s' のデータを突っ込んでいるところがヒットしました。
はて…PHP5.4 使ってた時は問題なかったのになーっていうか、Zend_Date ロケール見に行ってたのか。
私のスキルが足りなくて未だにZend_Date 使いこなせてない感。
PHP5 以降ならsimplexml 標準で読んでくれるって質問掲示板にあって特に有効にさせる方法見当たりませんでした。
#最新版ZF1のPDOコーディング
というわけで安直にアップデートという選択肢をとってみたわけですが
今サーバーで動かしているのがZF1.11.11 最新版は1.12.8 らしい。
ZF2は構成が違いすぎて現時点では移行できないのでなしになりました。
さて、ZF1.11.11 だと
$command = "round(win / (win + lose)*100, 3) AS percent";
$select->from ( array($table ), array( '*', "$command" ) );
(部分抜粋)
これ動くんですが、1.12.8だとシンタックスが
SELECT `rate`.*, `rate`.`round(win / (win + lose)*100, 3)` AS `percent` FROM `rate` WHERE (rate_id = 1);
こうなって
ERROR 1054 (42S22): Unknown column 'rate.round(win / (win + lose)*100, 3)' in 'field list'
こうなった。
うーん、ご丁寧に演算にもグラーブアクセントつけてくれるのでエラーになっちゃいました、と。
#応急処置
取り敢えず時間も時間なんで取り敢えずエラーだけ取り除くのであれば、影響範囲の狭いZend_Dateを何とかする(取り除く) ことにしました。
ZF1 の関数を使わずに、PHP 標準のdate() と strtotime() で頑張るやつですね。
まあこれでなんかクレームでなかったらもうこれでいいような気もしますが
結局解決できなかったって後味の悪さは残ってるので時間があるときに何とかしたいなぁと思いながら。
以下Diff
before
// for graph data
if($value == $params['player_id']){
// set data only before 3 month from today
$today->sub( 3, Zend_Date::MONTH ); //ちなみにこれはちゃんと動く
$date = new Zend_Date( $list['created_on'] ); // アウトだったコーディング。
if ( $date->isLater($today)){
$target_rate[] = array('created_on' => $list['created_on'], 'rate' => intval($list['player'.$k.'_rate']));
}
}
after
// for graph data
if ( $value == $params['player_id'] ){
// set data only before 3 month from today
$before_3month = date( 'Y-m-d H:i:s', strtotime( '- 3 months' ) );
$date = date( $list['created_on'] );
if ( strtotime( $date ) > strtotime( $before_3month ) ) {
$target_rate[] = array( 'created_on' => $list['created_on'], 'rate' => intval( $list['player'.$k.'_rate'] ) );
}
}