2012-03-28 108 views
1

我正在使用反射來調整對象中的各種值,並且我有一個對象是我需要調整的父對象。如何從PHP的外部對象本身獲取父對象?

例如:

class Ford extends Car 
{ 
    private $model; 
} 

class Car 
{ 
    private $color; 
} 

我可以很容易地使用反射來改變模型,但如何從孩子分開父母,讓我可以在父使用反射?

什麼我希望一些僞代碼是可能的:

$ford = new Ford(); 

$manipulator = new Manipulator($ford); 

$manipulator->set('model','F-150'); 
$manipulator->setParentValue('color','red'); 

class Manipulator 
{ 
    public function __construct($class) { 
     $this->class = $class; 
     $this->reflection = new \ReflectionClass($class); 
    } 

    public function set($property,$value) { 
     $property = $this->reflection->getProperty($property); 
     $property->setAccessible(true); 
     $property->setValue($this->class,$value); 
    } 

    public function setParentValue() { 

     $parent = $this->reflection->getParent(); 

     $property = $this->reflection->getProperty($property); 
     $property->setAccessible(true); 

     // HOW DO I DO THIS? 

     $property->setValue($this->class::parent,$value); 
    } 
} 

問題的要點是:

在這種情況下,我怎麼可以改變顏色$從外部對象?

是否有類似Ford :: parent()或get_parent_object($ ford)的東西?

注意

上面使用的對象是沒有確切的方案,但只是用來說明該概念。在現實世界的情況下,我有一個父母/孩子的關係,我需要能夠從外部訪問/更改每個值。

ANSWER

請檢查我的回答如下......我想通了。

+0

車應該有$模型屬性..它只是可以因爲它是私密的,所以不能訪問它。如果您在Car上使用反射並嘗試獲取$ model屬性,它是否會給您一個錯誤? – 2012-03-28 18:24:29

+0

我還沒試過。我會嘗試,但在這種情況下,這幾乎是無關緊要的,我想。上面使用的對象並不是確切的場景,只是用來說明這個概念。在現實世界的情況下,我有一個父母/孩子的關係,我需要能夠從外部訪問/更改每個值。 – johnnietheblack 2012-03-28 18:29:09

+0

PHP中的屬性沒有這種關係。你可以使用'parent :: myMethod()'來訪問父方法,但是你沒有看到屬性,因爲它們全都存在於同一個平面上..只有它們的範圍和可訪問性發生了變化。我可能完全錯誤地解釋了這個問題。如果你在Car/Ford例子中加入了(psuedo)反射代碼,它可能會有所幫助 – 2012-03-28 18:32:31

回答

3

經過廣泛的審查,我發現我無法訪問對象的父爲對象的對象本身之外。

但是,使用的反思,我是能夠解決上面的例子貼:

<?php 
class Car 
{ 
    private $color; 

    public function __construct() 
    { 
     $this->color = 'red'; 
    } 

    public function color() 
    { 
     return $this->color; 
    } 
} 

class Ford extends Car 
{ 
} 

$ford = new Ford(); 

echo $ford->color(); // OUTPUTS 'red' 

$reflection = new ReflectionClass($ford); 

$properties = $reflection->getProperties(); 
foreach($properties as $property) { 
    echo $property->getName()."\n>"; 
} 

$parent = $reflection->getParentClass(); 

$color = $parent->getProperty('color'); 
$color->setAccessible(true); 
$color->setValue($ford,'blue'); 

echo $ford->color(); // OUTPUTS 'blue' 

看到它在這裏的行動:http://codepad.viper-7.com/R45LN0

+0

謝謝!你救了我的一天! – 2017-04-07 12:55:48

1
+0

是啊,我已經看到了......但是這不只是得到父類的名字?我如何在上面的例子中利用它來改變汽車的顏色?謝謝! – johnnietheblack 2012-03-28 18:20:08

+0

這是一個私人財產,你不應該直接訪問它。使用getter/setter方法,如 class Car私有$ color: public function getColor(){return $ this-> color; } public function setColor($ newcolor){$ this-> color = $ newcolor; } } – brunobg 2012-03-28 18:23:53

+0

通常情況下,這將工作,但在這種特定情況下,我需要能夠從外部更改值,而無需以任何方式更改子類。這就是爲什麼我一直在使用Reflection。 – johnnietheblack 2012-03-28 18:26:02

0

下面是函數我answered your other question的靜態版本:

function getProperties($object) { 
    $properties = array(); 
    try { 
     $rc = new \ReflectionClass($object); 
     do { 
      $rp = array(); 
      /* @var $p \ReflectionProperty */ 
      foreach ($rc->getProperties() as $p) { 
       $p->setAccessible(true); 
       $rp[$p->getName()] = $p->getValue($object); 
      } 
      $properties = array_merge($rp, $properties); 
     } while ($rc = $rc->getParentClass()); 
    } catch (\ReflectionException $e) { } 
    return $properties; 
} 
1
function getPrivateProperty(\ReflectionClass $class, $property) 
{ 
    if ($class->hasProperty($property)) { 
     return $class->getProperty($property); 
    } 

    if ($parent = $class->getParentClass()) { 
     return getPrivateProperty($parent, $property); 
    } 

    return null; 
} 
+0

歡迎來到Stack Overflow!雖然這段代碼可能會解決這個問題,包括一個解釋[真的有幫助](http://meta.stackexchange.com/q/114762),以提高您的文章的質量。請記住,你正在爲將來的讀者回答這個問題,而不僅僅是現在問的人!請編輯您的答案以添加解釋,並指出適用的限制和假設。 – BrokenBinary 2016-11-01 23:41:31