php nesne nesnenin içinde, üst düzey nesne örneğini almak

9 Cevap php

PHP OOP ile deney yaşıyorum

Ben dışarı bulmaya çalışıyor ettiğimi, bu nesne örneği oluşturulan bir nesne withing bir nesne örneğini erişmek mümkün mü?

kafa karıştırıcı geliyor, işte bir örnek:

indeksi içeriğini


    class mainclass {
        var $data;
        function __construct($data){
            $this->data = $data;
        }
        function echodata(){
            echo $this->data;
        }
        function start($classname){
            include $classname.'.php';
            $inner = new $classname();
            $inner->show();
        }

    }

    $mainclass = new mainclass('maininfostuff');
    $mainclass->start('innerclass');



    //i want it to echo "maininfostuff"

innerclass.php içeriğini


class innerclass{
        function show(){
            mainclass->echodata();//the problem is here
        }
}

Bu test davanın amacı / MainClass echodata işlevi çalıştırmak için zaman eğer iç sınıf karar yapmaktır

nasıl Yukarıdaki örnekte yapılabilir? (Statik sınıflar veya tekil veya genişletilmiş sınıflar dayanmadan)

edit: due to some confusion in answers i have edited the example

9 Cevap

Iç sınıflar PHP mümkün değildir. Yani MainClass içinde innerclass ilan edemez. Bunu yapamazsınız çünkü, sen de olabildiğince dış sınıflar değişkenleri erişmek için bir yol, örneğin, Java var.

Bunu yerine bunu yapabilirsiniz:

 class mainclass {
     var $data;
     function __construct($data){
         $this->data = $data;
     }
     function echodata(){
         echo $this->data;
     }
     function start(){
         $inner = new innerclass();
         $inner->show($this);
     }

 }
 class innerclass{
     function show($mainclass){
         $mainclass->echodata();//the problem is here
     }
 }

 $mainclass = new mainclass('maininfostuff');
 $mainclass->start();

Dış sınıfa erişmek için iç sınıf için tek yolu iç sınıfının yapıcı geçirilecek dış örneğin ve bir örnek değişkeni kaydedilmiş olması içindir.

Ben şahsen bir class önce başka bir sınıfın yöntemleri içinde tanımlanan görmedim, bu yüzden aslında hepsi çalışıyor eğer, ben çok şaşırdım. (Ben ... zaten sen / Bu ihtiyaç isterdim neden hakkında daha fazla şaşırdım, ama)

Bunu oluşturmak zaman sadece iç nesne akım (dış) nesne geçmek.

class InnerClass {
    var $outer;
    function __construct(&$outer) {
        $this->outer = $outer;
    }
    function someStuff() {
        $this->outer->doStuff();
    }
}

$innerObj = new InnerClass($this);

Hayır, iç clases PHP değildir.

"Işlevselliği diğer dillerde zaten mevcuttur, ancak soru PHP gerekli olup olmadığıdır. Kısa cevap hayır. PHP yürütme model, daha da yavaşlatmak ve PHP derleme kabartmak istiyorum" dedi. - http://jacobsantos.com/2006/general/dont-advocate-subclasses/comment-page-1/

Bu yapmanız gerekir gibi görünüyor:

class mainclass {
    var $data;
    function __construct($data){
        $this->data = $data;
    }
    function echodata(){
        echo $this->data;
    }
    function start(){
        class innerclass(){
            var $mainclass;
            function __construct($mainclass) {
                $this->mainclass = $mainclass;
            }
            function show(){
                $this->mainclass->echodata();//the problem is here
            }
        }
        $inner = new innerclass($this);
        $inner->show();
    }

}

$mainclass = new mainclass('maininfostuff');
$mainclass->start();

Ama bu PHP bunu yapamazsınız gibi görünüyor:

Fatal error: Class declarations may not be nested in test.php on line 11

Yani MainClass dışarı iç sınıf ayıklayın.

Hayır başka bir nesnenin bir üyesi olarak bir nesne oluşturduğunuzda:

$this->my_new_object = new classname(a,b,c);

üst öğe erişmek için bir yol benim bilgi yoktur. Sen bunu oluşturduğunuzda nesneye ana öğeye bir başvuru geçmek zorunda olacaktır:

class innerclass(){

  private $parent; // Reference to the parent object

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

function show(){
   $this->parent->echodata();
  }
 }

A class definition, though, should never ever reside in a function, even though it may be possible. Class definitions can have a hierarchy - they can extend each other. But that is invoked using extends. A class can extend another. Their definition is still side by side, they are not nested in the code.

Sana is bir sınıfın genişletilmesi için ne arıyor belki yapmaya çalışıyorsun biliyorum, ama yok. Bu durumda, parent anahtar sözcüğünü kullanarak ebeveyn tanımlanan işlevleri ve değişkenleri erişebilirsiniz:

function show(){
parent::echodata();
}

Ancak, şu anda ne yaptığınızı temelde farklı bir şeydir.

Bana önemli bir satırı ele alalım:

mainclass->echodata();//the problem is here

PHP, infix nesne erişim operatörünü kullanmak amacıyla (->) sol taraftaki argüman (en az biri $ tarafından önüne) bir değişken olmalı ve bir örnek olmalıdır bir sınıfı, örn $myClass->whatever ya da $this->foo.

Başka bir dilden geliyor ve statik erişim düşünüyorsanız, size ::, eg doğru operatörü kullanmanız gerekir someClass::$someValue ya da someClass::SOME_CONST.

Eğer ısrarla çocuğun kurucusuna "üst" nesne geçen karşıyız Şimdi eğer o, size statik yerde kod adlı üst sınıf (yalnızca) örneğine erişmek için izin verecek bir tek desen, dahil düşünebiliriz alt nesne.

Ama cidden, sadece yapıcı bir argüman olarak geçmesi ve başka birilerinin söylediği gibi, bu işlev başka bir sınıfın bir üyesi kendisi, özellikle, bir işlev içinde sınıfını tanımlamak gerekmez. Bu işlevi iki kez çağrılır ise, ölümcül bir hata alırsınız.

EDIT

İşte ben neden bahsettiğimi bir örnek:

class mainClass {
    private static $instance = null;
    private $data = null;

    private function __construct($setData) {
        if (!is_null($setData)) {
            $this->data = $setData;
        }
    }

    public static function getInstance($setData = null) {
        if (is_null(self::$instance)) {
            self::$instance = new mainClass($setData);
        }
        return self::$instance; // objects will always be passed by reference
    }

    public function echodata() {
        echo $this->data;
    }

    public function start() {
        $inner = new innerClass;
        $inner->show();
    }
}

class innerClass {
    function show() {
        mainClass::getInstance()->echodata();   
    }
}

Sonra çalıştırın:

$foo = mainClass::getInstance('Foo');
$foo->start(); // prints "Foo"

Sen koduyla statik olmayan bir statik yöntemi çağırmak için çalışıyorsunuz

mainclass->echodata();//the problem is here

Bunun yerine, mainclass alt sınıf örneğine geçmek gerekir:

 <?php

 class innerclass(){
     function innerclass($parent) {
         $this->_parent = $parent // hold onto our parent
     }

     function show(){
         $this->_parent->echodata();
     }
  }

  // ....

  $inner = new innerclass($this);
  $inner->show();
  ?>

Bunu yapmak için daha fazla yollar buldular

class innerclass{
        function show(){
            mainclass::echodata();
        }
}
class mainclass {
    var $data;
 protected static $_instance;
    function __construct($data){
        $this->data = $data;
        self::$_instance = $this;
    }
    //run previosuly declared mainclass method from anywhere
    public static function echodata(){
    if( self::$_instance === NULL ) {
        self::$_instance = new self();
    }
        self::$_instance->runechodata();
    }
    function runechodata(){
        echo $this->data;
    }
    function start($classname){
        $inner = new $classname();
        $inner->show();
    }

}

$mainclass = new mainclass('maininfostuff');
$mainclass->start('innerclass');




//i want it to echo "maininfostuff"

ve ben onun çok zarif dikkate alınarak, tercih de bu.

class sharing {
 protected static $mainclass;
 function echodata(){
  self::$mainclass->echodata(); 
 }
}
class innerclass extends sharing {
        function show(){
            parent::echodata();
        }
}
class mainclass extends sharing {
    var $data;
    function __construct($data){
        $this->data = $data;
  parent::$mainclass = $this;//share $this
    }
    function echodata(){
        echo $this->data;
    }
    function start($classname){
        $inner = new $classname();
        $inner->show();
    }

}

$mainclass = new mainclass('maininfostuff');
$mainclass->start('innerclass');

ve burada ben sadece yapılmış bir nesne örneği paylaşım sınıf :)

//PHP Object Sharing 
class sharing {
 //list the classes that you would like to be available for sharing
 protected static $mainclass;


 //run any function that is shared (part of any of the shared objects)
 public function __call($name,$args){
  $shared_objects = get_class_vars(get_class());
  foreach($shared_objects as $sharedObject){
   if (method_exists($sharedObject,$name)){
    $classname = get_class($sharedObject);
    self::$$classname->$name(implode(', ',$args));
    return;
   }
  }
 }
}


class innerclass extends sharing {
        function show(){
   $data = 'inner says hi';
            parent::echodata($data);
        }
}
class mainclass extends sharing {
    var $data;
    function __construct($data){
        $this->data = $data;
  parent::$mainclass = $this;//share mainclass with anything that is a part of sharing
    }
    function echodata($moredata=NULL){
        echo $this->data.'+'.$moredata;
    }
    function start($classname){
        $inner = new $classname();
        $inner->show();
    }

}

$mainclass = new mainclass('maininfostuff');
$mainclass->start('innerclass');

//returns "maininfostuff+inner says hi"

this allows you to run any shared "object instance" functions from any shared object now mainclass can include/run any innerclass it wants, while innerclass has the ability to run mainclass instance functions as if its the already started mainclass object