I have a collection of PHP classes that can be instantiated traditionally using constructors. Now I want to add the ability to instantiate these objects using YAML configuration files.
Here’s an example of a configuration file describing a web form:
title: Contact
fields:
message:
type: text
required: true
topic:
type: dropdown
options: ["HTML", "CSS", "PHP"]
This should result in a Form object with two corresponding Field objects. In other words, the configuration files sometimes describe objects that contain other objects.
I don’t want simply a mapping from YAML key/value pairs to PHP properties because I want to allow shorthand syntax in the configuration files. For instance, I want to abbreviate some property names and also be able to type something like default: today, where “today” is not interpreted as a string literal but rather transformed into the current timestamp.
Since many of the classes are subclasses, I’m looking for a solution that also lets me somehow “inherit” configuration logic from the superclass.
I want to avoid modifying the existing classes, but I am willing to do so if it allows for a simpler solution. On second thought, I don’t really mind modifying the existing classes; I’m just interested in the best solution.
How do I best create objects from configuration files in this manner?
You could take the following approach:
Each of your model-classes to be populated from the configuration-file should implement an interface with, for example, a method
fromArray($data).On the top-level you know the type of Object (a Form) you want to create. This object is instanciated and the data from your config-file passed to the fromArray-method. The object then traverses the configuration-data and “knows” what to do with each of the entries.
For each element of the ‘fields’-array it can then pass the data on to the child-objects which
can themselves traverse and handle the configuration properly (including things like interpreting ‘today’ in a special way for any field that accepts a date).
Just split up the responsibility of creating object into special methods that know how to handle this kind of object.