doddsey_65 Posted June 8, 2011 Share Posted June 8, 2011 i have several classes which have a private var $db. when i use a method that requires a db connection i connect to the database and assign it to $db. however this means connecting to the database in each method. Is there any way i can connect to the database in the main core class and then call this connection in other classes? i thought of connecting in the main class and then extending each other class off it but you cant use the private variable $db, just methods. Any tips? something like: class mainCore { public $db; public function __construct() { //connect to database } } class anotherClass extends mainCore { public function someFunction() { $this->db->query(); } } $asf = new mainCore; Quote Link to comment https://forums.phpfreaks.com/topic/238737-db-connection-in-classes/ Share on other sites More sharing options...
trq Posted June 8, 2011 Share Posted June 8, 2011 Extending a Main Core class is ridiculous, are all your classes the same type? The best thing you can do is use some form of dependency injection to inject the database object into classes that need it. The simplest form of dependency injection is simply passing the required object into the constructor of the class that needs it. Of course, the object that needs it should also verify it understands the API of the object being passed in (you can do this easily enough using interfaces or an abstract database object). Quote Link to comment https://forums.phpfreaks.com/topic/238737-db-connection-in-classes/#findComment-1226802 Share on other sites More sharing options...
doddsey_65 Posted June 8, 2011 Author Share Posted June 8, 2011 that all sounds good but i didnt understand any of it. Do you perhaps have a small example or is there a tutorial out there somewhere? Quote Link to comment https://forums.phpfreaks.com/topic/238737-db-connection-in-classes/#findComment-1226807 Share on other sites More sharing options...
jedeye Posted June 8, 2011 Share Posted June 8, 2011 i have several classes which have a private var $db. when i use a method that requires a db connection i connect to the database and assign it to $db. however this means connecting to the database in each method. Is there any way i can connect to the database in the main core class and then call this connection in other classes? i thought of connecting in the main class and then extending each other class off it but you cant use the private variable $db, just methods. Any tips? something like: class mainCore { public $db; public function __construct() { //connect to database } } class anotherClass extends mainCore { public function someFunction() { $this->db->query(); } } $asf = new mainCore; make your db vars constants the use this in your DBClass, and do as you were by extending off DBClass with other classes. class DBClass { protected function __construct($dbConnectionNew){ $this->dbConnection = $dbConnectionNew; } function getConnection(){ $db_connection = pg_connect("host=" . self::db_host . " dbname=" . self::db_database . " user=" . self::db_user . " password=" . self::db_pass); return $db_connection; } } then from with-in your other classes you need to call it like this.. class OtherClassName extends DBClassName { private static instance; public function getInstance (){ if (!isset(self::$instance)) { self::$instance = new OtherClassName(parent::getConnection()); } return self::$instance; } } Quote Link to comment https://forums.phpfreaks.com/topic/238737-db-connection-in-classes/#findComment-1226814 Share on other sites More sharing options...
doddsey_65 Posted June 8, 2011 Author Share Posted June 8, 2011 okay i have amended the database class like so: class db_pdo extends PDO { public $query_count = 0; public $execution_time = 0; public $query_list = ''; public $conn; static $hostname = 'localhost'; static $database = 'asf_forum'; static $username = '********'; static $password = '********'; public function __construct($conn) { $this->conn = $conn; } function getConnection() { $db_connection = parent::__construct("host=" . self::$hostname . " dbname=" . self::$database . " user=" . self::$username . " password=" . self::$password); return $db_connection; } but then what do i do in the classes i want to use the database connection? i added this to my forum class private static instance; public function getInstance() { if (!isset(self::$instance)) { self::$instance = new OtherClassNameHere(parent::getConnection()); } return self::$instance; } but im not sure what OtherClassNameHere is supposed to be. Quote Link to comment https://forums.phpfreaks.com/topic/238737-db-connection-in-classes/#findComment-1226817 Share on other sites More sharing options...
doddsey_65 Posted June 8, 2011 Author Share Posted June 8, 2011 okay this is what im doing now but how do i run a query? class db_pdo extends PDO { public $conn; public function __construct($connectionNew) { $this->conn = $connectionNew; } public function getConnection() { $dsn = "mysql:dbname=asf_forum;host=localhost"; $user = "************"; $pass = "************"; $connection = parent::__construct($dsn, $user, $pass); return $connection; } class mainCore extends db_pdo { public function getInstance() { self::$instance = new mainCore(parent::getConnection()); return self::$instance; } i have tried using self::$instance->query but it comes up with the error Fatal error: Call to a member function query() on a non-object Any advice? it is connecting to the database btw. Quote Link to comment https://forums.phpfreaks.com/topic/238737-db-connection-in-classes/#findComment-1226831 Share on other sites More sharing options...
ignace Posted June 8, 2011 Share Posted June 8, 2011 That's because you decided to listen to the less experienced person while thorpe gave you the answer: class MyObjectThatAlsoHappensToInteractWithADatabase { private $db = null; public function __construct(Database $db) { $this->db = $db; } } Another option you could opt for is to use a factory: class MyObjectThatAlsoHappensToInteractWithADatabase { private $db = null; public function __construct() { $this->db = AppAssetFactory::getDb(); } } That saves you the trouble of having to pass $db all the time. Quote Link to comment https://forums.phpfreaks.com/topic/238737-db-connection-in-classes/#findComment-1226874 Share on other sites More sharing options...
doddsey_65 Posted June 8, 2011 Author Share Posted June 8, 2011 so to get my config variable within a class could i use this: class mainCore { public static function setVariable() { return $config = 'Config Var'; } } class testClass { public $config; public function __construct() { $this->config = mainCore::setVariable(); echo $this->config; } } sorry if it's still wrong, im just trying to grasp this concept. Ive only ever used global keyword. Quote Link to comment https://forums.phpfreaks.com/topic/238737-db-connection-in-classes/#findComment-1226884 Share on other sites More sharing options...
KevinM1 Posted June 8, 2011 Share Posted June 8, 2011 That's one way to get that variable, yes. Also, once again, your data members should either be private or protected, depending on whether or not you anticipate making child classes. Making them public breaks encapsulation. In other words, do this: class testClass { private $config; // rest of class } Quote Link to comment https://forums.phpfreaks.com/topic/238737-db-connection-in-classes/#findComment-1226887 Share on other sites More sharing options...
doddsey_65 Posted June 8, 2011 Author Share Posted June 8, 2011 thanks, i have used private on the actual script just forgot to make the example ones private. So theres no problem with getting the config and other variables that way? Quote Link to comment https://forums.phpfreaks.com/topic/238737-db-connection-in-classes/#findComment-1226888 Share on other sites More sharing options...
ignace Posted June 8, 2011 Share Posted June 8, 2011 return $config = 'Config Var'; is the same as return 'Config Var'; Quote Link to comment https://forums.phpfreaks.com/topic/238737-db-connection-in-classes/#findComment-1227059 Share on other sites More sharing options...
ignace Posted June 8, 2011 Share Posted June 8, 2011 Since you are so keen to keep it all centralized you can either use an Abstract Factory or a Registry. The Abstract Factory going something like this: class ASF_Factory { public static function getConfig() {/*code*/} public static function getDb() {/*code*/} } In your application you would use this like: $confg = ASF_Factory::getConfig(); $database = ASF_Factory::getDb(); This is more specialized then a Registry which is more generalized: $config = ASF_Registry::get('Config'); $database = ASF_Registry::get('Database'); Both inject the dependency and hides the real implementation of your Config object and Database which means that when at some point you want to switch your implementation of either the Config object or the Database object you can replace the lines of code in getConfig() or getDb() with the new object without you having to change any application code or create bugs. However both of course impose a global object and a hard coupling between ASF_Factory or ASF_Registry and the calling class since it doesn't necessarily need the ASF_Factory and ASF_Registry. Quote Link to comment https://forums.phpfreaks.com/topic/238737-db-connection-in-classes/#findComment-1227064 Share on other sites More sharing options...
doddsey_65 Posted June 9, 2011 Author Share Posted June 9, 2011 However both of course impose a global object and a hard coupling between ASF_Factory or ASF_Registry and the calling class since it doesn't necessarily need the ASF_Factory and ASF_Registry. So then how would you do it? how would you get $config['asf_root'] from the config file and inject it into a class? Quote Link to comment https://forums.phpfreaks.com/topic/238737-db-connection-in-classes/#findComment-1227280 Share on other sites More sharing options...
ignace Posted June 9, 2011 Share Posted June 9, 2011 In your case I would go for the Abstract Factory or the Registry these are more flexible then your current designs. Quote Link to comment https://forums.phpfreaks.com/topic/238737-db-connection-in-classes/#findComment-1227350 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.