2013-03-15 2 views
4

Я пытаюсь преобразовать массив в объект. Я хочу использовать магические методы - __get и __set со статическими свойствами.PHP как использовать магический метод со статическим классом?

Мой код:

class UserData { 
    private static $id, $name, $login; 

    public function __get($var) 
    { 
     return self::$var; 
    } 
    public function __set($var, $val) 
    { 
     self::{$var} = $val; 
    } 
} 

и установка:

foreach($userArray as $key => $val) 
    { 
     DaneBilingowe::${$key} = $val; 
    } 

Ошибка: Фатальная ошибка: Не удается получить доступ к собственной UserData собственности :: $ ID

Можно ли использовать магический метод со статическим свойством?

+0

[Руководство по PHP] (http://www.php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.members): 'Свойство перегрузка работает только в контексте объекта. (...) не будет запускаться в статическом контексте. «В значительной степени это суммирует его. –

+0

@Alvin Вы можете получить доступ к статическому контексту, если у вас есть контекст объекта. Это нонсенс, но возможно. Посмотрите на мой ответ. – Ihsan

+0

"' DaneBilingowe :: $ {$ key} = $ val; '" - действительно ли вы создали подкласс для каждого пользователя? Вот для чего нужны примеры. '$ daneBillingowe = new UserData ('Dane Billingowe');' - проблема решена? –

ответ

4

Одним словом, нет.

__get() и __set() - это методы экземпляра. Это, по сути, функции, которые составляют stdClass(), который является экземпляром.

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

Например:

class UserData { 
    protected static $_instance; 
    protected $_data = array(); 

    public static function get_instance() { 
     static $initialized = FALSE; 

     if (! $initialized) { 
      self::$_instance = new UserData; 
      $initialized = TRUE; 
     } 

     return self::$_instance; 
    } 

    public function __get($var) { 
     $self = self::get_instance(); 

     return isset($self->_data[$var]) ? $self->_data[$var] : NULL; 
    } 

    public function __set($var, $val) { 
     $self = self::get_instance(); 

     $self->_data[$var] = $val; 
    } 
} 

Тогда вы могли бы пойти:

$UserData =& UserData::get_instance(); 
$UserData->var = 'val'; 

echo $UserData->var; // prints 'val' 

Я не рекомендую использовать синглтонов в PHP, однако, поскольку они не имеют смысла. Вы можете прочитать некоторые причины, почему в сообщении Best practice on PHP singleton classes.

Либо используйте статический класс или класс экземпляра.

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

class UserData { 
    protected $id, $name, $login; 

    public static function set_name($name) { 
     self::$name = $name; 
    } 

    public static function set_login($login) { 
     self::$login = $login; 
    } 

    public static function get_id() { 
     return self::$id; 
    } 

    public static function get_name() { 
     return self::$name; 
    } 

    public static function get_login() { 
     return self::login; 
    } 
} 

Обратите внимание, как в приведенном выше код $ ID не доступен для записи. Он доступен только для чтения. $ name и $ login доступны для чтения и записи. Легче и менее затруднительно контролировать чтение и запись с использованием обычных сеттеров и геттеров. Магические методы - это только то, что магия, и обычно магия не является конкретной и менее понятной в коде.

Последним моментом, который я хочу сделать, является то, почему UserData будет статичным? Если только у вас всего 1 пользователь во всем своем коде, нет смысла ставить его. Возможно, я не получаю всю картину, но нужно создать экземпляр с идентификатором и именем, чтобы вы могли иметь несколько экземпляров. В противном случае, почему есть идентификатор, потому что сам класс является уникальным.

4

Если вы действительно хотите использовать магические методы для статических свойств, вы можете, но вам понадобится экземпляр. Хотя это не выглядит разумным, сам программист не является разумным :)

Также определенные пользователем классы и объекты не являются динамическими в php. Вы не можете добавить переменные к ним так легко ... Таким образом, вы можете использовать шаблон ниже:

class UserData { 
    private static $id, $name, $login, $arr = []; 

    public function __get($var){ 
     return (array_key_exists(self::$arr, $var)? self::$arr[$var]:null; 
    } 

    public function __set($var, $val){ 
     self::$arr[$var] = $val; 
    } 
} 

и установка: Ну что такое DaneBilingowe? Я здесь не здесь ...Но:

$inst = new UserData(); 

foreach($userArray as $key => $val){ 
    $inst->$key = $val; 
} 

будет работать.

Но будьте осторожны, он будет работать только на классовой (статической) памяти. Кроме того, поскольку для определения имен нет соответствующей фильтрации, могут возникнуть странные вещи. (Это значит, что вам следует добавить их)

Смежные вопросы