Контейнер php: почему все используют более сложный метод? - PullRequest
4 голосов
/ 15 сентября 2010

Когда я нахожу скрипты для php или смотрю на php-фреймворки, я вижу «класс реестра» или «контейнерный класс», который часто содержит переменные или другие объекты, использующие магический метод __get.

Вот упрощенноепример того, что я имею в виду:

пример 1:

class container {
 private $objects;
 public function __get($class){
  if(isset($this->objects[$class])){
   return $this->objects[$class];
  }
  return $this->objects[$class] = new $class();
 }
}

приведенный выше пример будет иметь больше функций при создании класса, а не просто вызывать его, но длямоего примера должно быть достаточно.«Пример 1» - это то, как я в основном вижу его в скриптах, загруженных из Интернета, он поддерживает один экземпляр класса, и теперь мне интересно, что этот пример не сделал бы то же самое и был бы более эффективным:

пример 2:

class simplecontainer {
 public function __get($class){
  return $this->$class = new $class();
 }
}

Но я никогда не вижу «пример 2» в сценариях других народов, что заставляет меня дважды подумать, прежде чем даже подумать о его использовании.

Я протестировал контейнер против simplecontainer, используя несколько классов, которые они будут содержать и повторно использовать около 100000 раз, и «пример 1» делает это за 0,75 секунды на моей локальной машине, а «пример 2» делает это за 0,29 секунды.

что я должен использовать в моих сценариях?пример 1 или пример 2?а почему?

Ответы [ 2 ]

8 голосов
/ 15 сентября 2010

Потому что в вашем я не могу этого сделать:

class container {
    private $foo = "I'm only a var";
    private $objects;
    public function __get($class){
        if(isset($this->objects[$class])){
            return $this->objects[$class];
        }
        return $this->objects[$class] = new $class();
    }
}

class simplecontainer {
    private $foo = "I'm only a var";
    public function __get($class){
        return $this->$class = new $class();
    }
}

class foo {
    public $bar = "wibble";
}

$c1 = new container();
$c2 = new simplecontainer();

$foo = $c1->foo;
$foo->bar = "Don't you forget about me!";
unset($foo);
$foo = $c1->foo;
echo $foo->bar;
// Don't you forget about me!

$foo = $c2->foo;
$foo->bar = "Don't you forget about me!";
unset($foo);   
$foo = $c2->foo;
echo $foo->bar;
// wibble

В вашей версии имя класса не совпадает с закрытым членом объекта-контейнера. Хорошо, так что это должно быть легко избежать, но было бы трудно найти ошибку. Безопасное кодирование означает меньше стресса.

4 голосов
/ 15 сентября 2010

Без первого отключения example2 не определяет объекты как protected или private, что означает, что simplecontainer::objects будет открытым членом, который может быть перезаписан следующим образом:

$container->className = new SomethingElse();

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