PHPのグローバルなユーザー定義関数の名前はスネークケースにするべきだと思う

  • 3
    いいね
  • 4
    コメント

前提

PSRには関数の命名規則について記載がない

PSRには、関数の命名規則についての記載がありません。
下の表のとおり、クラスとメソッドについては決められています。

項目 PSRでの命名規則 大文字小文字を区別
名前空間 記載なし 区別しない
クラス StudlyCaps (アッパー・キャメル) 区別しない
メソッド camelCase (ローワー・キャメル) 区別しない
関数 記載なし 区別しない
プロパティ 自由 (ただし統一すること) 区別する
クラス定数 大文字とアンダースコア 区別する
変数 記載なし 区別する
定数 記載なし 区別する

関数名は大文字小文字を区別しない

上の表のとおり、ケース・センシティブなのはプロパティ名と変数名、定数名だけです。
関数は、たとえBAZFUNCと定義していても、bazfunc()で正常に実行できます。
確認のために下記を実行してみてください。

<?php
namespace FOO\BAR;

class BAZCLASS
{
    public $BAZPROP = "プロパティ\n";
    const BAZCLASSCONST = "クラス定数\n";
    public function BAZMETHOD()
    {
        return "メソッド\n";
    }
}

$obj = new \foo\bar\bazclass();
echo $obj->bazmethod();
echo $obj->bazprop; // Noticeで警告される
// echo BAZCLASS::bazclassconst; // Fatal errorで処理が止まる

function BAZFUNC() {
    return "関数\n";
}

echo \foo\bar\bazfunc();

$BAZVAR = "変数\n";
echo $bazvar; // Noticeで警告される

define('BAZCONST', "定数\n");
echo bazconst; // Noticeで警告される

スネークケースを推す理由

get_defined_functionsが強制的に小文字で返しても影響が少ないから

定義済みの関数を配列で返すget_defined_functionsは、名前を全て小文字に変換してしまいます。

<?php
namespace FOO\BAR;

function BAZFUNC()
{
    return 'BAZ!';
}

$arr = get_defined_functions();
foreach ($arr['user'] as $val) {
    echo $val.'<br>'; // foo\bar\bazfunc と表示される
}

私の体験ですが、PHPフレームワークのLaravelで使えるグローバルな関数を確認しようとしてget_defined_functionsを実行したところ、doublevalueという関数を発見しました。
これの定義場所を知りたくてファイル横断検索をしたところ、何もヒットしませんでした。
これは、本来の関数名がdoubleValueで、さらに私が「大文字小文字を区別する」という設定で検索していたことが原因でした。
ものすごく発生確率の低いつまづきですが、それでもスネークケースでfoo_bar_bazのように定義しておけば、こんな些細なことでつまづくことはありません。

なお、上に挙げたグローバル関数のdoubleValueは、実際の処理はIsDouble::doubleValueメソッドに丸投げしているようで、名前を統一するために敢えてローワー・キャメルにしているのだと思います。

doubleValueはLaravelが公式に提供しているグローバル関数ではなく、Laravelが依存しているComposerパッケージで定義されているグローバル関数です。
「Laravelとしては本来なら隠してしまいたいんだろうけど、グローバルだから呼び出せてしまう」という状態です。
詳しくは下記をご覧ください。
:link: Laravel5.4: 公式ドキュメントでは言及されていないヘルパー関数

(補足) get_class_methodsはそのまま返す

get_defined_functionsと比べて、クラスメソッドを配列で返すget_class_methodsは、大文字小文字を変換せずそのまま返します。

<?php
namespace FOO\BAR;

class BAZCLASS {
    public function BAZMETHOD()
    {
        return 'BAZ!';
    }
}

$arr = get_class_methods('foo\bar\bazclass'); // 小文字でもOK
foreach ($arr as $val) {
    echo $val.'<br>'; // BAZMETHOD と表示される
}

get_defined_functionsは強制的に小文字。
get_class_methodsはそのまま。
これは、PHP開発者の「グローバル関数は当然スネークケースでしょ」という姿勢が無意識に反映されたのでは、と感じてしまいます。
もっとも、上の例のとおりget_defined_functionsは名前空間まで小文字にしてしまうので、その線は薄いと思いますが…。
ともかく、スネークケースならば余計なつまづきをひとつ減らせることは確かです。

PHPの組み込み関数やLaravelのヘルパー関数がスネークケースだから

:link: 組み込み関数の一覧(配列関連)
:link: Laravelのヘルパー関数

理由その1で今回言いたいことは全部言ってしまいました。
ただ、上のようにPHPの組み込み関数やLaravelのヘルパー関数(グローバルに使える)でもスネークケースなので、やはりグローバルなユーザー定義関数の名前はスネークケースにするべきだと思います。