yonta Posted October 11, 2006 Share Posted October 11, 2006 Right now i'm following the mvc pattern in an app i'm building, so i basically have templates, controllers and models. There's one model per mysql table, so if i have a products table i'll have a products_model with all the basic CRUD functionality. A controller can use one or several models. For example, each product can have several documents and so there's a product_docs table and its corresponding model. This means that the product_controller can use the products_model and the product_docs_model.All models extend (inherit from) a common database manager class and it's this common class that's responsible for actually connecting to the database (it has a connect method).Now for my problem: if in a single call to the server more than one model is used, there will be more than one instance of the database manager class created, and so more than one attempt to connect to the database (it's a persistent connection, btw) and there seems to be no need for it. In a single call to the server i only need to connect once to the database. I mean, performance wise it just seems stupid. And so i thought i could use the singleton pattern to ensure that only one attempt to connect to the database was done.something like this:[code]class products_Model extends DbManager{ var $select_titles; var $tablename; var $security; function products_Model() { $this->tablename = 'products'; $this->select_titles = 'SELECT prod_id, prod_title, prod_text, prod_ispub FROM '.$this->tablename; if(!singleton::getInstance('DbManager')) //if there's no dbmanager in singleton array, attempt to connect parent::connect(); //without the singleton pattern it was just like below //parent::connect(); $this->security = new Security(); }[/code]But searching around i found this:"The singleton pattern applies to the situation where you need a single, global instance of a class. It fits situations where a factory object returns uniform objects, such as file handles or user sessions. These aren't good candidates for being implemented in a PHP script because the [b]language provides built-in solutions such as persistent database connections[/b]." ( http://www.zend.com/zend/trick/tricks-app-patt-php.php )which of course got me thinking. Am i thinking about this the totally wrong way? Maybe i should do it another way? Or is it actually ok? Or there's no need to worry about making several calls to pconnect since it's a persistent connection anyway? Or should i use delegation ($db = new DbManager(); ) instead of inheritance (.. extends DbManager ) ?Any input would be a great great help. Quote Link to comment https://forums.phpfreaks.com/topic/23622-singleton-to-avoid-multiple-calls-to-pconnect/ Share on other sites More sharing options...
yonta Posted October 11, 2006 Author Share Posted October 11, 2006 Ok, maybe my post was a bit confusing.If you follow the mvc pattern in your apps, do you have a common database manager for all your models (in my case, it's a wrapper for adodb - http://adodb.sourceforge.net/ ) or not? If not, why not?If you do have a common db manager, how do you avoid multiple attemps to connect to the database when you use more than one model in a controller? Do you simply detect if there's a connection already established or not?I'm thinking i could use something like this:[code]$this->DB = &ADONewConnection('mysql'); if(!$this->DB->IsConnected( )) { $this->DB->PConnect(DB_SERVER,DB_USERNAME,DB_PASSWORD,DB_DATABASE) or trigger_error("Não é possível ligar à base de dados. Contacte o administrador.", E_USER_ERROR); }[/code]Do you do something like this as well?..I'm still a bit new to the oop scene so if anyone could tell me how they do it, it would help.Thanks Quote Link to comment https://forums.phpfreaks.com/topic/23622-singleton-to-avoid-multiple-calls-to-pconnect/#findComment-107323 Share on other sites More sharing options...
Jenk Posted October 11, 2006 Share Posted October 11, 2006 Depends on your application's purpose. For example.. if it's a database management application, you may very well want multiple connections available. Also take note when using pconnect - the function first checks if there is a connection already open that uses the same criteria (host, username, password)If there is it will automagically use the existing connection instead of creating a new one. So the singleton part is taken care of for you..[code]<?php$link = mysql_pconnect(/* etc */);$link2 = mysql_pconnect(/* same details as above */);// $link2 is now a reference to $link?>[/code]Also rather than using a singleton, at worst I'll use a registry - however I much prefer (as do a lot of OOD/P folk) to just pass the Db object as a parameter.[code]<?phpclass SomeClass{ private $_db; public function __construct($db) { $this->_db = $db; } // or use a setter: public function setDb($db) { $this->_db = $db; }}// the above is prefered over the following:class SomeClass2{ private $_db; public function __construct() { $this->_db = DbClass::getInstance(); }}?>[/code]OOD/P is all about encapsulation and controlled points on input/output. Using a Singleton (as above) is 'breaking' that rule of encapsulation. Quote Link to comment https://forums.phpfreaks.com/topic/23622-singleton-to-avoid-multiple-calls-to-pconnect/#findComment-107333 Share on other sites More sharing options...
yonta Posted October 11, 2006 Author Share Posted October 11, 2006 So are you saying that instead of extending the dbmanager in all my models, to avoid the repetition i could in a controller do $db = new DbManager();$products = new ProductsModel($db); - basically just pass the dbmanager around, and since i only use one controller in a single call to the server there would be uneeded multiple instantiation. It does seem cleaner :) thank you, thank youSo pconnect checks if there's already a connection available. I use persistent connections because i read that it's faster but that you also increase the risk of having too many connections open. How is that if pconnect checks if there's already a connection available?'if it's a database management application, you may very well want multiple connections available' - it is, but i really don't get why i would want multiple connections to the database. If multiple users are asking to see the same or different pages, shouldn't the server use the same connection to mysql? Could you explain this a bit more please?thanks :) Quote Link to comment https://forums.phpfreaks.com/topic/23622-singleton-to-avoid-multiple-calls-to-pconnect/#findComment-107344 Share on other sites More sharing options...
Jenk Posted October 11, 2006 Share Posted October 11, 2006 With non-persistent connections, the connection is terminated as soon as the script ends. A persistent connections stays open until explicitly told to close (or when the persistent connection timeout expires)Persistent connections are 'assigned' to the webserver executable, so multiple users will use the same connection.You only need worry about creating multiple connections if you are connecting to two or more database servers concurrently, otherwise you should continue to use the same connection. Quote Link to comment https://forums.phpfreaks.com/topic/23622-singleton-to-avoid-multiple-calls-to-pconnect/#findComment-107373 Share on other sites More sharing options...
yonta Posted October 11, 2006 Author Share Posted October 11, 2006 Thanks for your help JenkI undestand it better now :) Quote Link to comment https://forums.phpfreaks.com/topic/23622-singleton-to-avoid-multiple-calls-to-pconnect/#findComment-107378 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.