PHPを書くときの注意点

もう3年もPHPでご飯を食べているわけですが、プログラムを書いているときに、いつも頭の片隅に置いている注意点というものを一回もまとめたメモに書いたことがないので、ここに羅列しておきます。

基本的に、PHP Manual に書いてあること丸飲みです。速さの部分など、自分で検証したわけではありませんので、ご了承ください。


文字列の置換には、str_replaceを使え

いろんなプログラムを書いていると、つい 文字列置換=preg_replace一択 と思考回路が作られがちですが、

(正規表現のような) 技巧的な置換ルールを必要としない場合、
ereg_replace() または preg_replace() の代わりにこの関数を常用するべきです。
http://jp2.php.net/manual/ja/function.str-replace.php

とあるように、単純な文字列置換の場合は、きちんと str_replace を使うようにしましょう。


ereg系よりpreg系

ereg系(POSIX拡張正規表現使用)もpreg系(PCRE,Perl互換の正規表現使用)も正規表現関係の関数群ですが、preg系のほうが速く動作する、とManualに書いてありますね。

ereg → preg_match
ereg_replace → preg_replace
などの変更をオススメします。


マルチバイト文字が入る可能性がある場合は、必ずmb系を使うこと

上2つで文字列関係操作について挙げましたが、str_replaceでもpreg_replaceでも、

xxx_replace($search, $replace, $subject)

の、$search 部分に、マルチバイトが来る場合は、2関数とも使ってはいけません。

str系も、preg系も、マルチバイトのことを考えずに真面目にヒットを狙ってくるので、1文字目の右側と、2文字目の左側に$searchが引っかかる場合もあるのです。

$replaced = str_replace(' ', '', 'あるふぁ〜');

さぁ、$replaced には何が入るでしょう?予想していた結果通りだったでしょうか?

マルチバイト文字が引数に(この場合は $search に)入ってくる場合は、mb系を使いましょう。
ただし、上と同じ文字列置換を行いたい場合でも、正規表現で以下のようにするしかありません。(私は、mb系で普通のreplaceに当たるものが見つけられないのですが、ありますかね?)

mb_ereg_replace($pattern, $replacement, $string)
http://jp2.php.net/manual/ja/function.mb-ereg-replace.php

マルチバイト文字は、気をつけていないと、予想してない動きを起こす元になっている場合が多いので、プログラムを書く前に、マルチバイト文字で置換・判断しないように、うまくロジック設計をすることが大事ですね。


splitよりexplode

split や explodeは、CSVやTSVなどのデータを、カンマ・タブ区切りで配列に格納するのに良く使います。どちらを使うかは、その人が先に知ったほうを使うのだろうと思いますが、

Perl 互換の正規表現構文を使用する preg_split() は、
往々にして split() よりも速い代替案となります。
正規表現の威力が必要ないのであれば、explode() を使用するほうがより高速です。
これは正規表現エンジンの オーバーヘッドを受けません。
http://jp2.php.net/manual/ja/function.split.php

だそうです。explode > preg_split > split という感じでしょうか。


配列のキーが在るかどうか調べるには

プログラムを書き始めた当初は、「配列のキーが在るか」という日本語のままに、array_key_exists() を使っていました。が、isset() を使って、

array_key_exists('foobar', $array)

isset($array['foobar'])

というように調べたほうが、高速なようです。(Manual下の議論より)
ただ、1つだけ、$array['foobar'] の中身が null でセットされている場合は、issetでは存在をつかめません。その点だけ注意です。


単純配列に値を突っ込む

array_push($data, $var);

でしょ?とお思いの貴方。

$data[] = $var;

という方法があるのです。というか、array_pushの中身はこれです。Manualを良く読みましょう。
http://jp2.php.net/manual/ja/function.array-push.php


単純配列なのか連想配列なのか、きっちりしなさい!

これは、PHPに限らず、プログラミングの基礎みたいなものでしょうが…

PHPは、配列とハッシュの区別がありません。単純配列も、キーが0から始まる整数である連想配列になってしまっているので、プログラムする際に、配列の中にデータを投げ込む際、

$data[] = 'a';
$data['foo'] = 'bar';

と、単純配列と連想配列を混ぜて投げ込むと、あとでこの配列を使う人が、困ってしまいます。(困るレベルなのか)
配列を作成する際は、どちらかに統一しましょう。ね?

(声小さく)ついこの間、配列を受け取り、それをJSONに変換する関数を書いたのですが、受け取った配列が、単純配列か連想配列かを見分ける方法に困り、仕方なく、キーが全て整数だったら単純配列とみなす、という格好悪い方法を取らざるを得ませんでした。http://jp2.php.net/manual/ja/function.array-keys.php この下の議論でも同じネタが上がっていて、苦笑してしまいました。いやはや…



以上、ざっと思いついただけでこの7点でしょうか。
文字列関連と、配列だけに偏ってますね。
そんなに仕事で困ってたんですかね?よく分かりませんね(^^;


いかがでしょう。へぇ、と思う方が少しでもいれば幸いです。