PHPについてよくやりがちな修正といつかやりそうな修正について、その解説をここにまとめましょう。
BEFORE: if ($count == 0 or $foo == 'bar') do_someting(); AFTER: if ($count == 0 || $foo == 'bar') do_someting();
if文などで使われる論理演算( a == b, a > b など ) に演算子「and」「or」が使われている場合、容赦なく「&&」「||」に修正します (^^;
OK: $dp = @opendir($dir) or die($dir . ' is not found or not readable.');
and / or 演算子は 代入文よりも後に評価されます。
'something or die()' という書き方はPerlでは普通に使われています。
BUG: $via_proxy = $use_proxy and via_proxy($arr['host']);
BEFORE: if (!bool) do_someting(); AFTER: if (! bool) do_someting();
今後のメンテナンスをふまえ、変数名・関数名の修正などを行う際にうっかり判定結果を反転させる事が無い様に、同様に参照渡しであるところの「&」を削ることが無い様に、極力スペースを挿入する様にしています (^^;
BEFORE: if (function_exists('gzfile')) { ... } AFTER: if (extension_loaded('zlib')) { ... }
特定のPHPエクステンションを要求している場合、それを明確に記述します。
このようにしておくと、コードを見た人間が「そうかウチの環境にはzlib入ってないや」などと即座に気付く事ができるようにもなります。
preg_replace("/\n/", '', $string) => str_replace("\n", '', $string)
preg_replace("/[\r\n]*$/", '', $line); => rtrim($line, "\r\n");
簡潔な文字列関数で表現できる操作(意図)についてはそのように記述すべきです。正規表現を利用する関数を用いる場合、正規表現を処理するため、一般的にオーバーヘッド(メモリとCPU)が大きくなります。
一方、正規表現関数を用いることでコードを手早く構築することができるでしょう。また、時間が豊富にあるならば、後で整理する事ができます。これはバランスの問題です。
BEFORE: $str = "strings"; $array = array["cmd"]; AFTER: $str = 'strings'; $array = array['cmd'];
(PHPの場合)単なる文字列を囲むのにダブルクォートを使っている場合、無条件でシングルクォートに直すことができます。一般的にダブルクォートは変数展開などが可能であるため、コンパイル時に無駄な処理が発生します。
BEFORE: $url = "$script?$r_page"; AFTER: $url = $script . '?' . $r_page;
同様に、変数を不必要にダブルクォーテーションの中に入れている場合、無条件で取り出すことができます。不要な変数展開を防ぐほか、PHPコードのシンタックスカラーリングが可能なエディタやデバッガでの可読性が向上します。
BEFORE: if(count($array)) AFTER: if(! empty($array))
BEFORE: if(count($array) == 0) AFTER: if(empty($array))
「配列の数が0かどうか」を比較している部分に count() を使っている場合、随時 ! empty() に置き換えます。(配列の数を最後まで数えさせる必要が無いため)
厳密には empty は必要ではありませんが、コード(行)の可読性が損なわれると判断しているため省略していません。
AFTER: if(! empty($array)) AFTER: if($array)
<?php // Code from PukiWiki // 現在時刻をマイクロ秒で取得 function getmicrotime() { list($usec, $sec) = explode(' ', microtime()); return ((float)$sec + (float)$usec); } // Init $count = array(); for($i = 0; $i < 10; $i++) $count[$i] = TRUE; // Bench start ----------------- define('MUTIME', getmicrotime()); // ---- //var_dump($count); for($i = 0; $i < 5000; $i++) { if (1) { if (count($count)) echo '- '; //if ($count) echo '- '; } else { if (! empty($count)) echo '- '; } } // ---- $taketime = sprintf('%01.03f', getmicrotime() - MUTIME); // Bench end ------------------- echo '<br/>' . 'HTML convert time: ' . $taketime; ?>
BEFORE: $page = array_key_exists('page', $vars) ? $vars['page'] : ''; AFTER: $page = isset($vars['page']) ? $vars['page'] : '';
多少早くなるという事以外に、「その配列の利用のされ方」を理解しやすくなるのが大きなポイントです。
※上下は省略
for($i = 0; $i < 5000; $i++) { if (1) { if (array_key_exists(0, $count)) echo '- '; } else { if (isset($count[0])) echo '- '; } }
主に文字化けが絶対に起きないようにするためのケア
BEFORE: mb_convert_kana($str, $option); AFTER: mb_convert_kana($str, $option, SOURCE_ENCODING);
BEFORE: mb_strlen($word_nm); AFTER: mb_strlen($word_nm, SOURCE_ENCODING);
BEFORE: mb_substr($word_nm, $pos, 1); AFTER: mb_substr($word_nm, $pos, 1, SOURCE_ENCODING);
PLUGIN_<プラグイン名(大文字)>_<[A-Z0-9][A-Z0-9_]+[A-Z0-9]>
function plugin_<プラグイン名(小文字)>_<[a-z0-9][a-z0-9_]+[a-z0-9]>