PHP在父级中访问子级的私有属性
Posted
技术标签:
【中文标题】PHP在父级中访问子级的私有属性【英文标题】:PHP Accessing a child's private properties in parent 【发布时间】:2011-03-29 21:20:49 【问题描述】:我有一个父对象,用于在我的应用程序中进行一般 CRUD - 它具有基本的保存和检索方法,因此我不必将它们重新包含在我的所有对象中。我的大多数子对象都扩展了这个基础对象。这工作正常,但我发现检索序列化子对象存在问题。我在创建子对象实例的父对象中使用“检索”方法,然后从未序列化子对象的属性中填充自身 - 这意味着可以“自我反序列化”对象。
唯一的问题是 - 如果子对象具有受保护或私有属性,则父对象无法读取它,因此在检索期间不会被拾取。
所以我正在寻找一种更好的“自我反序列化”方法,或者一种允许父对象“看到”受保护属性的方法 - 但仅限于检索过程中。
代码示例:
BaseObject
protected $someparentProperty;
public function retrieve()
$serialized = file_get_contents(SOME_FILENAME);
$temp = unserialize($serialized);
foreach($temp as $propertyName => $propertyValue)
$this->$propertyName = $propertyValue;
public function save()
file_put_contents(SOME_FILENAME, serialize($this));
class ChildObject extends BaseObject
private $unretrievableProperty;
public setProp($val)
$this->unretrivableProperty = $val;
$tester = new ChildObject();
$tester->setProp("test");
$tester->save();
$cleanTester = new ChildObject();
$cleanTester->retrieve();
// $cleanTester->unretrievableProperty will not be set
已编辑:应该说“私人”不受保护的子属性。
【问题讨论】:
【参考方案1】:解决此问题的最佳方法是使用反射。 示例:
$_SESSION[''] = ''; // init
class Base
public function set_proxy()
$reflectionClass = new ReflectionClass($this);
$ar = $reflectionClass->getDefaultProperties();
!isset($ar['host']) or $_SESSION['host'] = $ar['host'];
class Son1 extends Base
private $host = '2.2.2.2';
class Son2 extends Son1
$son1 = new Son1();
$son1->set_proxy();
var_dump($_SESSION); // array(2) [""]=> string(0) "" ["host"]=> string(7) "2.2.2.2"
unset($_SESSION);
$_SESSION[''] = ''; // init
$son2 = new Son2();
$son2->set_proxy();
var_dump($_SESSION); // array(1) [""]=> string(0) ""
【讨论】:
【参考方案2】:试试这样:
abstract class ParentClass
protected abstract function GetChildProperty();
public function main()
$value = $this->GetChildProperty();
class ChildClass extends ParentClass
private $priv_prop = "somevalue";
protected function GetChildProperty()
return $this->priv_prop;
【讨论】:
【参考方案3】:似乎同一类可见性策略不适用于继承/父类。 php 文档没有解决这个问题。
我建议您将检索方法声明为静态,并通过静态调用而不是您当前的“自我反序列化”方法获取 $cleanTester。
static function retrieve()
$serialized = file_get_contents(SOME_FILENAME);
return unserialize($serialized);
[...]
$cleanTester = BaseObject::retrieve();
或者您可以利用__get()
方法访问不可访问的属性...我相信这可以添加到BaseObject
类并从子类中获取受保护的属性。由于相同的类可见性策略应适用于 BaseObject
,因此您可以定义 __get()
方法 private 或 protected。
BaseObject
private function __get($propertyName)
if(property_exists($this,$propertyName))
return $this->$propertyName;
return null;
【讨论】:
谢谢。静态方法似乎是可行的——但事实上,一些子对象需要被实例化,并在它们可以计算出应该从中检索的文件名之前进行一些处理。 __get 已经被使用了,几乎就是为了这个目的——但是当我遍历对象的属性时,父级再次不知道要请求什么属性。我想我需要看看迭代方法 - 感谢指针。【参考方案4】:子对象中的 getProperty() 函数如何返回 $this->unretrievableProperty
【讨论】:
谢谢 - 好主意,但由于 baseobject 不知道孩子的属性,它不知道要求什么以上是关于PHP在父级中访问子级的私有属性的主要内容,如果未能解决你的问题,请参考以下文章
css父级没包住子级是怎么回事,我用firebug查看,确实在父级的div中,但是就是没有包括子级的内容