Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Для профи > Получить изнутри имя объекта класса


Автор: мухр 16.12.2007, 03:35
Код

class Test
{
  function getObjectName()
  {
    //
    ...
    //
    return $objectName;
  }
}

$simpleTest = New Test;
echo $simpleTest ->getObjectName(); // Выводит 'simpleTest'



Как это можно осуществить? Смотрел Reflection API, но так и не нашёл.

Автор: skyboy 16.12.2007, 03:39
как мне кажется, невозможно в принципе. а если две переменных будут ссылаться на один и тот же объект - надо будет выводить две строки? А если полсотни переменных?

Автор: мухр 16.12.2007, 04:34
Цитата(skyboy @ 16.12.2007,  03:39)
как мне кажется, невозможно в принципе. а если две переменных будут ссылаться на один и тот же объект - надо будет выводить две строки? А если полсотни переменных?

Если не ошибаюсь, один объект не может иметь несколько имён. Мы пока говорим об имени объекта, а не о ссылках на него, если вы это имеете в виду: 
Код

$simpleTest2 =& $simpleTest;

Я хочу избежать необходимости создавать окружение. Возможно ли завязать все процессы внутри объектов, чтобы можно было на произвольном уровне определить в том числе, кто породил данный объект, каким другим объектом вызван данный объект, какой объект стоит надо всем, внутри которого всё осуществляется и др.? Я хочу отказаться от global и оперировать по возможности относительными категориями.

Автор: Feldmarschall 16.12.2007, 10:22
А оно надо, вообще, знать имена элементов программы?
для отладки поможет debug_backtrace, а для функционала - это, имхо, порочный подход.

Автор: WolfON 16.12.2007, 14:52
а зачем оно вообще надо?
мне кажется можно сделать по-другому smile

Автор: мухр 16.12.2007, 16:16
Цитата(Feldmarschall @  16.12.2007,  10:22 Найти цитируемый пост)
А оно надо, вообще, знать имена элементов программы?

Цитата(WolfON @  16.12.2007,  14:52 Найти цитируемый пост)
а зачем оно вообще надо?
 А оно вообще надо!

Цитата(Feldmarschall @  16.12.2007,  10:22 Найти цитируемый пост)
имхо, порочный подход.
 Этот порочный подход в свою очередь используется в Action Script и, стало быть, во многих первообразных средах программирования - в особенности на основе ООП. И что нельзя никак имя объекта заполучить? Что-то не верится.

Цитата(WolfON @  16.12.2007,  14:52 Найти цитируемый пост)
мне кажется можно сделать по-другому
 Расскажите.

Автор: SelenIT 16.12.2007, 17:25
Цитата(мухр @  16.12.2007,  16:16 Найти цитируемый пост)
используется в Action Script

ActionScript (до 3-ей версии) - не ОО-язык в традиционном понимании.

Цитата(мухр @  16.12.2007,  16:16 Найти цитируемый пост)
на основе ООП

В ООП сабж в кошмаре не приснится, ибо нарушает первую из его основ - инкапсуляцию. Объект знает лишь о том, что передали лично ему, но не обязан и даже не имеет права знать, как его самого обзывают другие (вышестоящие). Имхо, этого и в жизни никому лучше не знать, а то вообще всем работать расхочется... ;)

Цитата(мухр @  16.12.2007,  16:16 Найти цитируемый пост)
Расскажите.

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

Автор: мухр 16.12.2007, 17:45
Задача стоит следующим образом. Запускаем контроллер, сообщаем ему некоторые параметры, на базе которых создаётся некоторое внутреннее окружение, которое передаётся по цепи всем остальным объектам, инстанцированным внутри этого контроллера и ниже. Чтобы можно было запустить несколько контроллеров единовременно и параллельно под разными именами (или, допустим, вызвать контроллер из контроллера), и чтобы их окружения никак не пересекались.
Единственное решение мне видится пока, это передавать по цепи некоторый объект $ENV, содержащий все необходимые переменные окружения, но мне это кажется не очень удобным, так как приходится следовать некоторому соглашению в правиле написания классов объектов, используемых внутри контроллера.

Автор: Anarki 16.12.2007, 17:58
мухр, 
Вы определитесь, что имеете ввиду под именем объекта. Я считаю, что такой категории не существует. Есть имя класса, может быть атрибут объекта "имя"
Если я правильно вас понял
Код

$simpleTest = new SimpleTestClass();

$simpleTest - это в первую очередь переменная, которая хранит ссылку на объект(PHP5) а не имя объекта.
Цитата(мухр @  16.12.2007,  07:34 Найти цитируемый пост)
Я хочу избежать необходимости создавать окружение. Возможно ли завязать все процессы внутри объектов, чтобы можно было на произвольном уровне определить в том числе, кто породил данный объект, каким другим объектом вызван данный объект, какой объект стоит надо всем, внутри которого всё осуществляется и др.? Я хочу отказаться от global и оперировать по возможности относительными категориями.

Чтобы перестать использовать global...
Как я вижу это можно сделать, не привязываясь к именам переменных.

1. Передавать используемые объекты в конструктор класса.
Код

<?php
class myHelper {
    public function hFunc() {
        echo 'Help function activated!';
    }
}

class simpleTest {
    protected $helper = null;
    public function simpleTest($obj) {
        $this->helper = $obj;
    }
    public function doit() {
        $this->helper->hFunc();
    }
}

$helper = new myHelper();
$st = new simpleTest($helper);
$st->doit();

2. В ZF сделано так, не знаю паттерн ли Registry это или нет. Там существует вспомогательный класс(который представлен единственным объектом в программе - simgleton).
Код

$registry = Zend_Registry::getInstance();
$config = new Zend_Config_Ini('./application/config.ini','general'); 
$registry->set('config', $config);
// ...
$registry->set('dbadapter',$dbAdapter);

Дальше по коду можно использовать объект Zend_Config_Ini ($config) и другие объекты так:
Код

$config = Zend_Registry::get('config');
$dbAdapter = Zend_Registry::get('dbadapter');
$dbAdapter->connect(); // вызываем метод объекта

Это класс со статическими методами, синглтон, имеющий хранилище ссылок на объекты, представленное в виде ассоциативного массива, доступ к которому обеспечивается методами set и get. Думаю это несложно реализовать.

Автор: vasac 16.12.2007, 18:17
Цитата

Мы пока говорим об имени объекта, а не о ссылках на него, если вы это имеете в виду: 
$simpleTest2 =& $simpleTest;

Во-первых, данный пример так же вполне реален и показывает возможность двух ссылок на одно значение.
Во-вторых, в php5 как и во всех современных ООП-языках, значением переменной объектного типа является ссылка на объект. Т.е.
Код

$simpleTest2 = $simpleTest

даст две переменные, ссылающиеся на один объект.

Цитата(мухр @  16.12.2007,  16:16 Найти цитируемый пост)
И что нельзя никак имя объекта заполучить?

Нельзя, потому что у объекта нет имени. Оно есть у переменных и свойств.

В некоторых системах, возможно, и требуется привязывать объект к имени, но это уже реализуется в самой системе своими средствами. Уверен и в AS это сделано не на уровне языка. 

Автор: мухр 16.12.2007, 18:19
Anarki, c первым понятно, а вот второй способ, мне кажется, не совсем то, потому что приходится подставлять разные имена в set и забирать через get, соответственно, указывая всё явным образом. Получается как бы два разных кода и две разные конструкции, но речь идёт про одинаковые конструкции, поведение которых различается от различных входящих параметров, переданных через конструктор или ещё как-нибудь.
Если я всё до конца улавливаю.

Автор: мухр 16.12.2007, 19:13
Цитата(Anarki @  16.12.2007,  17:58 Найти цитируемый пост)
Это класс со статическими методами, синглтон, имеющий хранилище ссылок на объекты, представленное в виде ассоциативного массива, доступ к которому обеспечивается методами set и get. Думаю это несложно реализовать.
 Тяжело понять это место. Мы имеем отдельное хранилице, в котором регистрируем ссылки на объекты, но как мы потом узнаем, какому объекту принадлежит данная ссылка, если мы имеем несколько экземпляров одного класса с разными ссылками соответственно. Как осуществляется механизм обратной идентификации?

Автор: мухр 16.12.2007, 19:28
Код

class Regiser
{

  private $container = Array();

  public function set ($name, $obj)
  {
     $this->container[$name] = $obj;
  }

  public function getInstanceName ($obj)
  {
     return array_search($obj, $this->$container);
  }

}


Код

class SimpleClass
{

  public function getInstanseName ()
  {
    global $register;
    return $register->getInstanceName($this);
  }

}


Код

$register = New Register;
$simpleClass = New SimpleClass;
$register->set('simpleClass', $simpleClass);
echo $simpleClass->getInstanceName(); // Должно вернуть 'simpleClass'

Разве что вот так, но будет ли это работать?

Добавлено через 7 минут и 40 секунд
Дубль два. Ещё проще.
Код

class Regiser    
{    
  private $container = Array();    
  public function set ($name)    
  {    
     $this->array_push($container, $name);    
  }    
  public function getInstanceName ($obj)    
  {
    foreach ($this->container as $instanceName)
    {
      global ${$instanceName};
      if ($obj === ${$instanceName}) return $instanceName;
    }    
  }    
}


Код

class SimpleClass    
{    
  public function getInstanseName ()    
  {    
    global $register;    
    return $register->getInstanceName($this);    
  }    
}


Код

$register = New Register;    
$simpleClass = New SimpleClass;    
$register->set('simpleClass');    
echo $simpleClass->getInstanceName(); // Должно вернуть 'simpleClass'

А наверное, в регистрацию ещё можно добавить имя класса, чтобы число итераций уменьшить.

Автор: Fally 19.12.2007, 20:46
символические ссылки используй для таких целей... но ИМХО, не зачем объекту знать как его звать.

Автор: Mal Hack 19.12.2007, 21:22
Цитата(vasac @  16.12.2007,  18:17 Найти цитируемый пост)
В некоторых системах, возможно, и требуется привязывать объект к имени, но это уже реализуется в самой системе своими средствами. Уверен и в AS это сделано не на уровне языка.  

Скорее в некоторых языках у объекта есть свойтво Name, в которое IDE сама закатывает имя переменной, ну или ручками...

Автор: N0dwis 19.12.2007, 22:40
Гради Буч "Объектно-ориентированный анализ и проектирование".
Бьярн Страуструп "Язык программирования C++" (Часть II. Механизмы абстракции).
Если возник такой вопрос - подход в принципе не тот. Лучше пересмотреть общую архитектуру, чем изобретать фонарик на солнечных батареях.
мухр, задайте конкретный вопрос!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)