二回目のPHP 5.4 Advent Calender用のエントリです。
今回はPHP 5.4より後のPHP(5.5かな?)で利用可能になると思われるAccessorの仕様について紹介します。まずはAccessorのおさらいから。
追記:この機能は投票で棄却されてしまいました。賛否両論が拮抗していたのですが、実装されなくて残念です。
PHP 5.3まで
class foo {
private $var;
function getVar() { return $this->var; }
}
などと書いてプライベートプロパティなどにアクセスするのがAccessorです。アクセサの良い部分はアクセスを制限できることです。この例の$this->varはリードオンリープロパティと同じ効果があります。
しかし、クラス、プロパティが沢山ある場合にこんな風に書くのは面倒ですし、機械的な作業の繰り返しになります。
PHP 5.4
PHP 5.4からはTraitsが使えるようになるため、繰り返し書かなくてもよくなります。
https://gist.github.com/1379592
<?php
// Example code how to eliminate getter and setter methods
// with traits introduced from PHP 5.4
trait Accessors {
public function __get($name) {
if ($this->r_property[$name])
return $this->$name;
else
trigger_error("Access to read protected property");
}
public function __set($name, $value) {
if ($this->w_property[$name])
$this->$name = $value;
else
trigger_error("Access to write protected property");
}
}
class OrderLine {
use Accessors;
private $r_property = array('price'=>1, 'amount'=>1);
private $w_property = array('price'=>0, 'amount'=>1);
protected $price;
private $amount;
private $tax = 1.15; // property without getter/setter
public function getTotal() {
return $this->price * $this->amount * $this->tax;
}
}
$line = new OrderLine;
$line->price = 20;
$line->amount = 3;
echo "Total cost: ".$line->getTotal();
?>
こんな感じです。これでも十分便利なのですが、Rubyにはリードオンリープロパティがあったり、C#には汎用的なアクセサの構文があります。
PHP 5.5以降
まだ構文が検討されている段階なので最終的にどうなるか分かりませんが、C#に近い感じのアクセサが実装される予定です。
class Foo
{
protected $name {
get { return $this->name; }
set { $this->name = $value; }
}
// ...
}
プロパティ名の後にブロックが定義できるようになり、get/setの処理が定義できるようになります。
単純なリードオンリープロパティに比べて、時間を秒に変換したり、価格を税率に合わせて税込価格にしたり、といった処理ができるのでとても便利です。書き込み時にも同様に処理が記述できます。get/setの処理がプロパティに近い場所で定義されるのでコードも読みやすくなります。
以下はそのパッチです。
https://bugs.php.net/patch-display.php?bug_id=49526&patch=accessor_v2.diff&revision=latest
以上、簡単ですがPHP 5.4とそれ以降のPHPでアクセサがどのように変わるのか紹介しました。