PHP覚え書きブログ

【2012年02月06日】

PHPでオブジェクト指向しようと思っても、どうしても徹しきれない。
その一つの要因として、型がクラスではないという事が挙げられる。

これはオブジェクト指向としては致命的。

例えば型がクラスであると仮定すると、

<?php

$str = "あいうえお";
$sub = $str->substring(0, 3);
var_dump($sub);

?>

という感じになるのである。
変数を文字列で初期化した時点でその変数は文字列クラスのインスタンスを保持していることになる。
オブジェクト指向言語というのはだいたいこんな感じになっている。

しかし実際のPHPではこう。

<?php

$str = "あいうえお";
$sub = substr($str, 0, 3);
var_dump($sub);

?>

つまり変数は本当に文字列の値自体を保持しているもので、
当然メソッドなんてものは持たない。
なので標準関数に引数として文字列を渡して処理する。

例えば配列であればArrayObjectをarrayの代わりに使用することでオブジェクト指向らしい扱いが出来る。

しかし型そのものである文字列とか数値はどうしようもない。
どうしてもやろうとすると、文字列クラスを無理矢理作ることになる。

<?php

class String
{
    private $_value = '';

    public function substring($start, $length)
    {
        $str = substr($this->_value, $start, $length);
        return new String($str);
    }
}

$str = new String('あいうえお');
$sub = $str->substring(0, 3);

?>

こういうことをすれば表面的には完全オブジェクト指向的にすることは不可能ではない。

うーん、それにしても文字列を変数に代入するたびにnewしなくちゃならないなんて重苦しいことは嫌過ぎる。
これならどうだ

<?php

function str($string)
{
    return new String($string);
}

$str = str('あいうえお');
$sub = $str->substring(0, 3);

?>

関数を通す事で間接的に文字列インスタンスを取得する。多少軽量な感じがする。
でもやっぱり実質的に同じだ。しかも関数を使っていては何か本末転倒な気がする。

  • 標準関数は一切使わない
  • 全ての標準関数はラップクラス的なものを作ってそれを使用する
  • 文字列が引数である関数に対するラップメソッドは文字列の引数の代わりに文字列インスタンスを受け付けるようにする
  • 戻り値が文字列である関数に対するラップメソッドの戻り値は文字列インスタンスとする

しかしやっぱり何かと問題は出てくるだろうし、
PHPのメリットも薄れてくるだろう。

結局のところ、表面的にもPHPの完全オブジェクト指向化は難しい。
PHPはPHPらしく、割り切ってオブジェクト指向するべきということである。