404 motivation not found | t_ishidaのブログ

2月/08

22

PHPではまり易かったところ

変数のスペルミス

PHPはどういう訳か変数宣言の強制が出来ない。はっきり言って、これはヒドイ。$date_timesを$data_timesや$date_time等とスペルミスしても突込みを入れてくれないので、何がおかしいのか分からなくてはまったりする。これは他の言語なら、動かす前に大体突っ込みを入れてくれるか、突っ込みを入れさせるための仕組みが用意されている。あのVBですらある。で、今の職場の先輩に教えてもらったのだが、PHPの場合は一応、有った。

こちらに詳しくあるので見てください。

use:strict みたいなの – もにっき

http://d.hatena.ne.jp/moto0215/20060525/1148525700

error_reporting(E_NOTICE|E_STRICT);

これを宣言しておくと、変数の変な使い方を通知してくれる。しかし、これが微妙。ハッシュのキーを引用符で囲んでないと、それも、「そんな定数宣言してねーだろ?死ねよ」みたいな突っ込みが有ったり。シンタックスエラーのチェック*1で引っ掛けてくれてなくて、あくまで実行時に「これ実はおかしいんじゃね?」って言うメッセージが表示されるだけ。まあ、無いよりはマシ??と、思って使ってみる。

文字コード

文字コードについては色んなところで書いてあると思うけど、自分の言葉でまとめた方が分かりやすくてね。ここに書くんだけど。って言ってもしっかり調べた訳でもなくて、ソースをハックした訳じゃないから、間違ってるかも。

文字コードって一口に言っても、気にしなきゃならんこといくつかある。

前提

PHPに内部コードらしきものとかは存在しない。どんな文字コードの文字だろうが変数には、そのまんまのバイト列が保存される。まあ、当たり前の話なんだけど、当たり前であるが故に忘れやすいから。

ソースコード中のリテラルの文字コードについて

前提の話を見ても、何がなんだか分からないと思うけど、この話見れば分かるかも。

つまり、

$xyzzy = 'ある晴れた昼下がり市場へ続く道';

って有ったら、僕らがエディタで見ている文字とか、内部コードとかは関係なしに、引用符から引用符までの間のバイト列をただ単に$xyzzyに放り込んでいる。つまり、そのソースを保存している文字コードで’ある晴れた昼下がり市場へ続く道’と表現されているバイト列って事ね。

まあ、要はソースコードを保存している文字コードそのまんまだよ。

だから、

  • ソースコードがSJIS
  • DBのクライアントエンコーディングがUTF8

の時、以下のコードはNGを返す

//id = 1のnameは太郎ね
$res = $db->query( "select name from t_1 where id = 1" );
$row = $res->fetchRow();

print $row[0] == '太郎' ? 'OK' : 'NG';

と言うこと。

PHPの外部からの入力について
  • POST値、GET値
  • DB
  • ファイル
  • http通信で得た値

ってところか?

この辺は相手が好き勝手な文字コードで送ってくる。これらの値は、mb_convert_encodingしてやる必要がある。

勘所(長くても読む気のある人編)

基本的に不定なところは外部からの入力になる。

何も細かい事を考えたくない場合には、上記を頭の片隅において以下の事に留意する。

  • 入力
    • ソースコードを保存する際の文字コードを統一する(これを基準にしとく)
    • 外部からの入力の有った値の文字コードを、基準となる文字コードにコンバートする。
      • ‘auto’はやめよう。’auto’もある程度の精度で変換してくれて、問題にはなりにくいかも知れないが、ソースを追うときに訳分からなくなりやすい。httpなら、ヘッダに文字コードを明記してくれている。DBやファイルならあらかじめ調べがつく
  • 出力
    • Webならヘッダに明記すれば好きな文字コードで出力してやれば良いことになっている。PHPは馬鹿みたいに、php.iniのdefault_charsetの値をそのまま突っ込んでしまう。これだと訳が分からなくなりやすいので、明示的にヘッダに出してやると良いだろう。
    • メールはヘッダに明記すれば好きな文字コードで出力してやれば良いことになっている。*2(以下ry
    • シェルに出力する場合には、シェルの文字コードに合わせて出力する必要がある。
    • DBに突っ込む時はDBのエンコーディングに合わせる必要がある

いずれにせよ、携帯相手の場合がネックになる。その場合は、不本意でも、SJISで統一して出してしまおう。

勘所(ちょっとなら読んでも良い人編)
  • ソースコードはUTF8にする
  • DBをUTF8で作る
  • default_char_setをUTF8にする

勘所(何も考えたくない人編)

日本語を使わない。

正規表現

はまる訳じゃないんだけどね、一応有用かなと。

能書きは書かないね。

<div id="test">
<p>aaaa</p>
<div id="test2">
aaaa
</div>
</div>

という値があるときに、id=”test2″のinnerHTMLを取得したい場合、

preg_match( '/<div id="test">(.+)<\/div>/msi', $html, $tmp );

ってやると、$tmp[1]が、”aaaa</div>”になってしまう。これは”+”が「強欲なマッチ」だから。

なので、この場合は最小マッチを使うと良い。

preg_match( '/<div id="test">(.+?)<\/div>/msi', $html, $tmp );

最小マッチは”+?”,”*?”となる。

PEAR::DB

とにかく、DB::isErrorだっけ?

アレ怪しい。

‘no error’とかで比べないと駄目だった気が。

*1:"php -l xyzzy.php"

*2:多少制限はある

Share and Enjoy:
  • Digg
  • del.icio.us
  • Google Bookmarks
  • Tumblr
  • email
  • Facebook
  • FriendFeed

RSS Feed

コメントはまだありません。

Leave a comment!

<< PSONクラス

Ethna >>

Find it!

Theme Design by devolux.org

Tag Cloud