php возражают в объекте, получая экземпляр объекта верхнего уровня

Я экспериментирую с ООП PHP

то, что я пытаюсь узнать, действительно ли возможно получить доступ к экземпляру объекта от скручивания жгутов объект, который был создан в этом экземпляре объекта?

сбивающие с толку звуки, таким образом, вот пример:

содержание индекса


    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


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

цель этого тестового сценария состоит в том, чтобы заставить внутренний класс решить, выполнить ли mainclass echodata функция

как может вышеупомянутый пример быть выполненным? (не полагаясь на статические классы или одиночные элементы или расширенные классы)

править: из-за некоторого беспорядка в ответах я отредактировал пример

5
задан Timo Huovinen 30 January 2010 в 09:42
поделиться

9 ответов

Внутренние классы невозможны в PHP. Таким образом, вы не можете объявить свой INNERCLASS в Mainclass. И поскольку вы не можете этого сделать, нет возможности получить доступ к переменным внешних классов, как вы можете в том, например, Java.

Вы можете сделать это вместо этого:

 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();
8
ответ дан 18 December 2019 в 07:09
поделиться

Я лично никогда не видел класс Определяется внутри методов другого класса до того, как он на самом деле работает вообще, я очень удивлен. (Я еще более удивлен, почему вы хотите / нуждаться в этом, но в любом случае ...)

Просто пропустите текущий (внешний) объект к внутреннему объекту, когда вы его строим.

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

$innerObj = new InnerClass($this);
4
ответ дан 18 December 2019 в 07:09
поделиться

Кажется, что вы должны сделать:

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();

, но кажется, что вы не можете сделать это в PHP:

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

Так что извлечь свой внутренний класс из майнкласса.

1
ответ дан 18 December 2019 в 07:09
поделиться

Нет, внутренние сцепления не в PHP.

«Функциональность уже доступна на других языках, но вопрос заключается в том, необходим ли это в PHP. Краткий ответ - нет. С моделью исполнения PHP она будет дополнительно замедляться и раздувать компиляция PHP». - http://jacobsantos.com/2006/general/dont-advocate-subclasses/comment-page-1/

3
ответ дан 18 December 2019 в 07:09
поделиться

Вы пытаетесь вызвать нестатический метод статически с кодом

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

вместо этого, вам необходимо пройти в экземпляре Mainclass в подкласс:

 <?php

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

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

  // ....

  $inner = new innerclass($this);
  $inner->show();
  ?>
0
ответ дан 18 December 2019 в 07:09
поделиться

Единственный способ для внутреннего класса иметь доступ к внешнему классу, предназначен для передачи внешнего экземпляра к конструктору внутреннего класса и для его сохранения в переменной экземпляра.

4
ответ дан 18 December 2019 в 07:09
поделиться

нет. Когда вы создаете объект в качестве члена другого объекта:

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

Есть для моих знаний нет способа доступа к родительскому элементу. Вам придется передавать ссылку на родительский элемент к объекту при его создании:

class innerclass(){

  private $parent; // Reference to the parent object

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

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

Определение класса, хотя никогда не должно происходить в функции, даже если это возможно. Определения классов могут иметь иерархию - они могут простираться друг на друга. Но это вызывается с использованием продлен . Класс может простираться другой. Их определение все еще рядом, они не вложены в код.

Я не знаю, что вы пытаетесь сделать, но, возможно, то, что вы ищете , это , расширяя класс. В этом случае вы можете получить доступ к функциям и переменным, определенным в родительском языке, используя родитель ключевых слов :

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

, то есть, однако, что-то принципиально отличается от того, что вы делаете прямо сейчас.

1
ответ дан 18 December 2019 в 07:09
поделиться

Позвольте мне обратиться к одной важной линии:

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

в PHP, чтобы использовать оператор объекта Infix Object-Access ( - > ) Аргумент на левом стороне должен быть переменной (добавлен как минимум один $ ) и должен быть экземпляром класса, например, $ MyClass-> Что бы ни было или $ this-> foo .

Если вы идете с другого языка, и вы думаете о статическом доступе, вы должны использовать правильный оператор, который является :: , например SomeClass :: $ somevalue или SomeClass :: uvere_const .

Теперь, если вы непрерывно выступаете против передачи «родительского» объекта к конструктору ребенка, вы могли бы рассмотреть шаблон Singleton, который позволил бы вам статистически получить доступ к экземпляру родительского класса из любой точки. код, включая дочерний объект.

Но серьезно, просто пропустите его как аргумент для конструктора, и, как кто-то еще сказал, не определяйте класс внутри функции, особенно если эта функция сама по себе является членом другого класса. Если эта функция называется дважды, вы получите фатальную ошибку.

Редактировать

Вот пример того, о чем я говорю:

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();   
    }
}

, а затем запустить:

$foo = mainClass::getInstance('Foo');
$foo->start(); // prints "Foo"
1
ответ дан 18 December 2019 в 07:09
поделиться

Я нашел больше способов сделать это

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"

, и этот тоже, который я предпочитаю, учитывая его довольно аккуратно.

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');

И вот класс совместного использования экземпляра объекта, который я только что сделал :)

//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"

Это позволяет запустить любой общий «экземпляр объекта» из любого общего объекта. Теперь MainClass может включать / запустить любой INNERCLASS, который он хочет, в то время как InnerClass имеет возможность запускать функции экземпляра Mainclass, как если бы его уже запущен объект Mainclass

0
ответ дан 18 December 2019 в 07:09
поделиться