1

So I finally started to refactor the base of my PHP office app: I added new functionality to it based on a singleton PDO-class, which I was planning to deploy throughout the whole app. It is very straightforward and working (for now) as it should:

class DB {

    protected static $instance;
    protected function __construct() {}
    public static function getInstance()
    {

        if( empty( self::$instance ) )
        {
            $dsn =  'pgsql:host=' . Config::$a .
                    ';dbname='    . Config::$b .
                    ';port='      . Config::$c .
                    ';connect_timeout=15';            
            $db_user = Config::$d;             
            $db_pass = Config::$e;

            try
            {
                self::$instance = new PDO( $dsn, $db_user, $db_pass );
                self::$instance->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
            }  
            catch( PDOException $e )
            {  
                new Log( 6, "DB Class failed to connect to dbase: $e" );
            }                          
        }
        return self::$instance;
    }
}

This afternoon I'm telling a friend of mine, who is a .NET-programmer about this singleton db-connection class, and he warns me that using a singleton to connect to a database can lead to threading-problems.

I must say that it had crossed my mind: several users will be using the app, and almost all functionality is related to (multiple) db-queries. It is not unthinkable that two users will be executing a query at the same time.

Is PDO (or PHP, or Apache (at the office), or Nginx (testing environment at home)) capable of dealing with this? Maybe a new instance is given for every user? Maybe I should use this singleton together with transactions that will lock the database for every query/update/insert/delete to avoid threading problems? Or maybe my friend is wrong and I don't have to worry?

Thx for any insights!

zenlord
  • 330
  • 3
  • 15
  • in php, the real world purpose of the "singleton pattern" is to provide a lazy loaded global symbol because php doesnt have threads. – goat Jan 27 '13 at 20:16
  • 1
    PHP has threading, http://stackoverflow.com/questions/209774/does-php-have-threading/14548828#14548828 – Joe Watkins Jan 28 '13 at 09:41

2 Answers2

6

Do not worry about using a singleton to establish the connection.

Every php script request will have its own thread. I mean, if two simultaneous requests happen, the web server will execute your singleton in two different threads, so you finally will have two different objects dealing with the database connection.

jap1968
  • 7,747
  • 1
  • 30
  • 37
  • 3
    Which makes the Singleton pattern in PHP rather inane. – stan Jan 27 '13 at 20:15
  • Thank you - this confirms what I was thinking. Maybe I didn't explain this correctly to my friend, or maybe PHP differs from other programming/scripting languages. – zenlord Jan 27 '13 at 22:04
1

Josh Lockhart resume it very fine at http://www.phptherightway.com/pages/Design-Patterns.html

The singleton pattern is useful when we need to make sure we only have a single instance of a class for the entire request lifecycle in a web application. This typically occurs when we have global objects (such as a Configuration class) or a shared resource (such as an event queue).

So, if you request to a script, and this script make more than one access to DB (or call another script that access the DB too), you are in advantage by using Singleton. =) Obvious, it is better to previne more than one access by request (by using stored procedures, for example).