Можете ли вы получить переменные вызывающего класса? - PullRequest
3 голосов
/ 03 декабря 2008

У меня есть класс Page, который создает экземпляр DB с именем $db.

В __construct() из Page я создаю новый объект $db и извлекаю кучу данных конфигурации из файла.

Теперь у класса DB есть метод _connectToDB(), который (пытается) подключиться к базе данных.

Есть ли способ в классе DB вызвать массив конфигурации родительского класса? Я не хочу делать глобальные переменные, если мне не нужно, и я не хочу дважды получать данные конфигурации.

Псевдокод может выглядеть примерно так ...

$dbUsername = get_calling_class_vars(configArray['dbUserName']);

Ответы [ 6 ]

6 голосов
/ 03 декабря 2008

Я считаю, что часто легче инициализировать все "важные" объекты, близкие к любым переменным, которые им нужно знать Вы можете попробовать это так:

/* Code to get config variables here */
$DB = new DB($config);
/* You might want to delete the database password from $config here */
$Page = new Page($config, $DB);

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

class Page {
    function __construct(array $config, DBClass $db) { }
}
1 голос
/ 13 июля 2017

Вы можете использовать static, если хотите использовать переменные без передачи этих данных:

class page{
    static $configArray = [];
    function doWhatever(){
        $db = new DB();
        $db->connectToDB();
    }
}
class DB{
    function connectToDB(){
        $dbUsername = page::$configArray['dbUserName'];
    }
}

В этом случае имеет смысл иметь эти данные как static, потому что даже если у вас есть несколько экземпляров класса страницы, параметры конфигурации всегда должны быть одинаковыми.

В любом случае, я думаю, что было бы лучше построить и сохранить $ configArray только в классе DB. Если вы хотите позвонить извне, используйте ту же логику static.

1 голос
/ 03 декабря 2008

См. debug_backtrace() для получения информации о вызовах классов или объектов.

Затем см. Отражение , чтобы получить больше информации о свойствах данного класса или объекта.

edit: Но для чего бы это ни стоило, я бы также рекомендовал передать конкретные параметры, которые вам нужны. Ссылка на данные вызывающего абонента, вероятно, составляет Content Coupling .

1 голос
/ 03 декабря 2008

Почему бы не передать параметры конфигурации в функцию connectToDb или передать данные конфигурации в конструктор класса DB.

А в справочник ответьте на вопрос: вы ничего не знаете о внешнем контексте вызова в вашем текущем контексте.

0 голосов
/ 03 декабря 2008

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

вы можете сделать ваши данные конфигурации глобальными или просто передать необходимые свойства для инициализации объекта db.

0 голосов
/ 03 декабря 2008

Вы можете передать ребенку ссылку на родителя. Например:

class Parent {
  function __construct() {
    $this->myChild = new Child($this);
  }
  public function doSomething() {}
}

class Child {
  function __construct(Parent $parent) {
    $parent->doSomething()
  }
}

Это может показаться вам странным, поскольку вы все еще находитесь в конструкторе родителя, и, следовательно, ваш родительский объект еще не полностью создан. Но вы все равно можете использовать $ this как ссылку на себя, даже в конструкторе. Вам просто нужно быть осторожным, чтобы ваш ребенок не ссылался на вещи в родителе, которые еще не были инициализированы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...