Auto update PHP object value based on the sum of other object values

Here's a simplified version of the problem.

class A{
public $value = 0;
}
class B{
    public $values;
    public $total = 0;
    function __construct($values) {
        foreach($values as $value){
            $this->values[] = &$value;
            $this->total += $value->value;
        }
    }
}

$a = new A;
$a->value = 10;
$b = new A;
$b->value = 20;
$x = new B(array($a, $b));
echo $x->total . "\r\n";
$b->value = 40;
echo $x->total;

      

Output:

30
30

      

I want the sum to automatically update to 50 without iterating over the array and recalculating the sum. Can PHP pointers be used? Desired output:

30
50

      

+3


source to share


1 answer


Amounts cannot change if there have been changes. This information is lost. However, you can use the magic method __set

to add additional logic to a simple setup. There you can call up the "calculator" to change the total.

If you don't need to keep the previous interface, you should use a real setter for the value ( setValue

), as __set

it is not good practice.

For example:



class A
{
    private $value = 0;
    private $b;

    public function setObserver(B $b)
    {
        $this->b = $b;
    }

    public function __get($name)
    {
        if ($name == 'value') {
            return $this->value;
        }
    }

    public function __set($name, $value)
    {
        if ($name == 'value') {
            $prev        = $this->value;
            $this->value = $value;

            if ($this->b instanceof B) {
                $this->b->change($prev, $this->value);
            }
        }
    }
}

class B
{
    public $total = 0;

    public function __construct($values)
    {
        foreach ($values as $v) {
            if ($v instanceof A) {
                $this->total += $v->value;
                $v->setObserver($this);
            }
        }
    }

    public function change($prevValue, $newValue)
    {
        $this->total -= $prevValue;
        $this->total += $newValue;
    }
}

      

Printing

30 
50

      

+1


source







All Articles