Locked History Actions

php/horibble

phpはヒドイ

phpのプログラムは本当にヒドイ。ヒドイ理由は三つある。

  • phpプログラムを書いてるやつがヒドイ
  • phpの言語仕様がヒドイ
  • php処理系実装が低レベル

以下、この三つの面から検証してみる。

phpプログラムを書いてるやつがヒドイ

phpプログラムを記述している者は、ほとんどがプログラミングの基礎的知識も持ちあわせていない、ド素人ばかりである。 これはもちろん私の経験上というだけの話であるが、しかし友人の話を聞いてみても、皆が皆口を揃えて言うのだから間違い無いところであろう。

どのようにヒドイかと言えば。。。。(これから記述予定)。

phpの言語仕様がヒドイ

メンバ変数・関数にアクセスするためには、必ず$this->を記述する必要がある

 function sample() { // ※1
 }

 class Test {
   private $a;
   function test() {
     $a = 2;
     sample();
   }
   function sample() {
   }
 }

などとし、test関数を呼び出すと、「private $a」には何も代入されない。 Testクラス内のメンバー関数内でメンバー変数にアクセスするためには「$this->a = 2;」とする必要があるのである。

ところが、「sample();」の方は、メンバー関数ではなく、※1を呼び出してしまう。 正しくは「$this->sample();」としなければならない。

このように、phpの「クラス」なるものは、およそスコープというものがデタラメなのである。

変数が勝手に作成されてしまう

さらに、「$this->」をつけていても、問題の発生する場合がある。 上記の例で、宣言されていない変数を参照することができてしまうのである。 つまり、「$this->abc = 2;」とすると、勝手にクラスのメンバとしてabcが宣言されてしまい、エラー等は発生しない。 このため、せっかくメンバ変数の宣言機能があるにも関わらず、何の役割も果たしていないと言ってよい。

メンバ関数の方はさすがに勝手に宣言するわけにはいかないので「$this->hello();」などとするとエラーが発生してしまう。

finallyが無い

tryにfinallyがない。

システム関数の挙動がいきなり変更されている

PHP 5.2まではsymlinkは相対パスが使えたが、5.3からは使えなくなっている。

コンストラクタ定義がいい加減

class Test {
  function test() {
    print "Hello";
  }
}
new Test();

このようなコードを書くと、Helloが表示される。なぜなら、クラス名と同じ名前を持つメソッドはコンストラクタと認識され、かつメソッドの大文字小文字は区別されないからだ。ところが、以下のように書くと

class Test {
  function __construct() {
  }
  function test() {
    print "Hello";
  }
}
new Test();

Helloは表示されない。

__construct()

は正式なコンストラクタなので、これがあるともはやtest()はコンストラクタとみなされなくなる。

クラスの継承をおこなう場合に、その書き順に注意しないとclass not foundになる。

これは明らかにバグと言えるが、少なくともphp5.1の時点では修正されていない。これを知らないとかなりハマることになる。

PHP処理系実装が低レベル

  • PHP処理系の実装自体も非常に低レベルにあり、とてもまともに使えるものではない。 以下はPHP5.3で経験する点。
  • require_onceに失敗すると、なぜかapacheのログに「an unknown filter was not added: PHP」というログが残される。どのrequire_onceが失敗しているのか一切不明。
  • やたらとSegmentation Faultが発生する。どのようなphpをプログラムを記述しようとも、これは本来「発生してはならない」はず。「mod_の組み合わせが悪い」などという言い訳をする御仁もいるが、全く理由にならない。ロクなTest Suiteを用意していない証拠。
  • 存在しないメソッドを呼びだそうとすると、何のエラーも出力せずに処理を中止してしまう場合がある。おそらくSegmentation Faultが発生しているものと思われるがはっきりとはわからない。