Mapping/parsing database table data to output data I have currently implemented this simple example of a database to output for a REST API to show the way information is being parsed, mapped and serialized starting from database data converting it to JSON. This solution currently works fine, but the problem comes from the fact that it makes use of PHP tricks (like calling a function from a string) which I really do not approve of. Do you think there is a better way/pattern to implement/split this solution?

class DataMapper {
    /**
     * @var array
     */
    private $rawData;

    /**
     * @var array
     */
    private $parsedData;

    /**
     * @var array
     */
    private $mapping = [
        'dbField1' =&gt; 'outputField1',
        'dbField2' =&gt; ['outputField2' =&gt; ['double']],
        'dbField3' =&gt; ['outputField3' =&gt; ['double', 'dollars']]
    ];

    public function __construct(array $data) {
        $this-&gt;rawData = $data;
        $this-&gt;mapData();
    }

    /**
     * @param $value
     * @return mixed
     */
    private function double($value) {
        return $value * 2;
    }

    /**
     * @param $value
     * @return string
     */
    private function dollars($value) {
        return $value . "$";
    }

    // Yes, I know the methods shouldn't be here but it rather be decoupled in another class and
    // injected with a DI but I wrote it like this just as an example
    private function mapData() {
        foreach($this-&gt;mapping as $dbFieldName =&gt; $content) {

            if(isset($this-&gt;rawData[$dbFieldName])) {

                if(is_string($content)) {
                    $this-&gt;parsedData[$content] = $this-&gt;rawData[$dbFieldName];
                } else
                if (is_array($content)) {
                    $frontFieldName = key($content);
                    $functionsArray = reset($content);
                    $value = $this-&gt;rawData[$dbFieldName];

                    foreach($functionsArray as $functionName) {
                        $value = $this-&gt;{$functionName}($value);
                    }
                    $this-&gt;parsedData[$frontFieldName] = $value;
                }
            }
        }
    }

    /**
     * Simple getter
     * @return array
     */
    public function getParsedData() {
        return $this-&gt;parsedData;
    }
}

// Usually the data comes from the DB so it would be in some kind of Row Set structure
$data = ['dbField1' =&gt; 1, 'dbField2' =&gt; 1, 'dbField3' =&gt; 1];
// The data is handed to the Holder which parses it
$dm = new DataMapper($data);
// The data is parsed so it can be 
echo json_encode($dm-&gt;getParsedData());


You can experiment with it here. 

I would highly appreciate it if you could give me pointers to how this could be made better programming to interfaces instead of simple strings; using composition, dependency injections, and maybe separation of the mapper functions in some abstract factories.
The only thing I would change is the mapping definition, e.g. separate the configuration from the actual logic so you don't have to write many mappers, but can use one with multiple configurations.

Quoting http://martinfowler.com/eaaCatalog/metadataMapping.html


  Much of the code that deals with object-relational mapping describes how fields in the database correspond to fields in in-memory objects. The resulting code tends to be tedious and repetitive to write. A Metadata Mapping allows developers to define the mappings in a simple tabular form, which can then be processed by generic code to carry out the details of reading, inserting, and updating the data.


The dollars method probably shouldn't be in your mapper though, because it is formatting the data. Move this to the presentation layer. If you want to map to money, introduce a Money object.

You can spice it up by also introducing a TypeConverter thing which then knows how to handle certain types from the ColumnDefinition, e.g. something like

class FooMapDefinition implements IteratorAggregate
{
    private $map = [
        'someProperty' =&gt; [
            'mapTo': 'propertyName',
            'mapAs': Money::class
        ],
        // … more definitions
    ];

    public function getIterator()
    {
        return this new ArrayIterator($this-&gt;map);
    }

}


Then inject a TypeConverterFactory into the mapper. When you map the properties, you let the factory create a converter from the class name in mapAs, push the value from the source data through it and then map it to your entity.