I want to prevent a model attribute from being directly set from an outside source without going through setters that control the logic.
class Person extends Model { public function addMoney($amount) { if ($amount <= 0) { throw new Exception('Invalid amount'); } $this->money += $amount; } public function useMoney($amount) { if ($amount > $this->money) { throw new Exception('Invalid funds'); } $this->money -= $amount; } }
This should not be allowed:
$person->money = -500;
You must use some kind of accessor or setter method:
$person->useMoney(100);
But I don’t care how you get the value:
echo $person->money; // or echo $person->getMoney(); // whatever
How do I enforce that the only way to update this attribute would be through specific methods that dictate some additional logic? In a sense, make a model attribute private or protected.
I want to do this separately and/or before the model data is persisted to the database.
Advertisement
Answer
You can override the set..Attribute() function for each member variable you want to protect, or you could potentially perform your validation inside the set..Attribute() function rather then having separate public methods.
class Person extends Model { public function addMoney($amount) { if ($amount <= 0) { throw new Exception('Invalid amount'); } if (!isset($this->attributes['money'])) { $this->attributes['money'] = $amount; } else { $this->attributes['money'] += $amount; } } public function useMoney($amount) { if ($amount > $this->money) { throw new Exception('Invalid funds'); } if (!isset($this->attributes['money'])) { $this->attributes['money'] = -$amount; } else { $this->attributes['money'] -= $amount; } } public function setMoneyAttribute($val) { throw new Exception('Do not access ->money directly, See addMoney()'); } }