Do You PHP はてブロ

Do You PHPはてなからはてブロに移動しました

PHPでJavaっぽく書く

ネタです。


PHPは C:Perl:Java:javascript=3:4:2:1でブレンドし、+αした言語なので、CとPerlJavajavascriptを知っといた方が良いと思う

に続けた


逆に (C|Perl|Java|javascript)の経験者なら、その言語っぽく書くこともできる

に対して、id:ZIGOROuさんから


@shimooka php で○○言語風に書くとこうなるってサンプル見たいー!

というreplyをいただいたので。

個人的に業務で使った言語が、(略)→PHPJavaPHP→(Java|PHP|Perl)と移っていったので、PHPだけじゃなくていろんな言語を知っておいた方が(何かと)役に立つことがあると思ってます。また、Javaの期間が結構長かった(JDK1.0/1.1〜1.4ぐらい)のと、同時期にPHPJavaの文法を積極的に取り入れていたので、どちらかというとJavaっぽく書いてるんじゃないかなぁ。というか、Javaをやってた頃のように書こうとしてます。

で、『PHPJavaっぽく書く』とこんな感じじゃないか、というのを並べてみました。

ハッシュじゃなくてオブジェクトを使う

たとえば、DBからユーザー情報を抜いてきたときに、ハッシュじゃなくてオブジェクトに格納。複数人の情報の場合、『オブジェクトの配列』にする。

<?php
// ハッシュの場合
$user = array('name' => 'foo', 'age' => '30');
echo $user['name'] . PHP_EOL;

// オブジェクトの場合
$user = new strClass();
$user->name = 'foo';
$user->age = 30;
echo $user->name . PHP_EOL;

クラスにpublicなプロパティが無く、accessorバリバリ

『ハッシュじゃなくてオブジェクトを使う』に続きますが、stdClassをそのまま使うことはないんじゃないかなぁ。仕事ではこういう書き方が多いです。

<?php
final class User
{
    private $name;
    private $age;
    public function __construct($name, $age) {
        $this->name = $name;
        $this->age = $age;
    }
    public function getName() {
        return $this->name;
    }
    public function getAge() {
        return $this->age;
    }
    public function __clone() {
        throw new RuntimeException ('Clone is not allowed against ' . get_class($this));
    }
}

$user = new User('foo', 30);
echo $user->getName() . PHP_EOL;

まあ、ここまでやると数が増えたときに面倒なんですが、いろいろなオブジェクトを持ち回すためのコンテナ的なオブジェクトを作ることがあります。

タイプヒンティングを積極的に使う

世間一般的にどうか分かりませんが、個人的には結構使ってます。現状はクラス名と配列を意味する『array』だけがサポートされていますが、『string』『int』『boolean』とかも欲しいぐらい。

<?php
class ProjectTeam
{
    private $members = array();
    public function add(User $user) {
        $this->members[$user->getName()] = $user;
    }
    public function getMembers() {
        return $this->members;
    }
}

$team = new ProjectTeam();
$team->add(new User('foo', 30));
$team->add(new User('bar', 35));
/**
 * PHP Catchable fatal error
 */
//$team->add(array('name' => 'foo', 'age' => '30'));

interface

適宜インターフェースを用意して、利用側のコードはインターフェースに対してプログラミングする、というものです。http://www.doyouphp.jp/phpdp/phpdp_02-2-1_factory_method.shtmlにあるReaderインターフェースと最終的なクライアントコード(DispMusic3.class.php)の関係を見ていただけると良いかも。

とりあえず、まとめ

改めて並べてみると、『オブジェクト指向を意識して書く』という感じですねぇ。。。orz まあ、PHPだと『共通関数』をまとめた数百KBもあるようなPHPスクリプトをrequire/includeするような書き方もできるわけですが、こういう書き方のほうがJavaっぽいんじゃないかと思います。
また、『最近のJavaはそんな書き方じゃなくてLLっぽくなってるよ』という意見もあるかも知れませんが、あくまで『Javaっぽく』ということで。
Lightweight Language』の『Lightweight』という意味からするとかなりメンドクサイ書き方になることは事実ですが、できることを『縛る』ことで変なバグ(配列の値を変えちゃったとか)に悩まされることが減る気がします。

残りのC、Perljavascriptはどなたかがやってくれるでしょう;-)


ちなみに、初めて触ったプログラミング言語はMZ系のHu-BASICです。Oh!MZとか月刊マイコンとかベーマガにお世話になりました。

追記(2010/03/18 14:50)

あー、これはやるわー。


@shimooka ネタエントリー拝見しました。個人的にはpublic static final int HOGE = 1 的なノリでconstをよく使うのですが(所属するクラスを明確にしたいので)、このあたり勝手にJavaらしいかも!と思っております。