2010-03-11 17 views
11

Nesne nesnesinin verilerini almak için bir nesneyi geçmenin bir yolu var mı? "Üst nesne" ile üst sınıfı anlamıyorum, ancak tam anlamıyla nesne. İşte bir örnek, bir javascripty Dünya :-) içinde: Ben alt nesne içinde ebeveynden tüm verilere erişmek olsaydıAna Nesne php'de

$parent->test = "hello world!"; 

$parent->child = new B(); 

harika olurdu: Şimdilik

class B{ 

//I know this doesn't exists, but it's what I wanted do do 
    function B(){ 
     $this->parent = $this->parent(); 
     echo $this->parent->test; //it would ouput "hello world" 
    } 
} 

benim çözümdür ana nesneyi çocuğa (referans olarak) aktarmak veya ana nesneyi global hale getirmek için. Daha iyi bir çözümünüz var mı?

Teşekkürler!

+0

o birbirlerine referanslarla sadece iki nesne var. onlara ebeveyn ve çocuk diyebilirsiniz. – Anurag

+0

Ailenin referansını almak için çocuğa neden ihtiyaç duyuyorsunuz? Ebeveynte çocuğun da erişime ihtiyacı olduğu bir şey var mı? Eğer öyleyse, çocuğa, ebeveyninden almayı denemek yerine, ihtiyaç duyabileceği her şeyi iletmek daha iyidir. – rojoca

+0

Ebeveynte bir "gizlilik nesnesi" var, sonra çocuğa ihtiyaç duyduğum bazı değişkenler ve bunların hepsini geçmek yorucu olurdu ... – AntonioCorrenti

cevap

21

sizin sınıfları yapısı dört yolu vardır,


Genellikle B'deki $ ebeveyne bir başvuru var otomatik

$parent->test = "hello world!"; 
$parent->child = new B(); 

çağırmak ve hiçbir yolu yoktur 1. Ebeveyn nesnesini Enjeksiyon ile toplayın, örn. nesne oluşturulduğu zaman bir ebeveyni olması gerekiyor

class B 
{ 
    private $parent; 

    public function __construct($parent) 
    { 
     $this->parent = $parent; 
    } 

    public function setParent($parent) 
    { 
     $this->parent = $parent; 
    } 

    public function accessParent() 
    { 
     $this->parent->someMethodInParent(); 
    } 
} 

kullanın yapıcı enjeksiyonu. Bu, numaralı ilişkisindedir ve çok gevşek bir bağlantı oluşturur. B'de kodlanmış bağımlılıklar yoktur, bu nedenle, örneğin bir Test Testini yaptığınızda bir Mock ile Ana Örneğini kolayca değiştirebilirsiniz. Bağımlılık Enjeksiyonunu Kullanma, kodunuzu daha iyi hale getirecektir. senin Usecase olarak

, sen B oluştururken B'ye $parent geçerdi:

$parent->child = new B($parent); 

2.Bu aynı zamanda bir olduğunu

class B 
{ 
    private $parent; 

    public function __construct() 
    { 
     $this->parent = new Parent; 
    } 

    public function accessParent() 
    { 
     $this->parent->someMethodInParent(); 
    } 
} 

Kullanım Kompozisyon ilişkisi-a vardır, ancak B noktasına çiftler Veli sınıfı Aynı zamanda değil, varolan Veli örneği, ancak yeni bir örneği bu. İfadeden, çocuğun yarattığı bir ebeveyne sahip olmak biraz garip geliyor. Bağımlılık, kök sınıfın dışında var sayılmayan, ancak temsil ettiği tüm şeyin parçası olan bir sınıf olduğunda bunu kullanın.

UseCase'iniz için, $parent->child = new B(); yapmanın hiçbir yolu yoktur ve $ parent'in bir Singleton olmadığı sürece, bu yaklaşımı kullanırken hangi üst öğenin olduğunu bilir. Eğer öyleyse, Singleton örneğini alabilirsiniz, ör. İstediğinizi elde etmek için Parent::getInstance(), ancak Singleton'un herkesin favori şekli olmadığını unutmayın. test etmek zor. Bir oluşturmak

3. Kullanım Kalıtım

class B extends Parent 
{ 
    public function accessParent() 
    { 
     $this->someMethodInParent(); 
    } 
} 

Bu yoludur-a ilişkisi. Tüm genel ve korunan yöntem ve özellikleri, Ana sınıftan (ancak belirli bir örnek değil) B'de kullanılabilir ve bunlara, B örneğinin $this anahtar sözcüğü aracılığıyla erişebilirsiniz. Eğer hiç Ana örneğini olması gerekmez gibi USECASE

, bu yaklaşım, çalışmıyor, ancak

$b = new B; 

4. Kullan oluşturulduğu zaman B Veli şeyi kapsülleyen geçerli kapsamdaki içine küresel anahtar kelime

class B extends Parent 
{ 
    private $parent; 

    public function __construct() 
    { 
     global $parent; 
     $this->parent = $parent; 
    } 

    public function accessParent() 
    { 
     $this->parent->someMethodInParent(); 
    } 
} 

global kelime ithalatı küresel değişkenleri. Genel olarak bir OO bağlamında you should avoid using the global keyword, ancak yukarıdaki diğer üç yöntemden birini, tercihen birinci olanı kullanın. Bu bir dil özelliği olsa da, birincisi için en yakın şey olsa da, -

$parent->child = new B(); 

Yine de, umarım yardımcı olur.

+0

bu çok garip – user151496

+0

Bu yazıyı güncel tuttuğunuz için teşekkürler, Gordon. Güzel. – Ricalsin

0

sayılı

Sen $ bu kullanarak üst sınıftan değişkenleri erişebilirsiniz:

<?php 
class A { 
    public function __construct() 
    { 
     $this->foo = 'hello'; 
    } 
} 

class B extends A { 
    public function printFoo() 
    { 
     echo $this->foo; 
    } 
} 

$b = new B(); 
$b->printFoo(); 
?> 
+0

Bu soru değildi. Üst sınıflara erişmek istemiyor. – Hinek

+0

Bu cevabın iyi olduğunu düşünüyorum ("Hayır"). Sjoerd ayrıca alternatif bir çözüm sunar. –

1

çocuğa daha iyi bir çözüm ana öğe olduğu geçirilmesi. Her ne kadar istenmeyen bir simbiyotik ilişki olsa da.

B(), bir öznitelik nesnesi hakkında herhangi bir bilgiye sahip olmalı mı? Muhtemelen daha fazla değil. Bunlar sadece kompozisyon ile gevşek ilişkilidir.

B() neden ebeveyninin bir özelliği olmalıdır? Bu uygulamayı B() 'de mi yoksa ebeveynin bir parçası mı olmalı?

+0

Geçiş nesnesinin normal olduğu bir ay javascript'ten sonra, bu durumda php'yi sadece "statik" buluyorum. Bazı özelliklerin öntanımlı olarak tanımlanmadığı ve ana denetleyici sınıfının bir alt nesne oluşturmayı tetikleyen bir yöntemi çağırdığı bir mvc çerçeveyi düşünün. Eğer Sjoerd tarafından "extends" yöntemini kullanırsam, yol üzerinde oluşturulan özelliklere ancak sınıfın üstünde tanımlanan özelliklere erişemem. – AntonioCorrenti

+0

Yani, oluşturduğunuz bilgileri tutan bir nesneyi geçmeniz gerekiyor mu? Belki de bu tasarımı yeniden birleştirmek için yeniden düşünmelisiniz - bağımlılık enjeksiyon kabı burada yardımcı olur mu? –

0

Eminim, PHP'nin böyle bir şeye sahip olmaması.

Ebeveyn nesnesini çocuğa geçirme çözümünüz en iyi çözümdür. Birden fazla ebeveynin aynı çocuğa sahip olmasını önlemek için, ebeveyn-mülkünüzü yalnızca çocuğun yapıcısı olarak belirlemeyi düşünmelisiniz.

:

1

Belki de bazı durumlarda yararlı olabilir: ana nesneyi ChildClass'a kurucunun çok erken, ancak bir adım sonra getirmez. Bu var olmayan bir yöntem yolunu kesmek için yeteneği ile oynuyor:

class ParentClass 
{ 
    const CHILD_PROPERTY_NAME = 'child'; 
    public $data = 'Some data'; 

    public function 
    __set($property_name, $property_value) 
    { 
     if ($property_name == self::CHILD_PROPERTY_NAME) 
     { 
      $property_value->set_parent_object($this); 
     } 
    } 
} 


class ChildClass 
{ 
    private $parent_object = null; 

    public function 
    set_parent_object($object) 
    { 
     $this->parent_object = $object; 
     echo $this->parent_object->data; 
    } 

} 


$p = new ParentClass(); 
$p->child = new ChildClass(); 

çıktısı verir Some data