PHP Abstract Base Class - Including validation

An example of a base class.

Sample extension and call for instantiation:

PHP

<?php
class Course extends Base {
 
        public function __construct($properties) {
                $this->_properties array(
                        'id'=>array(
                                'required' => false,
                                'default' => null,
                                'filter' => FILTER_VALIDATE_INT,
                                'options' => array('min_range' => 0'max_range' => PHP_INT_MAX)),
                        'name' => array(
                                'required' => true,
                                'default' => null,
                                'filter' => FILTER_VALIDATE_REGEXP,
                                'options' => array('regexp' => '/^[\w\,\.\'\-\(\)\$ ]{3,}$/')),
                        'isCore' => array(
                                'required' => true,
                                'default' => true,
                                'filter' => FILTER_VALIDATE_BOOLEAN));
 
                return parent::__construct($properties);
        }
}

PHP

<?php
Abstract Class Base {
 
        protected $_properties null;
        protected $_data array();
        protected $_valid false;
        protected $_error_message array();
 
        function __construct($properties null) {
                if (is_array($properties)) {
                        foreach ($this->_properties as $k => $v) {
                                if (isset($properties[$k])) {
                                        $p $properties[$k];
                                        if (is_string($p)) {
                                                $p trim($p);
                                                if ($p === "") {
                                                        if (empty($p) && $v['required']) {  // this should never happen
                                                                return null;
                                                        }
                                                }
                                        }
                                } else {
                                        $p $v['default'];
                                }
                                $this->_data[$k] = $p;
                        }
                        $filter filter_var_array($this->_data,$this->_properties);
                        if ($filter === false || in_array(false,$filter,true)) {
                                foreach ($filter as $k => $v) {
                                        if (($v === false) &&
                                                ($this->_properties[$k]['filter'] !== FILTER_VALIDATE_BOOLEAN)) {
                                                // This is an important test, a boolean false, 
                                                // validated as such, doesn't mean the filter
                                                // failed.  
                                                trigger_error('Invalid data');
                                        }
                                }
                        }
                }
                return $this->_data;
        }
 
        function __get($property) {
                return isset($this->_data[$property]) ? $this->_data[$property] : null;
        }
 
        function __set($property$value) {
                $this->_data[$property] = $value;
        }
 
        function toJson() {
                return json_encode($this->_data);
        }
 
        function isValid($property null) {
                if ($property === null)
                        return $this->_valid || (count($this->_error_message) == 0);
                else
                        return !isset($this->_error_message[$property]);
        }
 
        function error($property) {
                if (isset($this->_error_message[$property])) {
                        return $this->_error_message[$property];
                } else {
                        return '';
                }
        }
}