I've worked out my Schema Builder for Propel. In short: I've created a class that can be used to create the 'schema.xml' for building a database for propel dynamically, because I need this for another project. Unfortunately I found out that propel doesn't read the 'schema.xml' file like I thought as configuration file, but you have to create the tables manually using command tool. My idea was to create an on-the-fly extension for propel, so that you could work with propel without having built manually a database. The effect I wanted was to be able to use propel with an initially empty database.However, I've learned much through creating this class, especially about overloading and constructors, so it wasn't useless at all. For further learning processes I would like to share the code with you, to find out whether this is a good solution or what improvements one could make.I've integrated all options that can be used in the XML file, like stated here.The Schema Builder should work like this:$test = new SchemaBuilder('path/to/output', 'db_name', false, array('defaultIdMethod', array('package' => 'test', [... further db params])));$params = array('idMethod' => 'test'); //the params you can give a table$references_1 = array(array('local' => 'test', 'foreign' => 'test')); //references for a foreign key$foreignKey_1 = array('foreignTable' => 'test', 'foreignSchema' => 'test', 'references' => $references_1);$foreignKeys = array($foreignKey_1);$additional_elements = array('foreignKeys' => $foreignKeys); //additional elements inside of the table like unique, index, foreignKey etc.$table_1 = $test->add('table_1', array($params, $additional_elements));$table_1->column_1(array('test', array('size' => 15)));$table_1->column_2(array(1, array('primaryKey' => true)));In this example it outputs two columns inside table_1. What is missing, but what i won't integrate (because the whole thing is useless except for learning) is a store function, which would use the first variable inside of the array as content to put into the database. This way it does nothing with the variable.class SchemaBuilder {private $schema;private $tbl_name;protected $added = array();//Checks if an table existsprivate function tableExists($tbl_name) {    return preg_match(~<table\sname=\$tbl_name\~, $this->schema_object);}//Loads XML File into Objectpublic function loadXML($file) {    return simplexml_load_string(file_get_contents($file));}/** Writes XML Content to a schemata file*/private function writeXML($file, $content) {    return file_put_contents($file, $content);}/** Appends Table to Schemata*/private function appendTable($params, $i=0, $columns=array(), $additional_params=array(), $column_added=false) {    $columns_xml = ;    $foreignKeys_xml = ;    $indexes_xml = ;    $uniques_xml = ;    $id_method_parameters_xml = ;    $external_schemas_xml = ;    $i=0;    $table_params = (isset($params[0]) ? 'name='.$params[0].' ' : 'name='.$this->tbl_name.' ').(isset($params[1]) ? 'phpName='.$params[1].' ' : '').(isset($params[2]) ? 'namespace='.$params[2].' ' : '').(isset($params[3]) ? 'idMethod='.$params[3].' ' : '').(isset($params[4]) ? 'package='.$params[4].' ' : '').(isset($params[5]) ? 'schema='.$params[5].' ' : '').(isset($params[6]) ? 'skipSql='.$params[6].' ' : '').(isset($params[7]) ? 'abstract='.$params[7].' ' : '').(isset($params[8]) ? 'phpNamingMethod='.$params[8].' ' : '').(isset($params[9]) ? 'baseClass='.$params[9].' ' : '').(isset($params[10]) ? 'description='.$params[10].' ' : '').(isset($params[11]) ? 'heavyIndexing='.$params[11].' ' : '').(isset($params[12]) ? 'readOnly='.$params[12].' ' : '').(isset($params[13]) ? 'treeMode='.$params[13].' ' : '').(isset($params[14]) ? 'reloadOnInsert='.$params[14].' ' : '').(isset($params[15]) ? 'reloadOnUpdate='.$params[15].' ' : '').(isset($params[16]) ? 'allowPkInsert='.$params[16].'' : '');    foreach ($columns as $column) {        if (isset($column_added[is_object($column) ? reset($column['name']) : $column['name']])) {            $column_params = (isset($column['name']) ? 'name='.$column['name'].' ' : 'name=column_'.$i.' ').(isset($column['phpName']) ? 'phpName='.$column['phpName'].' ' : '').(isset($column['type']) ? 'type='.$column['type'].' ' : '').(isset($column['required']) ? 'required='.$column['required'].' ' : '').(isset($column['primaryKey']) ? 'primaryKey='.$column['primaryKey'].' ' : '').(isset($column['autoIncrement']) ? 'autoIncrement='.$column['autoIncrement'].' ' : '').(isset($column['size']) ? 'size='.$column['size'].' ' : '').(isset($column['tableMapName']) ? 'tableMapName='.$column['tableMapName'].' ' : '').(isset($column['phpType']) ? 'phpType='.$column['phpType'].' ' : '').(isset($column['sqlType']) ? 'sqlType='.$column['sqlType'].' ' : '').(isset($column['scale']) ? 'scale='.$column['scale'].' ' : '').(isset($column['defaultValue']) ? 'defaultValue='.$column['defaultValue'].' ' : '').(isset($column['defaultExpr']) ? 'defaultExpr='.$column['defaultExpr'].' ' : '').(isset($column['valueSet']) ? 'valueSet='.$column['valueSet'].' ' : '').(isset($column['lazyLoad']) ? 'lazyLoad='.$column['lazyLoad'].' ' : '').(isset($column['description']) ? 'description='.$column['description'].' ' : '').(isset($column['primaryString']) ? 'primaryString='.$column['primaryString'].' ' : '').(isset($column['phpNamingMethod']) ? 'phpNamingMethod='.$column['phpNamingMethod'].' ' : '').(isset($column['inheritance']) ? 'inheritance='.$column['inheritance'].' ' : '');            $columns_xml .= \t\t<column $column_params/>\n;            $i++;        }    }    if (isset($additional_params[0])) {        foreach ($additional_params[0] as $foreignKey) {            $foreignKey_params = 'foreignTable='.$foreignKey['foreignTable'].' '.(isset($foreignKey['foreignSchema']) ? 'foreignSchema='.$foreignKey['foreignSchema'].' ' : '').(isset($foreignKey['name']) ? 'name='.$foreignKey['name'].' ' : '').(isset($foreignKey['phpName']) ? 'phpName='.$foreignKey['phpName'].' ' : '').(isset($foreignKey['refPhpName']) ? 'refPhpName='.$foreignKey['refPhpName'].' ' : '').(isset($foreignKey['onDelete']) ? 'onDelete='.$foreignKey['onDelete'].' ' : '').(isset($foreignKey['onUpdate']) ? 'onUpdate='.$foreignKey['onUpdate'].' ' : '').(isset($foreignKey['skipSql']) ? 'skipSql='.$foreignKey['skipSql'].' ' : '').(isset($foreignKey['defaultJoin']) ? 'defaultJoin='.$foreignKey['defaultJoin'].' ' : '');            $foreignKeys_xml .= \t\t<foreign-key $foreignKey_params>\n;            foreach (isset($foreignKey->reference) ? $foreignKey->reference : $foreignKey['references'] as $reference) {                $local = $reference['local'];                $foreign = $reference['foreign'];                $foreignKeys_xml .= \t\t\t<reference local=\$local\ foreign=\$foreign\/>\n;            }            $foreignKeys_xml .= \t\t</foreign-key>\n;        }    }    if (isset($additional_params[1])) {        foreach ($additional_params[1] as $index) {            $index_name = isset($index['name']) ? 'name='.$index['name'].'' : '';            $indexes_xml .= \t\t<index $index_name>\n;            foreach ($index->index_column as $index_column) {                $index_column_name = 'name='.$index_column['name'].'';                $index_column_size = isset($index_column['size']) ? 'size='.$index_column['size'].' ' : '';                $indexes_xml .= \t\t\t<index-column $index_column_name $index_column_size/>\n;            }            $indexes_xml .= \t\t</index>\n;        }    }    if (isset($additional_params[2])) {        foreach ($additional_params[2] as $unique) {            $unique_name = isset($unique['name']) ? 'name='.$unique['name'].'' : '';            $uniques_xml .= \t\t<unique $index_name>\n;            foreach ($unique->unique_column as $unique_column) {                $unique_column_name = 'name='.$unique_column['name'].'';                $unique_column_size = isset($unique_column['size']) ? 'size='.$unique_column['size'].' ' : '';                $uniques_xml .= \t\t\t<unique-column $unique_column_name $unique_column_size/>\n;            }            $indexes_xml .= \t\t</unique>\n;        }    }    if (isset($additional_params[3])) {        foreach ($additional_params[3] as $id_method_parameter) {            $id_method_parameter_value = $id_method_parameter['value'];            $id_method_parameters_xml .= <id-method-parameter value=\$id_method_parameter_value\/>\n;        }    }    if (isset($additional_params[4])) {        foreach ($additional_params[4] as $external_schema) {            $external_schema_filename = 'filename='.$external_schema['filename'].'';            $external_schema_referenceOnly = isset($external_schema['referenceOnly']) ? 'referenceOnly='.$external_schema['referenceOnly'].' ' : 'referenceOnly=true ';            $external_schemas_xml .= <external-schema $external_schema_filename $external_schema_referenceOnly/>\n;        }    }    return \t<table $table_params>\n$columns_xml $foreignKeys_xml $indexes_xml $uniques_xml $id_method_parameters_xml  $external_schemas_xml</table>\n;}/** Creates Schemata Content */private function createSchema($params, $tables=array(), $column_added=false) {    $tables_schema = '';    $i=0;    foreach ($tables as $table) {        $tables_schema .= $this->appendTable($table[0], $i, $table[1], $table[2], $column_added);        $i++;    }    $package = isset($params[2]['package']) ? 'package='.$params[2]['package'].' ' : '';    $schema = isset($params[2]['schema']) ? 'schema='.$params[2]['schema'].' ' : '';    $namespace = isset($params[2]['namespace']) ? 'namespace='.$params[2]['namespace'].' ' : '';    $baseclass = isset($params[2]['baseclass']) ? 'baseclass='.$params[2]['baseclass'].' ' : '';    $defaultPhpNamingMethod = isset($params[2]['defaultPhpNamingMethod']) ? 'defaultPhpNamingMethod='.$params[2]['defaultPhpNamingMethod'].' ' : '';    $heavyIndexing = isset($params[2]['heavyIndexing']) ? 'heavyIndexing='.$params[2]['heavyIndexing'].' ' : '';    $tablePrefix = isset($params[2]['tablePrefix']) ? 'tablePrefix='.$params[2]['tablePrefix'].' ' : '';    $additional_params = $package.$schema.$namespace.$baseclass.$defaultPhpNamingMethod.$heavyIndexing.$tablePrefix;    return <database name=\$params[0]\ defaultIdMethod=\$params[1]\ $additional_params>\n$tables_schema</database>;}//Reads Schema or creates one if its emptyprivate function readSchema() {    return is_object($this->schema) ? $this->schema : $this->createSchema($this->params);}//Returns array of Tables of the current Schematapublic function readTables($schema=false) {    $i=0;    $schema = is_object($schema) ? $schema : $this->schema;    if (is_object($schema)) {        foreach ($schema->table as $table) {            if (isset($this->added[reset($table['name'])])) {                $object_array[$i] = $table;                $tables[$i][0][0] = $table['name'];                if (isset($table['phpName']))  {                    $tables[$i][0][1] = $table['phpName'];                }                if (isset($table['namespace']))  {                    $tables[$i][0][2] = $table['namespace'];                }                if (isset($table['idMethod']))  {                    $tables[$i][0][3] = $table['idMethod'];                }                if (isset($table['package']))  {                    $tables[$i][0][4] = $table['package'];                }                if (isset($table['schema']))  {                    $tables[$i][0][5] = $table['schema'];                }                if (isset($table['skipSql']))  {                    $tables[$i][0][6] = $table['skipSql'];                }                if (isset($table['abstract']))  {                    $tables[$i][0][7] = $table['abstract'];                }                if (isset($table['phpNamingMethod']))  {                    $tables[$i][0][8] = $table['phpNamingMethod'];                }                if (isset($table['baseClass']))  {                    $tables[$i][0][9] = $table['baseClass'];                }                if (isset($table['description']))  {                    $tables[$i][0][10] = $table['description'];                }                if (isset($table['heavyIndexing']))  {                    $tables[$i][0][11] = $table['heavyIndexing'];                }                if (isset($table['readOnly']))  {                    $tables[$i][0][12] = $table['readOnly'];                }                if (isset($table['treeMode']))  {                    $tables[$i][0][13] = $table['treeMode'];                }                if (isset($table['reloadOnInsert']))  {                    $tables[$i][0][14] = $table['reloadOnInsert'];                }                if (isset($table['reloadOnUpdate']))  {                    $tables[$i][0][15] = $table['reloadOnUpdate'];                }                if (isset($table['allowPkInsert']))  {                    $tables[$i][0][16] = $table['allowPkInsert'];                }                if (isset($table->column)) {                    $a=0;                    foreach ($table->column as $column) {                        $tables[$i][1][$a] = $column;                        $a++;                    }                } else {                    $tables[$i][1] = array();                }                $fk = 'foreign-key';                if (isset($table->$fk)) {                    $a=0;                    foreach ($table->$fk as $foreign_key) {                        $tables[$i][2][0][$a] = $foreign_key;                        $a++;                    }                } else {                    $tables[$i][2][0] = array();                }                if (isset($table->index)) {                    $a=0;                    foreach ($table->index as $index) {                        $tables[$i][2][1][$a] = $index;                        $a++;                    }                } else {                    $tables[$i][2][1] = array();                }                if (isset($table->unique)) {                    $a=0;                    foreach ($table->unique as $unique) {                        $tables[$i][2][2][$a] = $unique;                        $a++;                    }                } else {                    $tables[$i][2][2] = array();                }                $id_method = 'id-method-parameter';                if (isset($table->$id_method)) {                    $a=0;                    foreach ($table->$id_method as $id_method_parameter) {                        $tables[$i][2][3][$a] = $id_method_parameter;                        $a++;                    }                } else {                    $tables[$i][2][3] = array();                }                if (isset($table->external_schema)) {                    $a=0;                    foreach ($table->external_schema as $external_schema) {                        $tables[$i][2][4][$a] = $external_schema;                        $a++;                    }                } else {                    $tables[$i][2][4] = array();                }                $i++;            }        }    }    return array(object_array => isset($object_array) ? $object_array : array(), tables => isset($tables) ? $tables : array(), count => isset($i) ? $i-1 : -1);}/** Builds Schemata file* Schemata Builds can be freezed for performance gain*/public function build($tables=array(), $tbl_name=, $column_added=false) {    $tables = empty($tables) ? $this->readTables() : $tables;    $this->schema_object = empty($column_added) ? $this->createSchema($this->params, $tables) : $this->createSchema($this->params, $tables, $column_added);    return $this->freeze ? new Table($this, false) : $this->writeXML($this->dbfile, $this->schema_object) ? new Table($this, $tbl_name, $this->dbfile) : new Table($this, false);}//Loads the Schema when constructing and saves whether to freeze the schemapublic function __construct($file, $db_name, $freeze=false, $params=array()) {    $this->dbfile = $file.'schema.xml';    $this->schema = file_exists($file.'schema.xml') ? $this->loadXML($file.'schema.xml') : fopen($file.'schema.xml', 'w+');    $this->params = array($db_name, isset($params[0]) ? $params[0] : 'native', isset($params[1]) ? $params[1] : array());    $this->schema_object = $this->readSchema();    $this->freeze = $freeze;}//Constructs the tablepublic function add($table_name, $params=array()) {    $this->tbl_name = $table_name;    $current_tables = $this->readTables();    if (!empty($current_tables)) {        $object_array = $current_tables['object_array'];        $tables = $current_tables['tables'];        $i = $current_tables['count'];    } else {        $i=-1;      }    $tables[$i+1][0][0] = $table_name;    if (isset($params[0]['phpName']))  {        $tables[$i+1][0][1] = $params[0]['phpName'];    }    if (isset($params[0]['namespace']))  {        $tables[$i+1][0][2] = $params[0]['namespace'];    }    if (isset($params[0]['idMethod']))  {        $tables[$i+1][0][3] = $params[0]['idMethod'];    }    if (isset($params[0]['package']))  {        $tables[$i+1][0][4] = $params[0]['package'];    }    if (isset($params[0]['schema']))  {        $tables[$i+1][0][5] = $params[0]['schema'];    }    if (isset($params[0]['skipSql']))  {        $tables[$i+1][0][6] = $params[0]['skipSql'];    }    if (isset($params[0]['abstract']))  {        $tables[$i+1][0][7] = $params[0]['abstract'];    }    if (isset($params[0]['phpNamingMethod']))  {        $tables[$i+1][0][8] = $params[0]['phpNamingMethod'];    }    if (isset($params[0]['baseClass']))  {        $tables[$i+1][0][9] = $params[0]['baseClass'];    }    if (isset($params[0]['description']))  {        $tables[$i+1][0][10] = $params[0]['description'];    }    if (isset($params[0]['heavyIndexing']))  {        $tables[$i+1][0][11] = $params[0]['heavyIndexing'];    }    if (isset($params[0]['readOnly']))  {        $tables[$i+1][0][12] = $params[0]['readOnly'];    }    if (isset($params[0]['treeMode']))  {        $tables[$i+1][0][13] = $params[0]['treeMode'];    }    if (isset($params[0]['reloadOnInsert']))  {        $tables[$i+1][0][14] = $params[0]['reloadOnInsert'];    }    if (isset($params[0]['reloadOnUpdate']))  {        $tables[$i+1][0][15] = $params[0]['reloadOnUpdate'];    }    if (isset($params[0]['allowPkInsert']))  {        $tables[$i+1][0][16] = $params[0]['allowPkInsert'];    }    $tables[$i+1][1] = array();    $tables[$i+1][2] = array();    if (isset($params[1]) && !empty($params[1])) {        if (isset($params[1]['foreignKeys'])) {            $tables[$i+1][2][0] = $params[1]['foreignKeys'];        }        if (isset($params[1]['indexes'])) {            $tables[$i+1][2][0] = $params[1]['indexes'];        }        if (isset($params[1]['uniques'])) {            $tables[$i+1][2][0] = $params[1]['uniques'];        }        if (isset($params[1]['id_method_parameters'])) {            $tables[$i+1][2][0] = $params[1]['id_method_parameters'];        }        if (isset($params[1]['external_schemas'])) {            $tables[$i+1][2][0] = $params[1]['external_schemas'];        }    }    $boolean = $this->freeze ? true : $this->tableExists($table_name);    $this->added[$table_name] = true;    return $boolean ? true : $this->build($tables, $table_name);}}class Table extends SchemaBuilder {//Searches an array of tables and returns the position of the tableprivate function tableSearch($tables) {    $i=0;    foreach ($tables as $table) {        $found = reset($table[$i][0][0])==$this->name;        if ($found) {            $key = $i;        }        $i++;    }    return isset($key) ? $key : false;}//Searches in a table for a column and returns the position of the columnprivate function columnSearch($column_name, $table_columns) {    $i=0;    foreach ($table_columns as $column) {        $found = $column['name']==$column_name;        if ($found) {            $key = $i;        }        $i++;    }    return isset($key) ? $key : false;}//Whether new Columns can be added or notpublic function __construct($instance, $tbl_name=false, $file=schema.xml) {    $this->SchemaBuilder = $instance;    $this->allowed = !empty($tbl_name);    $this->name = $tbl_name;    $this->dbfile = $file;    $this->columnKey = isset($this->columnKey) ? $this->columnKey : 0;}//Dynamically extends the Table with a columnpublic function __call($column_name, $variables) {    if($this->allowed) {        $schema = file_exists($this->dbfile) ? $this->SchemaBuilder->loadXML($this->dbfile) : fopen($this->dbfile, 'w+');        $all_tables = $this->SchemaBuilder->readTables($schema);        $table_key = $this->tableSearch(($all_tables['tables']));            if (isset($all_tables['tables'][$table_key][1])) {                $column_found = $this->columnSearch($column_name, $all_tables['tables'][$table_key][1]);            } else {                $column_found = false;            }            if (!is_int($column_found)) {                $this->added[$column_name] = true;                $column_key = $this->columnKey;                $all_tables['tables'][$table_key][1][$column_key]['name'] = $column_name;                if (isset($variables[0][1]['phpName'])) {                    $all_tables['tables'][$table_key][1][$column_key]['phpName'] = $variables[0][1]['phpName'];                }                if (isset($variables[0][1]['type'])) {                    $all_tables['tables'][$table_key][1][$column_key]['type'] =  $variables[0][1]['type'];                }                if (isset($variables[0][1]['required'])) {                    $all_tables['tables'][$table_key][1][$column_key]['required'] = $variables[0][1]['required'];                }                if (isset($variables[0][1]['primaryKey'])) {                    $all_tables['tables'][$table_key][1][$column_key]['primaryKey'] = $variables[0][1]['primaryKey'];                }                if (isset($variables[0][1]['autoIncrement'])) {                    $all_tables['tables'][$table_key][1][$column_key]['autoIncrement'] =  $variables[0][1]['autoIncrement'];                }                if (isset($variables[0][1]['size'])) {                    $all_tables['tables'][$table_key][1][$column_key]['size'] =  $variables[0][1]['size'];                }                if (!isset($all_tables['tables'][$table_key][0])) {                    $all_tables['tables'][$table_key][0] = array();                }                if (!isset($all_tables['tables'][$table_key][2])) {                    $all_tables['tables'][$table_key][2] = array();                }                $this->SchemaBuilder->build($all_tables['tables'], $this->name, $this->added);                return $this->columnKey++;            } else {                return false;            }    } else {        return false;    }}}
Propel ORM Schema Builder
php;database;xml;propel