If we're talking strictly about PHP here and not about C#, Java, etc (where the compiler will optimise these things), I find getters and setters to be a waste of resources where you simply need to proxy the value of a private field and do nothing else.
On my setup, I made two crappy classes, one with five private fields encapsulated by five getter/setter pairs proxying the field (which looked almost exactly like java code, funnily enough) and another with five public fields, and called memory_get_usage() at the end after creating an instance. The script with the getter/setters used 59708 bytes of memory and the script with the public fields used 49244 bytes.
In the context of a class library of any significant size, such as a web site framework, these useless getters and setters can add up to a HUGE black hole for memory. I have been developing a framework for my employer in PHP (their choice, not mine. i wouldn't use it for this if i had the choice but having said that, PHP is not imposing any insurmountable restrictions on us) and when I refactored the class library to use public fields instead of getters/setters, the whole shebang ended up using 25% less memory per request at least.
The __get(), __set() and __call() 'magic' methods really shine for handling interface changes. When you need to migrate a field to a getter/setter (or a getter/setter to a field) they can make the process transparent to any dependent code. With an interpreted language it's a bit harder to find all usages of a field or method even with the reasonably good support for code sensitivity provided by Eclipse PDT or Netbeans, so the magic methods are useful for ensuring that the old interface still delegates to the new functionality.
Say we have an object which was developed using fields instead of getters/setters, and we want to rename a field called 'field' to 'fieldWithBetterName', because 'field' was inappropriate, or no longer described the use accurately, or was just plain wrong. And say we wanted to change a field called 'field2' to lazy load its value from the database because it isn't known initially using a getter...
class Test extends Object {
public $field;
public $field2;
}
becomes
class Test extends Object {
public $fieldWithBetterName = "LA DI DA";
private $_field2;
public function getField2() {
if ($this->_field2 == null) {
$this->_field2 = CrapDbLayer::getSomething($this->fieldWithBetterName);
}
return $this->_field2;
}
public function __get($name) {
if ($name == 'field')) {
Logger::log("use of deprecated property... blah blah blah\n".DebugUtils::printBacktrace());
return $this->fieldWithBetterName;
}
elseif ($name == 'field2') {
Logger::log("use of deprecated property... blah blah blah\n".DebugUtils::printBacktrace());
return $this->getField2();
}
else return parent::__get($name);
}
}
$t = new Test;
echo $t->field;
echo $t->field2;
(As a side note, that 'extends Object' bit is just a base class I use for practically everything which has a __get() and a __set() declaration which throws an exception when undeclared fields are accessed)
You can go backwards with __call(). This example is quite brittle, but it's not hard to clean up:
class Test extends Object {
public $field2;
public function __call($name, $args) {
if (strpos($name, 'get')===0) {
$field = lcfirst($name); // cheating, i know. php 5.3 or greater. not hard to do without it though.
return $this->$field;
}
parent::__call($name, $args);
}
}
Getter and setter methods in PHP are good if the setter has to do something, or if the getter has to lazy load something, or ensure something has been created, or whatever, but they're unnecessary and wasteful if they do nothing other than proxy the field, especially with a few techniques like the ones above to manage interface changes.