PHPの標準関数は統一感がない
まずは、下記の関数を見てください。
htmlspecialchars(); // 単語の間に区切りがない
str_split(); // 単語の間に区切りがある
上記はいずれも標準関数ですが、決定的な違いがあります。
それは、 単語の間を アンダースコア( _ )で区切っているかどうかです。
我々は、この統一感のなさを真似するべきではないでしょう。
単語の区切りは、しっかりとルールに則って付けるべきです。
我々は、 単語間の区切りをどうやって表現するかを取り決め、それに沿ってコーディングする事が必要です。
キャメルケース・スネークケース・パスカルケース
単語の区切りを表現する方法として、代表的な3パターンを挙げます。
キャメルケース (camel case) 例 : htmlSpecialChars
複合語をひと綴りで表現し、次の単語の始まりを大文字で表す表現法です。
スネークケース(snake case) 例 : html_special_chars
単語の区切りをアンダースコア( _ )で表現する方法です。
パスカルケース(pascal case) 例 : HtmlSpecialChars
キャメルケースと似ていますが、最初の単語も大文字で表す事が特徴です。
私のお勧めは、 クラス名はパスカルケース、 変数名と関数名はスネークケースですが、いずれのルールを採用したとしてもしっかりとルールに則って書けば問題ありません。
しかし、クラス名は一般的に大文字で始まる事が多く、クラス名と変数名で違いを表現するために変数名にパスカルケースを採用するケースは多くありません。
略語の活用
下記の関数を見てください。
bin2hex(); // 2 = to
上記はphpの標準関数です。ここで知っておくべき事は、 2がtoを表すということです。
その他にも、 4がforを表すケースもあります。
このような略語は、関数名をコンパクトにする事に役立ちます。しかし、あまり浸透していない略語を用いる事は控えましょう。
プロジェクトによっては、 使用する略語を規定している 場合もあるかと思います。
長い関数名が嫌いな人は多いですが、他の人が理解出来る関数名を付ける事を第一に目指しましょう。
PHPの標準関数で使用されているような略語は、比較的浸透しているケースが多いです。
変数の型
下記は、C言語での変数定義です。
# 整数型
int i;
# 文字型
char c;
C言語やJAVAプログラムでは、変数に型を設定します。
整数型の変数には、整数以外の値は入れる事が出来ません。
しかし、PHPでは変数宣言で型を決めません。そのため、変数には自由に何でも入れる事が出来ます。
(メモ : PHP以外のLL(light weight language)言語でも、変数に型を定義しないことは多いです)
何でも入るというのは、メリットもある反面、その変数に何を入れるかはプログラム任せとなります。そのため、プログラムを追わないと何型の値が入っているかは分かりません。
トラブルの一例を挙げます。
- $id が整数型だと思っていたのに、実は文字列型で入っており、 is_int() チェックで弾かれてしまいエラーが発生した。
$id = "123";
var_dump(is_int($id));
結果: bool(false)
このようなトラブルはよくある事です。そのため、不具合を避けるために変数は他の言語と同じくある程度型を固定して取り扱いたいものです。
勿論、キャスト変換などのテクニックもありますが、今回は規約を検討してみましょう。
コーディング規約でトラブルの発生確立を減らすためには、
- 整数型の値を入れる変数は、変数名の最初に i_ を付ける
- 文字列型の値を入れる変数は、変数名の最初に s_ をつける
他にも、以下のような書き方など。
参考: http://www.webgeekly.com/tutorials/php/20-tips-you-need-to-learn-to-become-a-better-php-programmer/
$iNumber = 10; // For Integers
$sName = "Marc"; // For Strings
$fPi = 3.14159265; // For Floats
$aNames = array(); // For Arrays
$oUser = new User(); // For Objects
$bIsMember = false; // For Booleans
上記のようなルール付けにより、 全員が変数を同じ型として扱う事で、ある程度トラブルを予防する事が出来ます。 変数の型を意識する事は、バグを減らす近道であると言えるでしょう。
変数の型を固定しない方が良い場合
変数の型は固定した方が良いと述べましたが、勿論例外はあります。
// hoge を bar に変える再帰関数
function hoge2bar($hoge)
{
if (is_array($hoge)) {
foreach ($hoge as $key => $val) {
$hoge[$key] = hoge2bar($val);
}
} else if (is_string($hoge)) {
$hoge = str_replace('hoge', 'bar', $hoge);
}
return $hoge;
}
上記は、いわゆる再帰関数というものです。 配列にも文字列にも対応しており、非常に使い勝手の良い関数となっています。
(メモ : hogeをbarに変えたい人はいないかもしれませんが)
変数の型の違いをうまく扱えるようになれば、変数を自在に操れるようになる事でしょう。
複数形の使い方について
例えば、ユーザーの一覧を格納する配列を定義する場合、下記のようなパターンがあります。
$users = array(); // ユーザーを複数形にして一覧という意味を表現する場合
$user_list = array(); // 複数形にはせず、listで一覧という事を表現する場合
各自がそれぞれの自己判断で配列名を付ける事は、統一感を下げるだけです。
特に、配列名やDBにおけるテーブル名などにおいて複数をどう表現するかは、事前に取り決めてから開発した方が良いでしょう。
ゴミ変数に注意
PHPの特徴として、他の言語よりも変数のスコープが緩い事が挙げられます。
# 変数宣言にmyを付ける事により、$iはfor文の中でしか参照できない
for (my $i = 0; $i < 10; $i++){
print "count = $i ¥n";
}
// $iはfor文を抜けた後も残ってしまう
for ($i = 0; $i < 10; $i++) {
echo "count = $i ¥n";
}
PHPでは $i はループを抜けた後も残り続けるため、最終的にループを抜けた時の値、つまり「10」という値をループの外でも保持しています。
そのため、PHPでは一時的な使用と思っていた変数が思わぬ値を保持し続ける事により、想定外のトラブルが発生する可能性があります。
特に大規模なデータを入れた一時変数の場合は、残り続ける事によりメモリを無駄に占有してしまうため、最悪メモリリークの原因となる事もあります。そのため、特に大規模なデータを入れた一時変数の場合には、使い終わったら必ず unset() する事で変数を削除しておいた方が無難でしょう。
(メモ : 変数が自動で削除されるのは、スコープを抜けるタイミングです。例えば、PHPでは関数内で定義した変数は関数を抜けると自動で削除されます)
汎用変数の乱用はやめよう
よく用いられる汎用的な変数として、 $i (for文のカウンタ)、 $fp (ファイルポインタ)などがあげられます。
大事なのは、これら汎用変数に固執する必要はないと言う事です。特に、ファイルポインタは一度に複数開かれる事があります。
(メモ : Aファイルを読み込みながら、同時にBファイルとCファイルに書き込むなど)
この場合、安易に $fp2
や $fp3
などとつけてしまいがちですが、トラブルの元である上に可読性を著しく落としてしまいます。
同じ汎用変数が複数入り交じって登場する場合には、しっかりとした名前をつけてあげた方が良いでしょう。また、数十行に渡って使われるような息の長い変数の場合も、同じく名前をつけてあげた方が無難です。
まとめ
プログラムは、 変数、関数、クラス、構文で出来ていると言っても過言ではありません。これらを丁寧に扱う事が、良質なプログラマになる近道である言えるでしょう。
(メモ : 残念ながら筆者は良質なプログラマではありませんが)