Я экспериментирую с ООП 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 функция
как может вышеупомянутый пример быть выполненным? (не полагаясь на статические классы или одиночные элементы или расширенные классы)
править: из-за некоторого беспорядка в ответах я отредактировал пример
Внутренние классы невозможны в 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();
Я лично никогда не видел класс Определяется внутри методов другого класса до того, как он на самом деле работает вообще, я очень удивлен. (Я еще более удивлен, почему вы хотите / нуждаться в этом, но в любом случае ...)
Просто пропустите текущий (внешний) объект к внутреннему объекту, когда вы его строим.
class InnerClass {
var $outer;
function __construct(&$outer) {
$this->outer = $outer;
}
function someStuff() {
$this->outer->doStuff();
}
}
$innerObj = new InnerClass($this);
Кажется, что вы должны сделать:
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
Так что извлечь свой внутренний класс из майнкласса.
Нет, внутренние сцепления не в PHP.
«Функциональность уже доступна на других языках, но вопрос заключается в том, необходим ли это в PHP. Краткий ответ - нет. С моделью исполнения PHP она будет дополнительно замедляться и раздувать компиляция PHP». - http://jacobsantos.com/2006/general/dont-advocate-subclasses/comment-page-1/
Вы пытаетесь вызвать нестатический метод статически с кодом
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();
?>
Единственный способ для внутреннего класса иметь доступ к внешнему классу, предназначен для передачи внешнего экземпляра к конструктору внутреннего класса и для его сохранения в переменной экземпляра.
нет. Когда вы создаете объект в качестве члена другого объекта:
$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();
}
, то есть, однако, что-то принципиально отличается от того, что вы делаете прямо сейчас.
Позвольте мне обратиться к одной важной линии:
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"
Я нашел больше способов сделать это
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