I've been messing around with some PHP this morning and came up with this. It's an approach to a data-storing object which stores raw data and accepts input/output as something more user friendly (e.g. storing a price in pence/cents and outputting it in the decimal pound/dollar format). It doesn't compare with efficiency of using methods like getPrice and setPrice, but is nicer to the developer and allows a custom object to be created on-the-fly. Its experimental, but worth sharing.

PHP Code:
class DataObject{
    protected 
$Data;
    protected 
$Fields;
    public function 
__construct(array $Fields, array $Data = array()){
        foreach(
$Fields as $Name => $Options){
            
$this->Data[$Name] = isset($Data[$Name]) ? $Data[$Name] : null;
        }
        
$this->Fields $Fields;
    }
    public function 
__get($Name){
        if(!isset(
$this->Fields[$Name])){
            throw new 
Exception("Field does not exist: {$Name}");
        }else{
            
$Field $this->Fields[$Name];
            if(isset(
$Field['get'])){
                
$Value $Field['get']($this->Data[$Name]);
            }else{
                
$Value $this->Data[$Name];
            }
            if(isset(
$Field['type'])){
                foreach(
explode(' '$Field['type']) as $T){
                    switch(
$T){
                        case 
'date':
                            
$Value date('d/m/Y'$Value);
                        break;
                    }
                }
            }
            return 
$Value;
        }
    }
    public function 
__set($Name$Value){
        if(!isset(
$this->Fields[$Name])){
            throw new 
Exception("Field does not exist: {$Name}");
        }else{
            
$Field $this->Fields[$Name];
            if(isset(
$Field['set'])){
                
$Value $this->Fields[$Name]['set']($Value);
            }
            if(isset(
$Field['type'])){
                foreach(
explode(' '$Field['type']) as $T){
                    switch(
$T){
                        case 
'bool':
                            
$Value = (bool)$Value;
                        break;
                        case 
'int':
                            
$Value = (int)$Value;
                        break;
                        case 
'positive':
                            
$Value abs($Value);
                        break;
                        case 
'date':
                            
$Value strtotime($Value);
                        break;
                    }
                }
            }
            
$this->Data[$Name] = $Value;
        }
    }
    public function 
outputList(){
        echo 
'<h3>Data:</h3>';
        echo 
'<ul>';
        foreach(
$this->Fields as $FieldName => $V){
            
printf('<li><strong>%s:</strong> %s</li>'$FieldName$this->{$FieldName});
        }
        echo 
'</ul>';
    }

Usage:
PHP Code:
class Product extends DataObject{
    public function 
__Construct(array $Data = array()){
        
parent::__construct(
            array(
                
'ID' => array(
                    
'set' => function($Value){
                        throw new 
Exception("IDs are read only.");
                    },
                ),
                
'Price' => array(
                    
'get' => function($Value){
                        return 
sprintf('%.2f'$Value 100);
                    },
                    
'set' => function($Value){
                        return 
round($Value 100);
                    },
                    
'type' => 'positive int'
                
),
                
'Qty' => array(
                    
'type' => 'positive int',
                ),
                
'Added' => array(
                    
'type' => 'date'
                
)
            ),
            
$Data
        
);
    }
}

$Phone = new Product(array('ID' => 3241'Qty' => 5'Added' => time()));
$Phone->outputList();

/* Make some changes */
$Phone->Added 'Yesterday';
$Phone->Price 24.99;
$Phone->Qty *= -2/* Will be made positive */
try{
    
$Phone->ID 1;
}catch(
Exception $e){
    echo 
$e->getMessage();
}

/* Output */
$Phone->outputList();

/* Feeling generous! */
$Phone->Price *= 0.8/* offer: 20% off. Without rounding would have value 19.992 before conversion to int */
$Phone->outputList(); 
This can be used to automatically cast and validate variables when they are set, which can save some hastle with user-input validation. Custom getters and setters can be defined for custom variable types, etc.