Cleaned up the mess I posted yesterday. The code should be pretty self-explanatory now. First I introduced type classes to mimic C structs:
001 <?php // types.php
002
003 class db_type {
004
005 public $name;
006 public $key;
007 public $type;
008 public $engine;
009 public $charset;
010 public $collate;
011
012 }
013
014 class db_type {
015
016 public $name;
017 public $key;
018 public $type;
019 public $engine;
020 public $charset;
021 public $collate;
022
023 }
These don't do much on their own. They're just for passing around variables pointing to correlated data. Also I got rid of the config class entirely, realizing there was no need to load all config files at once and keeping all the data when it's saved in objects anyways.
For now all values are public. It should be self-evident that these aren't meant to be muted. Still if really, really needed encapsulation could be introduced by simply using inheritance:
001 <?php // example.php
002
003 class my_type {
004
005 protected $a = 5;
006
007 }
008
009 class my_module extends my_type {
010
011 public static get_a(my_type $obj) {
012 return $obj->a;
013 }
014
015 }
016
017 $thing = new my_type();
018 var_dump($thing->a); // PHP Fatal error: Uncaught Error: Cannot access protected property my_type::$a
019 var_dump(my_module::get_a($thing)); // 5
Although I believe it should be enough for the documentation or comment hints to mention how an attribute may or may not be used. Encapsulation is nice, but ultimately not a killer feature if you ask me. All in all this code may be very close to legitimate object orientation but still feels much more straight forward to me.
001 <?php // store.php
002
003 class store {
004
005 private static $config = array();
006 private static $dblist = array();
007
008 public static function init() {
009 self::read_dbconf();
010 }
011
012 private static function read_dbconf() {
013 foreach (new FilesystemIterator(realpath(path::DB_CONFIG)) as $i) {
014 if (is_file($i)) {
015 $config['connections'] = array();
016 include ($i->getPathName());
017 $dblist[$config['key']] = db::load_from_conf($config);
018 }
019 }
020 }
021
022 private static function db($key) {
023 return self::$dblist[$key];
024 }
025
026 }
027
028 <?php // db.php
029
030 class db {
031
032 private static $use;
033
034
035 private static $connlist = array();
036
037 // Use like db::use(store::db('demo')->conn('demo'));
038 public static function use($conn) {
039 self::$use = $conn;
040 }
041
042 public static function conn($key) {
043 return self::$connlist[$key];
044 }
045
046 public static function load_from_conf($config) {
047 $db = new db_type();
048 $db->name = $config['name'];
049 $db->key = $config['key'];
050 $db->type = $config['type'];
051 $db->engine = $config['engine'];
052 $db->charset = $config['charset'];
053 $db->collate = $config['collate'];
054
055 foreach ($config['connections'] as $conn) {
056 self::$connlist[$conn['key']] = conn::load_from_conf($conn, $db);
057 if ($config['default'] && $conn['default']) {
058 self::use(self::$connlist[$conn['key']]);
059 }
060 }
061
062 }
063
064 }
065
066
067 <?php // conn.php
068
069 class conn {
070
071 public static function load_from_conf($config, $db) {
072 $conn = new conn_type();
073 $conn->name = $config['name'];
074 $conn->key = $config['key'];
075 $conn->db = $db;
076 $conn->host = $config['host'];
077 $conn->port = $config['port'];
078 $conn->user = $config['user'];
079 $conn->pswd = $config['pswd'];
080 }
081
082 }
Conclusion: I'm happy.
Bonus: Feel free to check out this horrible idea I just had:
001 <?php conn.php
002
003 class conn {
004 public static function ect(conn_type $conn) {
005 // connect
006 }
007 }
008 conn::ect($conn_type); // 8-)