Создание динамических переменных в классе

Тема в разделе "PHP Pro", создана пользователем CrashX, 2 мар 2011.

Статус темы:
Закрыта.
  1. CrashX

    CrashX В прошлом XSiteCMS

    Регистр.:
    6 июн 2008
    Сообщения:
    682
    Симпатии:
    112
    Создание динамических переменных в классе

    собственно реализовал класс подгрузки классов, ранее было так

    Код:
    class Engine {
    
      var $version = 0.01;
      var $debug = 'debug';
    
      function extend($object=null, $extend=null) {
        if (!is_object($object)):
          require_once(CLASSES_DIR . $object . ".php");
          switch ($object):
            case "db": $this->db = new DB();
              break;
            case "debug": $this->debug = new Debug();
              break;
    ****
    вызов где угодно
    $engine->extend($engine->debug); // загрузится класс отладки
    
    
    теперь сделал так

    Код:
    class Engine {
    
    private function __get($name) {
        $this->extend($name);
        return $this->$name;
        }
      
    private function extend($object=null, $extend=null) {
        if (!is_object($object)):
          require_once(CLASSES_DIR . $object . ".php");
          switch ($object):
            case "db": $this->db = new DB();
              break;
            case "debug": $this->debug = new Debug();
    ****
    
    + в этом случае я не думаю больше о том что нужно загрузить класс, если его нет он сам его загрузит, что избавляет меня от лишнего кода

    вопрос в другом
    насколько безопасна конструкция return $this->$name;
    или как можно иначе создать пеменную с нужным именем в классе, объявлять сверху нельзя, тк тогда не будет работать метод __get
     
  2. Ramazan

    Ramazan пыщ-пыщ

    Регистр.:
    28 янв 2007
    Сообщения:
    471
    Симпатии:
    98
    создайте в классе одну переменную скажем:
    PHP:
    private $objects = array();
    и уже в методе __get(), который обязательно должен быть публичным

    PHP:
    public function __get($name) {
        if(!isset(
    $this -> objects[$name])
            
    $this -> extend($name);
        return 
    $this -> {$name};
    }
    хотя проверять существование объекта $name, нужно в методе extend(), в противном случае у вас при каждом обращении будем создаваться новый объект
     
  3. CrashX

    CrashX В прошлом XSiteCMS

    Регистр.:
    6 июн 2008
    Сообщения:
    682
    Симпатии:
    112
    пробовал но не те почему
    ---
    я стараюсь избавится от дублирования паронаидальных фукнция и сделать их вызов однократныым там где это действительно нужно

    в вашем примере работа идет так
    $engine->db->insert($param); // тут инициалзиция класса и выполнение действия
    $engine->db->query(); // снова __get тк $engine->db нет, я за 1 модуль вызываю десятки функций оттуда отсюда, тут появляется лишние вызовы, обсолютно пустые, в том что я предлагаю обращение напрямую
    + ввашем придется подключить __set что не радует вообще. тк мне нужно не только получать но и передавать данные на хранение.


    так же в моем примере теперь лишние if (!is_object($object):(
    тк __get работает только если нет перменной. в моем случае объекта.

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

    меня больше волновал, тот момент, что я в классе создаю переменную которой не было ранее

    в других языках так нельзя там нужно было заводить массив и костыли
     
  4. Ramazan

    Ramazan пыщ-пыщ

    Регистр.:
    28 янв 2007
    Сообщения:
    471
    Симпатии:
    98
    забыл сказать, в extend, вместо
    PHP:
    $this->db = ...
    надо
    PHP:
    $this->objects['db'] = ...
    и в __get, моя ошибка

    PHP:
    return $this -> objects[$name];
    не нужно, и почему вы считаете что это плохо?

    получится, примерно так

    PHP:
    public function __set($name$value)
    {
        
    $this -> objects[$name] = $value;
    }
    и в вашем коде

    PHP:
    $engine -> db -> insert(...);
    $engine -> db_result $engine -> db -> query('...');
    получится, если вы назначили переменную сами, то обращения к extend не будет, но это уже вам решать как делать
     
Статус темы:
Закрыта.