Question

At the moment I test with this piece of code:

<?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>";

But my results are not like expected:

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
        )

)

Why is my added object changed?

Test area: http://codepad.viper-7.com/6q2H2A

Was it helpful?

Solution

That's because your object (i.e. $this in internal context) will be copied by reference, not by value. To do copy by value, you'll need to do:

    public function add($type, $message) 
    {
        $this->type = $type;
        $this->message = $message;
        self::$_alerts[] = clone $this;
    }

As an alternative, you'll need to instantiate (that is, for example, constructions like new self - but clone seems to be more flexible here) your object as many times as you'll wish to copy.

By the way, there's easy way to realize what's going on. Use var_dump() instead of print_r() - then you'll see that objects are actually same. Sample for your code (i.e. where copying is not fixed yet):

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"
  }
}

-as you can see, objects are same there.

OTHER TIPS

You save 2 refferences to the same object in your $_alerts array. You need to create a new object for each alert or do something like this:

<?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>";

The problem you are seeing is because your code is changing the same object twice. The first call, it will set the data "warning" and "test 1", and the second time it will overwrite these values.

You can solve this by creating a new instance of the object and adding the data:

$alert = new Alert();

$alert->add("warning", "test 1");

$alert2 = new Alert();
$alert2->add("error", "test 2");

This should give the following result:

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
    )

)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top