I'm saving the forms of my website in a MySQL database, with a separate table containing the form inputs. The table with inputs has the field 'type', which contains the type of an input, e.g. checkbox, text, select, password, etc. (matching HTML input types)

Table Inputs
------------
id
form_id
name
default_val
required
type

The inputs are also represented in the model of my framework by a generic input class containing generic info (name/default value/is required/..) extended by child classes for each type of input. Each child class has specific characteristics, so it's worth the trouble of keeping them separate and not merging them into the generic class.

Input
  |
  |--  Checkbox extends Input
  |--  Select extends Input
  |--  Password extends Input

Currently, I'm using mysqli->fetch_object to retrieve the inputs from the database and create generic input objects. The generic object can't be cast to a child object (user defined objects can not be cast), so that won't work.

Right now I'm using a special constructor in each child input class, to copy the values of the generic input object I pass as a parameter. This doesn't feel right, it doesn't seem to me like a good OOP practice.

My problem is: I want to use a single database table for all the inputs, but in the model I want to treat each type of input as a different class/object. The class_name is saved in the table, hence it is available right after calling fetch_object for which you need it.

How can I retrieve my input objects from the database in the correct class type?

    John44;11010747 wrote:

    Currently, I'm using mysqli->fetch_object to retrieve the inputs from the database and create generic input objects.

    It doesn't create generic input objects. It creates a generic object. That is, there is no real difference between fetching the row data into an array and an object. You either get an array with the table columns as array keys, or you get an object with the table columns as instance properties.

    John44;11010747 wrote:

    How can I retrieve my input objects from the database in the correct class type?

    You could use a static factory function, along these lines

    class Input
    {
    	# Not public visibility to force use of constructor function
    	protected function __construct($data)
    	{
    		# here I'd keep assignment of everything which is generic.
    		$this->name = $data['name'];
    		$this->required = (bool) $data['row'];
    		# etc
    	}
    
    public static fromDB($row)
    {
    	$class = $row['type'];
    	if (!class_exists($class))
    	{
    		# error handling
    	}
    	return new $class($row);
    }
    }
    
    class Checkbox extends Input
    {
    	protected function __construct($data)
    	{
    		parent::construct($data);
    		$this->checked = (bool) $data['checked'];
    	}
    }
    

    Also note that while I'm passing row data as an associative array in the above example, you could of course still pass row data as generic objects instead.

      Write a Reply...