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 to share