Domain Model Validation
Using some magic methods can integrate validation without having to implement get and set methods everywhere.
class ValidationException extends Exception { } abstract class DomainModel { private $validationErrors = array(); final public function __get($field) { $getMethodName = 'get' . ucfirst($field); if (method_exists($this, $getMethodName)) { return call_user_func(array($this, $getMethodName)); } elseif (isset($this->$field)) { return $this->$field; } } final public function __set($field, $value) { $setMethodName = 'set' . ucfirst($field); if (array_key_exists($field, $this->validationErrors)) { unset($this->validationErrors[$field]); } if (method_exists($this, $setMethodName)) { try { call_user_func(array($this, $setMethodName), $value); } catch (ValidationException $e) { $this->validationErrors[$field] = $e->getMessage(); } } elseif (array_key_exists($field, get_object_vars($this))) { $this->$field = $value; } } final public function isValid() { return count($this->validationErrors) == 0; } final public function getValidationErrors() { return array_values($this->validationErrors); } final public function setData($data) { foreach ($data as $field => $value) { $this->__set($field, $value); } } final public function getData() { return get_object_vars($this); } } class Test extends DomainModel { protected $message; public function setMessage($msg) { if ($msg == null || strlen(trim($msg)) == 0) { throw new ValidationException("Message must not be empty"); } $this->message = $msg; } } $obj = new Test(); $obj->message = "Hello!"; echo $obj->message . "\n"; $obj->message = " "; if (!$obj->isValid()) { foreach ($obj->getValidationErrors() as $error) { echo $error . "\n"; } }