目前我用这段代码测试:
<?php
class Alert {
private $type;
private $message;
public static $_alerts = array();
public function add($type, $message) {
$this->type = $type;
$this->message = $message;
self::$_alerts[] = $this;
}
}
$alert = new Alert();
$alert->add("warning", "test 1");
$alert->add("error", "test 2");
echo "<pre>";
print_r(Alert::$_alerts);
echo "</pre>";
但我的结果并不像预期的那样:
Array
(
[0] => Alert Object
(
[type:Alert:private] => error
[message:Alert:private] => test 2
)
[1] => Alert Object
(
[type:Alert:private] => error
[message:Alert:private] => test 2
)
)
为什么我添加的对象发生了变化?
答案 0 :(得分:2)
这是因为您的对象(即内部上下文中的$this
)将be copied by reference,而不是值。要按值复制,您需要执行以下操作:
public function add($type, $message)
{
$this->type = $type;
$this->message = $message;
self::$_alerts[] = clone $this;
}
作为替代方案,你需要实例化(例如,像new self
这样的结构 - 但clone
似乎在这里更灵活)你的对象和你一样多次希望复制。
顺便说一句,有很简单的方法来实现正在发生的事情。使用var_dump()
代替print_r()
- 然后您会看到对象实际上是相同的。代码示例(即复制 尚未修复的地方):
array(2) { [0]=> object(Alert)#1 (2) { ["type":"Alert":private]=> string(5) "error" ["message":"Alert":private]=> string(6) "test 2" } [1]=> object(Alert)#1 (2) { ["type":"Alert":private]=> string(5) "error" ["message":"Alert":private]=> string(6) "test 2" } }
- 你可以看到,对象在那里是相同的。
答案 1 :(得分:2)
您可以在$ alerts数组中保存2个对同一对象的引用。您需要为每个警报创建一个新对象,或者执行以下操作:
<?php
class Alert {
private $type;
private $message;
public static $_alerts = array();
private function __construct($type,$message){
$this->type=$type;
$this->message = $message;
}
public function getMessage(){
return $this->message;
}
public function getType(){
return $this->type;
}
public static function add($type, $message) {
self::$_alerts[] = new self($type,$message);
}
}
Alert::add("warning", "test 1");
Alert::add("error", "test 2");
echo "<pre>";
print_r(Alert::$_alerts);
echo "</pre>";
答案 2 :(得分:1)
您遇到的问题是因为您的代码正在两次更改同一个对象。 第一次调用时,它会设置数据“warning”和“test 1”,第二次会覆盖这些值。
您可以通过创建对象的新实例并添加数据来解决此问题:
$alert = new Alert();
$alert->add("warning", "test 1");
$alert2 = new Alert();
$alert2->add("error", "test 2");
这应该给出以下结果:
Array
(
[0] => Alert Object
(
[type:Alert:private] => warning
[message:Alert:private] => test 1
)
[1] => Alert Object
(
[type:Alert:private] => error
[message:Alert:private] => test 2
)
)