PHP中是否存在实际的只读属性,我不知道它们?如何将公共属性设置为只读?
我正在玩ReflectionClass,我在尝试覆盖属性时收到此错误消息:
$lol = new ReflectionObject($obj);
$lol->name = 'awawawawa';
答案 0 :(得分: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);
}
}
/* }}} */
所以基本上,它明确地禁止它为“名称”和“类”属性。 我找不到任何类属性存在的迹象!
答案 1 :(得分:1)
对象类的名称。只读,在尝试编写时抛出ReflectionException。
我在Properties
页面中没有看到任何关于将内容设为只读的内容,但是......我猜可能会以final
为前缀,但我不知道是否允许这样做它只在方法上提到过。
答案 2 :(得分:1)
来自ReflectionObject的PHP手册页:
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
他们是怎么做的没有太多,但我的猜测是它明确地寻找name属性的写入并阻止它发生,因为它会使反射变为谎言。
你可以自己做类似的事情:
<?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!');
}
}
?>
答案 3 :(得分:1)
来自ReflectionClass的文档:
<强>属性强>
名称
班级名称。只读,在尝试编写时抛出ReflectionException。
然而,文档也说
ReflectionClass implements Reflector {
/* Properties */
public $ReflectionClass->name;
...
这里需要注意的是,(即使文档看起来ReflectionClass是用纯PHP实现的),ReflectionClass也是 PHP核心的一部分,因此在C中实现!
虽然该属性记录是一个普通的公共财产,但实际上并非如此!
我太懒了,不能深入研究PHP的源代码,但你会发现一个特殊的案例处理,它保护公共属性,使其成为只读。编辑:见Mark Bakers回答。