Search code examples
phpooplate-static-binding

defining called class properties via parent class


I have written a parent class (using late static binding) from which my database classes are inherited. I'm trying to write a constructor to assign each table column as a public property of the child classes. So far i could write the constructor in child classes, which works just fine, but I want to put it in the parent class so that all child classes properties are defined automatically. Here is my child class:

class Sale extends DatabaseObject {

    protected static $table_name="invoices";
    protected static $db_fields = array();

    function __construct() {
        global $database;
        $query_cols = " SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_NAME LIKE '" . self::$table_name . "' AND TABLE_SCHEMA LIKE '" . DB_NAME . "' ORDER BY ORDINAL_POSITION ASC";
        $cols = $database->query($query_cols);
        while($col = $database->fetch_array($cols)) {
            if(!property_exists($this,$col['COLUMN_NAME'])) {
                $this->$col['COLUMN_NAME']=NULL;
                array_push(self::$db_fields,$col['COLUMN_NAME']);
            }
        }
    }
}

To use this constructor in the parent I need to be able to define the called class property.

function __construct() {
    $class_name = get_called_class();
    $query_cols = " SELECT COLUMN_NAME FROM information_schema WHERE TABLE_NAME LIKE '" . static::$table_name . "' AND TABLE_SCHEMA LIKE '" . DB_NAME . "'";
    $query_cols .= " ORDER BY ORDINAL_POSITION ASC";
    $cols = $database->query($query_cols);
    while($col = $database->fetch_array($cols)) {
        if(!property_exists($class_name,$col['COLUMN_NAME'])) {
            // the code to define called class public property?!
        }
    }
}

Thanks in advance.


Solution

  • Generally, if you're accessing static members of a class, you can use static::$foo rather than self::$foo, however you would need to redeclare the empty initial static variable for each child class, otherwise it will use the parent's static member.

    An alternative approach I use for a Model system, is to use the class name as part of an array structure.

    So instead of

    array_push(self::$db_fields,$col['COLUMN_NAME']);
    

    you would do

    array_push(self::$db_fields[$class_name],$col['COLUMN_NAME']);
    

    This way you basically have a single array at the parent class level, with each element an array of the child class fields, keyed by their class name.