一般的に思われているのとは異なり、PHPはとても愛されている言語だ、と思う。
なにしろ、私がたまにPHPの良くない点を指摘すると、 たちまちホットエントリになる。またコメント欄にたくさんの反論をいただく。 びっくりだ。
それだけPHPという言語を愛している人やら、 PHPという言語の欠点を公に指摘されると自分自身がけなされたと感じる人が多い、 ということなのだろう。それはそれですばらしい。
しかし、一方で「指摘はもっともだ」というような声も散見される。 言語としての評価は分かれるということなのだろうか。
しかし、PHP使いの反論は、その多くがどうにも噛み合わない。 今後のためにも*1ちょっと分析して記録しておこうと思う。
たぶん、ここのPHPをHSPとかに置き換えても同じことが成立すると思う。
これが一番多い。たとえば、
えーと、幻を読むのは止めていただきたい。そんなこと書いてないじゃん。
どうやら、私はRubyという言語設計者なので 「他の言語を馬鹿にし、自分の言語を宣伝したくてうずうずしてる」という 脳内イメージが形成されているらしい。
が、もう15年も付き合っていて、必要なだけは十分に世間に知れ渡っているRubyを 今さら宣伝しても、私にはなんにもうれしくない。
「人は自分が持つであろう意図と動機を他人に見いだすのだ」と以前聞いたことがある。 とすると、これらの批判をする人たちはもし「自分の言語」を持ったとしたら 全力で他の言語をけなし、自分の言語を持ち上げるのだろうか。 というか、PHPが彼らにとっての「自分の言語」なのか、もしかして。やれやれ。
私は言語オタクとして、さまざまな言語の良いと思うところは良い、悪いところは悪いという 印象を自分の日記に記録する。公開しているんで読みたい人は読み、参考にできると思う人は 参考にする、それで良いと思う。
私がPHPを「イケてない言語」と発言しても、 たかがひとりのプログラマにそう言われただけじゃないか。 それでPHPユーザーが負け犬認定されるわけでもなし、 「そういうところもあるよね」と笑い飛ばせば良いと思う。
そうじゃない?
言語を比較するためには他の言語についてのある程度の知識が必要だろう。 Perlを知らずしてスクリプト言語を深く語るのは難しいし、 Lispの知識なくRubyを深く語ることは難しい。 Pythonは? うーん、PythonにはPythonの知識だよね(笑)
たとえばPHPしか知らないとしたら、PHPの欠点を指摘されると自分のやり方全体が 否定されたと感じるのではないだろうか。
なんとなく、他の言語も知っているが諸般の事情でPHPを使う、 という人は「批判はわかる」と言っているような気がする。 たとえば「Rauru Blog >> 悪いのはPHP自体じゃないかもしれないけど」とか。例に出して悪いけど。
もちろん、セキュリティホール作りこむ人はどの言語でも作りこむ、ってのは真実ぢゃろう。しかし何と言うかだな、PHP には、そういう人を呼び寄せる(あるいは居付かせる)何かがある、んぢゃなかろうかね。 似たような話として、perl で use strict しない 文化圏 にもそういう何かがあるという気はしてる。
弾さんの 「PHPなめんな」と「(Perl|Python|Ruby)をなめんな」の違い でも指摘されているように 私のPHP批判に怒っている人はあまり外のことを知らないで怒っているような気がするな。
もちろん例外はあるだろうけど。
たとえば「どの言語でも安全でないプログラムは書ける」とかは正論だ。誰も否定できない。 正しいことを断言すると気分は良いだろう。また正論で反論するってことは 相手を間違い認定するのと同義なので、ますます「勝った」感が強くなる。
でも、ちょっと待って? 反論している相手(この場合は私)は 本当にそんな正論で論破されるようなことを主張しているの?
この場合だと、たとえば「PHPでは安全なプログラムは書けないが、Rubyなら書ける」とか 私が主張していたらこの反論は有効だ。でも、私はそんなこと言ってないよね。
私が書いたのは「Webアプリケーションをちゃんと書くのは難しいから、 Webアプリ向け言語に初心者に優しいという宣伝文句を使うのは良くない」ということである。 ここについては、別にRubyがいいとかなんにも書いてないよね。 また、「どの言語でも安全でないプログラムが書ける」ということと対立もしない。
ついでに言うと「どの言語でも安全でないプログラムが書ける」ということと、 「どの言語でも安全なプログラムを書くのは同じくらい難しい」とは まったく違う。でも、このふたつが同じことのような印象を与えがちだよね。 これって詭弁だと思う。
ここからはRubyの宣伝にもなっちゃうんでエントリを換えよう。
*1 今後もPHPの欠点を指摘するつもりなのか
最初に繰り返して明言しておくが、 どんな言語だろうとなにも考えないで完全に安全なWebアプリケーションは書けない。 が、脆弱性を作りにくい言語(およびフレームワーク)機能というのはありえる。 たとえば
安全なメモリ管理
Cのような生のメモリ領域を使い、実行時の範囲チェックを行わない言語では 容易にバッファオーバーフローが起きる。RubyやPHPのように言語自体がメモリ管理を 行う場合(バグがない限り)安全。
パラメタ処理などの抽象化
ミスによる脆弱性を起こしがちな、 環境変数や標準入力からデータを切り出してくる処理やクッキー処理を手動で行わない。
テンプレートシステムによる出力
インジェクションなどの原因となる生の文字列操作でHTMLを構築することをできるだけ避ける。
ORマッパーによるデータベースアクセス
インジェクションの原因となる生の文字列操作でSQLを構築することを避ける。
データフロー追跡
RubyやPerlでは外部から入力された文字列にtaint(汚染)と呼ばれるマークがつく。 taintされた文字列から加工された文字列にもtaintがつく。 これをチェックすることで外部からの入力をチェック(サニタイズ)しないまま 危険な操作(ファイル名にする、systemを呼び出す、HTML/SQLに埋めこむ、など)を 禁止することができる。
落とし穴の多寡
たとえば、バイナリセーフ関数かそうじゃないかの違いのような 「落とし穴」に対して開発者が無関心かどうかは、最終的なプログラムの安全性に 影響する。言語ユーザが気をつけなくちゃいけないことも増えるしね。
もちろん、PHPでも各種フレームワークなどを最大限活用することで、 上のような機能を揃えることもできるだろう。そもそも「できない」って言ってるわけじゃない。 でも、CGI向け各種機能がビルトインされていて
htmlspecialchars($_GET['text']);
とかを普通にやっちゃう(しかも、それがゆえに初心者に優しいとかされてる)環境で 安全なソフトウェアを書くのは、他の言語に比べて大変困難であろう。
なんか間違ってる?