カテゴリー別アーカイブ: php

[php]fgetcsvではまる…windowsとmacの改行

とある環境にて、CSVによるデータインポート処理をつくっていました。一度作ったCSV読み込みライブラリを使っていれば、はまることなどもうない!と思っていたのですが大いにはまりました。

あるデータというのが曲者で、Webアプリケーション(仮にシステムAとする)からエクスポートされるデータなのですが、改行コードがLFのみなのです。エクセルで読み込む際はそのへんが全く問題にならないのですが…fgetcsv関数で改行を判定してくれずすべてのカラムが等しく配列に格納されてしまいました。

php.iniのauto_detect_line_endingsをOnにすればよいという情報もありますが、稼働中のシステムにおいてこれによる別の弊害があるなら大変危険でございます。

>これにより、PHPがMacintoshシステムと相互運用できるようになりますが、 デフォルトはOffとなっています。これは、最初の行の行末表記を検出 する際にごく僅かな性能劣化があるためと、UNIXシステムのもとで復改 文字を項目セパレータとして使用している人が従来のバージョンと互換 性がない動作であると感じる可能性があるためです。

若干の性能劣化があるだけで基本的に問題なさそうですが、やめときましょう。自分の環境であればすぐ直すんですけどねえ。Window環境でしか修正されないことを見越してシステムAの改行コードをCR+LFに変更しました。Macで動かせないんですけどという問題は無きにしも非ずですが、とりあえず無視。

自己責任で環境を修正出来たらなんて楽でしょう。

PDOでbindParamしまくったら落ちてsignal Segmentation fault (11)になったの巻

phpでcsvインポートする処理を動かしたところ落ちた…apacheのerrorログには以下の寂しい文字が浮き出ている。

[core:notice] [pid XXXXX] AH000XX: child pid YYYYY exit signal Segmentation fault (11)

phpのpdoの仕様は知らぬのだけど、bindParamを2000近く設定するとsegmentation faultで落ちる模様。落ちる時と落ちない時があるようだが、負荷のない時でも落ちるし、webサーバはそんなに低スペックではない。php.iniの設定がずさんでメモリ割り当て値が著しく低い(または高い)わけではない。ゆえに謎現象。

そんないっぱい1回のクエリでつけるのかい!と言われればそれまでで設計が悪いということなんだけど、実行しているmysqlのクエリは、こんな感じです。


insert into tableA (column1)values(data1),(data2),(data3),(data4),(data5)
,(data6),(data7),(data8),(data9),(data10),(data11),(data12),(data13),(data14)
,(data15),(data16),(data17),(data18),(data19),(data20),(data21),(data22),(data23)
,(data24),(data25),(data26),(data27),(data28),(data29),(data30),(data31),(data32)
,(data33),(data34),(data35), ...

--以下数千データまで続く。

mysqlがこう書けるのだから1回のクエリで投げれば早いかもと勝手に思ったクソスクリプタでした。大きくても数千件のデータしか入ってこないんだからこれで問題ないと思ったらpdoモジュールが以外にクソ脆弱だった。いや、セキュリティの話じゃないから脆弱というのは言葉の選択間違えているか。。。…というかそれはどうでもいいけど、数千件のデータだったらそもそもこんなめんどくさいクエリではなく、クラシックなSQL文にすればよかったのだ。

結論:sql標準的な構文にしておくのがベスト。

あとgdbでsegmentation faultになるということをチェックするとか、c言語の特性をすっかんぴん忘れている&そもそも知らないことが徒となっていることにも自覚的になって、きちんとCから勉強しなおそうと思いなおしたのでした。勉学に励む秋の空。

PHPのprint_r関数のおかしな挙動に関するメモ

PHPのバージョンは5.4.16です。

print_r関数の第一引数にtrueを指定して実行すると、なぜか標準出力に1が出力されます。

戻り値ではなくて、標準出力です。

戻り値であれば、trueというブーリアンが整数型で出力された?のか、

などと捉えられなくもありませんが、標準出力ですから、あきらかに変。

第一引数にtrueを設定するというのはそもそもおかしい使い方ですが、

別にいれていけないわけでもないでしょう。

Webアプリ開発時に画面に1が出るだけで済むなら笑い話にもなろうとかというところだけど、

このバグを修正するのに少し時間がかかりました…。

jphpmailer.phpのStandardsエラーが出まくっている

Strict Standards: Declaration of JPHPMailer::setFrom() should be compatible with PHPMailer::SetFrom($address, $name = '', $auto = 1) in /export/sd206/www/jp/r/e/gmoserver/0/6/sd0321106/himawarik.jp/contact/stock/common/jphpmailer.php on line 26

www.himawarik.jp/contact/

ぐぐるといたるところでエラー吐いていることが確認できます。Web屋泣かせのエラー出力ですね。

エラーをオフにするという消極的な方法もありますがそれよりjphpmailer.phpの記述を直す方がよいでしょう。

継承元のメソッドと同数の変数を用意すればOKということで、setFromメソッドを以下のように書き換えるとエラーが消えます。

function setFrom($from,$fromname="",$auto=1){
...

こんな感じ。