我正在尝试将数组转换为对象。我想使用魔术方法 - 带有静态属性的__get和__set。
我的代码:
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
是否可以将magic方法与静态属性一起使用?
答案 0 :(得分:5)
简而言之,没有。
__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中使用Singletons,因为它们毫无意义。您可以在帖子Best practice on PHP singleton classes中阅读一些原因。
使用静态类或实例类。
Magic getters和setter是快捷方式。您可以使用普通的setter和getter实现相同的行为。下面的示例提供了相同的功能,但意图更清晰:
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是可读写的。使用普通的setter和getter来控制读写是更容易和更少的错误。魔术方法就是魔法,通常魔法并不具体,在代码中也不太容易理解。
我想说的最后一点是,为什么UserData会是静态的?除非您在整个代码中只有1个用户,否则将其保持静态是没有意义的。也许我没有全面了解,但应该实例化具有id和名称的内容,以便您可以拥有多个实例。否则,为什么有id,因为类本身是唯一的。
答案 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;
}
会奏效。
但要注意,它只适用于类(静态)内存。 此外,由于没有适当的过滤设置名称,可能会发生奇怪的事情。 (这意味着你应该添加它们)