[PHP-dev 1507] 新潟アクセス修飾子ってのを作りました

rti super.rti @ gmail.com
2010年 5月 22日 (土) 06:20:44 JST


始めまして。rtiと申します。
php 5.3.2を改造して、クラスの外から読めるけど書けないアクセス修飾子を実装しました。
http://d.hatena.ne.jp/rti7743/20100520/1274309263


これを利用すると、 getter を書く手間がなくなります。
また、 $obj->getVal() ではなく、 $obj->Val; 形式でアクセスできます。
それでいて、オブジェクトのカプセル化を一切破壊しません。

こんな感じで指定すると、、、

class Human{
   niigata $Age;	//これです。クラス外から読めるけど書けない。

   public function
            __construct($age,$name)
   {
       $this->Age = $age;
       //略
   }
};

//コレできても、
echo $HumanObject->Age;

//これはできない
$HumanObject->Age = 100;
// Fatal error: Cannot access niigata property Human::$Age in
// /home/rti/lab/php-5.3.2/a.php on line 13


getter がたくさんあるクラスで利用すると効果は抜群です。


//非新潟のコード
//無意味なgetterの連続
class Human{
   private $Age,$Name,$Address,$Tel;

   public function
            __construct($age,$name)
   {
       $this->Age = $age;
       //略
   }
   public function getAge(){
       return $this->Age;
   }
   public function getName(){
       return $this->Name;
   }
   public function getAddress(){
       return $this->Address;
   }
   public function getTel(){
       return $this->Tel;
   }

};

↓新潟ライズ


//新潟なコード
class Human{
   niigata $Age,$Name,$Address,$Tel; //これ

   public function
            __construct($age,$name)
   {
       $this->Age = $age;
       //略
   }
};


実装は簡単に言うと zend_object_handlers.c の zend_verify_property_access に引数
writable を追加して、
読み込み時は、 public のように振舞って、書き込み時は private のように振舞っています。

static int zend_verify_property_access(zend_property_info
*property_info, zend_class_entry *ce , int writable TSRMLS_DC) /* {{{
*/
{
	switch (property_info->flags & ZEND_ACC_PPP_MASK) {
		case ZEND_ACC_PUBLIC:
			return 1;
		case ZEND_ACC_PROTECTED:
			return zend_check_protected(property_info->ce, EG(scope));
		case ZEND_ACC_NIIGATA:
		    if (!writable)
			{
				return 1;
			}
		case ZEND_ACC_PRIVATE:
			if ((ce==EG(scope) || property_info->ce == EG(scope)) && EG(scope)) {
				return 1;
			} else {
				return 0;
			}
			break;
	}
	return 0;
}


PHP-dev メーリングリストの案内