Как инициализировать свойство объекта при первом доступе в php 7? - PullRequest
0 голосов
/ 23 апреля 2020

допустим, у меня есть этот класс:

class DB {
   private DBConnection $connection;
   private string $databaseName;

   public function __construct($databaseName) {
      $this->databaseName = $databaseName;
   }
   private function initConnection(): void {
      if (!isset($this->connection)) {
         $this->connection = new DBConnection($this->databaseName);
      }
   }
   public function query($str): array {
      $this->initConnection();
      return $this->connection->query($str);
   }
   public function something(): void {
      $this->initConnection();
      $this->connection->something();
   }
}

Тогда у меня есть код, который может или не может вызывать методы ->query / ->something, в зависимости от ситуации .

Как можно избежать звонка initConnection в каждом месте, где должен использоваться $this->connection? Я хочу инициализировать его, только если к нему обращаются при первом доступе.

Я уже пытался использовать метод c magi __get, но он вызывается только в том случае, если $connection отсутствует в определении класса .

Другой способ - создать метод доступа (getConnection), который вызывает initConnection и использовать $this->getConnection() (возвращающий объект соединения вместо void) вместо $this->connection, но все же , initConnection будет вызван ни за что.

Проблема с этим подходом состоит в том, что я мог бы все еще случайно использовать $this->connection вместо метода getter; Есть ли способ, которым я могу запретить прямое использование собственности?

1 Ответ

0 голосов
/ 23 апреля 2020

По моему мнению, вы правы, решив использовать (приватный) getConnection метод для создания экземпляра соединения только при первом его использовании. И пусть остальные методы класса будут использовать getConnection() вместо $this->connection.

Однако я также считаю, что вы испытываете обратную сторону одноэлементного паттерна. Возможно, рассмотрите возможность рефакторинга фактического DBConnection и передайте его в качестве аргумента конструктора (зависимости) в DB. Затем вы можете предоставить реализации DBConnection, которые поддерживают отложенную загрузку и синглтоны.

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