2012-02-16 29 views
1

PHPでは読み取り専用のプロパティが実際に存在していますが、それらは認識していませんか?パブリックプロパティを読み取り専用にするにはどうすればよいですか?読み取り専用プロパティを設定できません

私はちょうどReflectionClassで遊んでいたし、プロパティを上書きしようとしたとき、私は、このエラーメッセージが表示されました:

$lol = new ReflectionObject($obj); 
$lol->name = 'awawawawa'; 
+0

ええ!プロパティはそのようには機能しません:私は魔法のゲッターとセッターでそれをシミュレートすることができますが、プライベート、プロテクト、パブリックです... –

+0

私は知っています。それらを読み取るだけにするために使用???明らかに彼らはそこに現れないのでゲッタではありません... – thelolcat

+0

ReflectionObjectは$ objの別のインスタンスでも、それに対するポインタでもないので、同じメソッド...それは$ objに関する情報を表示するために使用できる独自のプロパティとメソッドを持つReflectionObjectです。ReflectionObjectは$ objが行っても "name"という名前のプロパティ(publicまたはその他)を持ちませんこの値を変更することはできません。Reflectionが独自の方法で魔法のゲッタ/セッターを実装していると仮定しています。 –

答えて

1

Properties 

name 

    Name of the object's class. Read-only, throws ReflectionException in attempt to write. 

http://sk.php.net/manual/en/class.reflectionobject.php

あり多くは、彼らがこれを行う方法をではありませんが、私の推測では、それが明示的に書き込みを探していますということでしょうそれが反射を嘘にするように起こるのを止めることができます。

あなたが何か似て自分で行うことができます:ReflectionClassのドキュメントから

<?php 
class MyReadOnlyJunk 
{ 
    protected // over private, or not defined here at all 
     $name = 'My Name'; 

    public function __set($key, $val) 
    { 
     if($key == 'name') 
      throw new Exception('Cannot has name set!'); 
    } 
} 
?> 
+1

プロパティは存在するので、__setは決して起動しませんので、私はうまくいきません... – thelolcat

+0

はい、申し訳ありませんが、存在しない場合(メンバーメソッドが存在しない限り、それをまだ設定できるかもしれません) – phatskat

1

PHP docs:オブジェクトのクラスの

名前。読み取り専用で、書き込もうとしてReflectionExceptionをスローします。

私は物事が読み取り専用で、しかし...私は推測する可能性finalでそれらの前に付けることについてPropertiesページに何も表示されませんが、それが唯一の方法に言及していますので、それが許可されています場合、私は知りません。 ReflectionObjectのためのPHPマニュアルのページから

1

プロパティ
名クラスの
名前を。読み取り専用で、書き込もうとしてReflectionExceptionをスローします。

ただし、ドキュメントにもReflectionClassがPHPのコアの一部です(ドキュメントがReflectionClassは純粋なPHPで実装されているように見えても)ことを、ここで注意することが重要である

ReflectionClass implements Reflector { 
    /* Properties */ 
    public $ReflectionClass->name; 
    ... 

を言いますCで実装されています!

プロパティはと記載されていますが、実際にはそうではありませんが、通常の公有地であると文書化されています。

私はこのためにPHPのソースコードを掘り下げるのは面倒ですが、パブリックプロパティを保護して読み取り専用にする特別なケースがあります。編集:マークベーカーの答えを参照してください。反射クラスのコードから

2

/* {{{ _reflection_write_property */ 
static void _reflection_write_property(zval *object, zval *member, zval *value TSRMLS_DC) 
{ 
    if ((Z_TYPE_P(member) == IS_STRING) 
     && zend_hash_exists(&Z_OBJCE_P(object)->default_properties, Z_STRVAL_P(member), Z_STRLEN_P(member)+1) 
     && ((Z_STRLEN_P(member) == sizeof("name") - 1 && !memcmp(Z_STRVAL_P(member), "name", sizeof("name"))) 
      || (Z_STRLEN_P(member) == sizeof("class") - 1 && !memcmp(Z_STRVAL_P(member), "class", sizeof("class"))))) 
    { 
     zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
      "Cannot set read-only property %s::$%s", Z_OBJCE_P(object)->name, Z_STRVAL_P(member)); 
    } 
    else 
    { 
     zend_std_obj_handlers->write_property(object, member, value TSRMLS_CC);  
    } 
} 
/* }}} */ 

はとても基本的に、それが明示的に「名前」と「クラス」のプロパティのためにそれを禁止です。 クラスプロパティが存在することを示す表示が見つかりません。

関連する問題