ホーム > 日記 > PHP4でマジックメソッドを利用したい

PHP4でマジックメソッドを利用したい

4.3以降ではoverload関数を利用すればPHP5のように使えるらしい。
思ったよりも癖があり、詳細マニュアル見つかりませんでしたが。

ジェネレータなしのValueObjectを書かされて、萎えたので投げつけた。


<?php
class ValueObject
{
    var $_prop = array();

    function __get($prop_name, &$prop_value)
    {
        if (isset($this->_prop[$prop_name])) {
            $prop_value = $this->_prop[$prop_name];
        }
        return true;
    }

    function __set($prop_name, $prop_value)
    {
        $this->_prop[$prop_name] = $prop_value;
        return true;
    }

    function __call($func_name, $func_argv, &$prop_value)
    {
        // getter
        if (preg_match('/^get([a-zA-Z][\w_\-]*)$/', $func_name, $matches)) {
            $name = strtolower($matches[1]);
            return $this->__get($name, $prop_value);
        }
        // setter
        if (preg_match('/^set([a-zA-Z][\w_\-]*)$/', $func_name, $matches) && isset($func_argv[0])) {
            $name = strtolower($matches[1]);
            return $this->__set($name, $func_argv[0]);
        }
        // construct
        if (strcasecmp($func_name, get_class($this)) == 0) {
            return true;
        }

        return false;
    }
}

// 4.3.0 <= PHP <  5.0.0
overload('ValueObject');
$VO = new ValueObject;

var_dump($VO->name);    // null
$VO->name = 'yotsuba';
var_dump($VO->name);    // yotsuba

var_dump($VO->getAge());    // null
$VO->setAge(14);
var_dump($VO->getAge());    // 14
?>

不要なのは登録させたくないと文句いわれたので追加。
_prop_def配列にキーがなければエラー。
丸め込みできるように微妙なことしつつ。


<?php
class ValueObject
{
    var $_prop = array();
    var $_prop_def = array();

    function __get($prop_name, &$prop_value)
    {
        if (!array_key_exists($prop_name, $this->_prop_def)) {
            trigger_error("Unknown property [{$prop_name}]", E_USER_WARNING);
            return false;
        }
        if (isset($this->_prop[$prop_name])) {
            $prop_value = $this->_prop[$prop_name];
        }
        return true;
    }

    function __set($prop_name, $prop_value)
    {
        if (!array_key_exists($prop_name, $this->_prop_def)) {
            trigger_error("Unknown property [{$prop_name}]", E_USER_WARNING);
            return false;
        }
        $this->_prop[$prop_name] = $prop_value;
        return true;
    }

    function __call($func_name, $func_argv, &$prop_value)
    {
        if (preg_match('/^set([a-zA-Z][\w_\-]*)$/', $func_name, $matches)) {
            $name = strtolower($matches[1]);
            $value = isset($func_argv[0])? $func_argv[0]: null; 
            return $this->__set($name, $value);
        }
        if (preg_match('/^get([a-zA-Z][\w_\-]*)$/', $func_name, $matches)) {
            $name = strtolower($matches[1]);
            return $this->__get($name, $prop_value);
        }
        if (strcasecmp($func_name, get_class($this)) == 0) {
            return true;
        }
        return false;
    }
}

class MyValueObject extends ValueObject
{
    var $_prop_def = array(
        'name' => true,
        'age' => true,
    );
}

overload('MyValueObject');
$vo= new MyValueObject;

var_dump($vo->getName());
$vo->setName('yotsuba');
var_dump($vo->getName());

var_dump($vo->getAge());
$vo->setAge(14);
var_dump($vo->getAge());
?>

カテゴリー: 日記 タグ:
  1. コメントはまだありません。
  1. トラックバックはまだありません。