私は仕事でも趣味でもPHPをよく使います。「PHPといえばウェブ」と考える人は多いと思いますが、私が主に使うのはコマンドラインです。ウェブも少しだけならやりますが、決して主流とはいえないでしょうね。

PHPの専門家からすれば、私なんかは素人に毛が生えた程度で、かつ邪道そのものですが、今回はそんなPHPについての話題です。

タイトルにも掲げましたが、PHPは難しすぎますね。世間的には、PHPは簡単だというのが多数派の意見のようですが、私は決してそうは思いません。むしろ、CやC++のほうがずっと簡単です。

ここで確認しておきたいことがあります。「複雑」ということと「難しい」ということは同じではありません。また、「手間がかかる」ということと「難しい」ということも同じではありません。

C++は複雑ですがPHPほど難しくはありませんし、Cは手間がかかりますがPHPほど難しくはありません。PHPの何が難しいかというと、マニュアルを読み解くのが難しいのです。

たとえば、「整数のオーバーフロー」についてです。マニュアルでは、次のように書かれています。

integer型の範囲外の数を指定した場合、代わりに floatとして解釈されます。また、結果が integer型の範囲外の数となるような計算を行うと floatが代わりに返されます。

これを読んで、PHP_INT_MAX << 1がfloat型になってくれると期待したのですが、実際にはそうはなりません。別のところに、

<< および >> 演算子のオペランドとその結果は、常に integer として扱います。

と書かれています。

実際に(var_dump(PHP_INT_MAX << 1);を)試してみると、Windows 10の環境ではint(-2)になりました。CやC++の場合、正の値を持つ符号付き整数が左シフトによって表現範囲を超えた場合は未定義の動作になるので、こういう結果であっても合点がいきます。けれども、PHPについては、マニュアルからこのような結果を予想することは(どんな実装になっているか想像することはできますが)困難です。

うーむ、難しすぎます。PHPはきっと言語処理系のソースコードを読み解くことが前提になっているんでしょうね。

ほかの内容についても考えてみましょう。やはり、ビット演算子のところですが、

&| そして ^ 演算子の左右のオペランドが文字列の場合、その演算は、 文字列を構成する文字の ASCII 値を使って行います。その結果は文字列になります。 それ以外の場合は、左右のオペランドを integer に変換 し、結果も integer になります。

上のように、なぜか&、|、^に<em>タグが付いていて斜体になっています。そりゃあ、「ビット演算子といってるんだから除算演算子ではないことは分かれよ」ということかもしれませんが、油断すると間違います。実際私は間違いました(笑)

そして、「文字列を構成する文字の ASCII 値を使って行います」とのことなので実際に試してみました。

とすると、結果はstring(4) “堊字”でした。

ASCII値をORして、どうやれば“堊字”という結果になるのでしょうか? この結果をマニュアルだけから予想するのは不可能です。

ほかにもたくさんあるのですが、今日はこれぐらいにしておきましょう。

それにしても、こんなに難しいPHPを使いこなしているプログラマーは、とんでもなく優秀だということがあらためて分かりました。私にはとても使いこなせそうにないので、コマンドラインでチョロチョロっと使うだけにとどめておきたいと思います。