我甚至不知道我尝试做什么是可能的,但我想我会检查一下,看看我得到了什么回复。以下是该课程的一个简单示例。
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;
如果你没有得到这个:
警告:在......
中从空值创建默认对象
我不知道......有什么想法?
答案 0 :(得分:1)
简答:使用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对象这一事实。
<强>替代:强>
这个替代方案怎么样:
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;