我什至不知道我正在尝试做的事情是否可行,但我想我会检查一下,看看我得到了什么回复。下面是该类的简单示例。
class MyClass {
public $data = array();
public function __construct($data) {
$this->data = $data;
}
public function __get($name) {
if (array_key_exists($name, $this->data)) {
return $this->data[$name];
}
return null;
}
public function __set($name, $value) {
$this->data[$name] = $value;
}
public function setTestData($name, $value) {
$this->data['test'][$name] = $value;
}
}
我试图开始工作的是以下内容(注意:仅当它很容易并且不需要任何其他类或外部源即可工作时,并且数据数组始终保持类内的数组(:
$obj = new MyClass(array('test' => array()));
$obj->test->add = 'me';
我收到以下消息:
Notice: Indirect modification of overloaded property MyClass::$test has no effect in ...
Warning: Attempt to assign property of non-object in ...
Array
(
[test] => Array
(
)
)
我还尝试更改__get以按引用传递,如下所示:
public function &__get($name) {
这似乎更接近,但仍然收到以下消息,这是有道理的,但不确定如何更改它以使其工作。
Warning: Attempt to assign property of non-object in ...
因此,如果以上所有内容都只是愚蠢或根本不是一个好主意,那么以下解决方案会是一个很好的替代解决方案吗?
$obj = new MyClass(array('test' => array()));
$obj->setTestData('add', 'me');
这按预期工作,甚至不使用魔术方法:
Array
(
[test] => Array
(
[add] => me
)
)
好吧,我希望有人能让我休息一下。感谢任何回复!
更新:其他替代方案:
仍然不完全是我想要的,但无论如何都很整洁。
class MyClass {
public $data = array();
public function __construct($data) {
$this->data = $data;
}
public function __get($name) {
if (!isset($this->data[$name])) {
$this->data[$name] = new stdClass();
} else if (is_array($this->data[$name])) {
$this->data[$name] = @json_decode(@json_encode($this->data[$name], JSON_FORCE_OBJECT), false);
}
return $this->data[$name];
}
public function __set($name, $value) {
$this->data[$name] = $value;
}
public function toArray() {
return @json_decode(@json_encode($this->data), true);
}
}
因此,当我运行以下内容时:
$o = new MyClass(array('test' => array()));
$o->test->value = 10;
print_r($o->data);
我得到这个输出:
Array
(
[test] => stdClass Object
(
[value] => 10
)
)
然后,如果我需要它是一个数组,我只需运行以下命令:
printr($o->toArray());
获得:
Array
(
[test] => Array
(
[value] => 10
)
)
它也适用于任何深度(我喜欢(:
$o = new MyClass(array());
@$o->one->two->three->four->five = 100;
printr($o->toArray());
输出:
Array
(
[one] => Array
(
[two] => Array
(
[three] => Array
(
[four] => Array
(
[five] => 100
)
)
)
)
)
我唯一不喜欢的是我不得不使用 @ 来抑制这里的警告:
@$o->one->two->three->four->five = 100;
如果你不这样做,你会得到这个:
警告:从 中的空值创建默认对象...
我不知道。。大家怎么看?
简短的回答:你正在尝试的东西是用PHP无法实现的。
你可以想象这样的事情:
class MyClass {
public $data = array();
public function __get($name) {
if (array_key_exists($name, $this->data)) {
return $this->data[$name];
}
return null;
}
public function __set($name, $value) {
$this->data[$name] = $value;
}
}
$o = new MyClass();
$o->test->val = "foo";
var_dump($o);
这看起来stdClass
它会为不存在(或无法访问!拥有对象后,您可以使用 ->
运算符访问或设置公共属性。
但它不起作用,因为您会收到以下消息:
PHP 通知:间接修改重载属性 MyClass::$test 对
它根本不在PHP中工作。代码需要如下所示:
$o = new MyClass();
$o->test = new stdClass();
$test = $o->test;
$test->val = "foo";
$o->test = $test;
var_dump($o);
注意!对于上面的示例,您不需要__get
或__set
。您只需简单地为PHP对象赋值即可利用以下事实:可以向PHP对象添加公共属性。
另类:
这个替代方案呢:
class MyClass {
public $data = array();
public function data($key) {
if(!isset($this->data[$key])) {
$this->data[$key] = new stdClass();
}
return $this->data[$key];
}
}
$o = new MyClass();
$o->data('test')->value = 10;