PHPでは読み取り専用のプロパティが実際に存在していますが、それらは認識していませんか?パブリックプロパティを読み取り専用にするにはどうすればよいですか?読み取り専用プロパティを設定できません
私はちょうどReflectionClassで遊んでいたし、プロパティを上書きしようとしたとき、私は、このエラーメッセージが表示されました:
$lol = new ReflectionObject($obj);
$lol->name = 'awawawawa';
PHPでは読み取り専用のプロパティが実際に存在していますが、それらは認識していませんか?パブリックプロパティを読み取り専用にするにはどうすればよいですか?読み取り専用プロパティを設定できません
私はちょうどReflectionClassで遊んでいたし、プロパティを上書きしようとしたとき、私は、このエラーメッセージが表示されました:
$lol = new ReflectionObject($obj);
$lol->name = 'awawawawa';
:
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!');
}
}
?>
PHP docs:オブジェクトのクラスの
名前。読み取り専用で、書き込もうとしてReflectionExceptionをスローします。
私は物事が読み取り専用で、しかし...私は推測する可能性final
でそれらの前に付けることについてProperties
ページに何も表示されませんが、それが唯一の方法に言及していますので、それが許可されています場合、私は知りません。 ReflectionObjectのためのPHPマニュアルのページから
:
プロパティ
名クラスの
名前を。読み取り専用で、書き込もうとしてReflectionExceptionをスローします。
ただし、ドキュメントにもReflectionClassがPHPのコアの一部です(ドキュメントがReflectionClassは純粋なPHPで実装されているように見えても)ことを、ここで注意することが重要である
ReflectionClass implements Reflector {
/* Properties */
public $ReflectionClass->name;
...
を言いますCで実装されています!
プロパティはと記載されていますが、実際にはそうではありませんが、通常の公有地であると文書化されています。
私はこのためにPHPのソースコードを掘り下げるのは面倒ですが、パブリックプロパティを保護して読み取り専用にする特別なケースがあります。編集:マークベーカーの答えを参照してください。反射クラスのコードから
:
/* {{{ _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);
}
}
/* }}} */
はとても基本的に、それが明示的に「名前」と「クラス」のプロパティのためにそれを禁止です。 クラスプロパティが存在することを示す表示が見つかりません。
ええ!プロパティはそのようには機能しません:私は魔法のゲッターとセッターでそれをシミュレートすることができますが、プライベート、プロテクト、パブリックです... –
私は知っています。それらを読み取るだけにするために使用???明らかに彼らはそこに現れないのでゲッタではありません... – thelolcat
ReflectionObjectは$ objの別のインスタンスでも、それに対するポインタでもないので、同じメソッド...それは$ objに関する情報を表示するために使用できる独自のプロパティとメソッドを持つReflectionObjectです。ReflectionObjectは$ objが行っても "name"という名前のプロパティ(publicまたはその他)を持ちませんこの値を変更することはできません。Reflectionが独自の方法で魔法のゲッタ/セッターを実装していると仮定しています。 –