Getter and setter pairs existed so that a rule could be added later without changing callers. Hooks give public properties that option. Migrate in three steps: make the property public and move the setter's rule into a set hook; turn computed getters into virtual get hooks; keep the old methods as thin wrappers marked #[\Deprecated] (Subsection 4.11.14) until their callers are gone.
<?php
final class Customer {
public string $email = '' {
set => strtolower(filter_var($value, FILTER_VALIDATE_EMAIL)
?: throw new InvalidArgumentException("Invalid email: $value"));
}
#[\Deprecated('use the $email property', since: '2.0')]
public function getEmail(): string { return $this->email; } // kept for old callers
}
$c = new Customer();
$c->email = 'Ann@Example.COM';
$viaGetter = $c->getEmail(); // old call site still works
echo $c->email, ' ', $viaGetter, "\n";
try { $c->email = 'nope'; }
catch (InvalidArgumentException $e) { echo $e->getMessage(), "\n"; }Output
PHP Deprecated: Method Customer::getEmail() is deprecated since 2.0, use the $email property in /tmp/ch04-11/migrate.php on line 12 ann@example.com ann@example.com Invalid email: nope
A setter that exists only to block outside writes becomes private(set) (Subsection 4.11.10). Keep as methods any setter that logs, dispatches events or calls other objects.