Creating a PDO abstract parent class
Continuing on Peter Kiss's answer, the static keyword is indeed hard to test, but you don't have to worry about it when it's in a dependency container. If you use Inversion of Control and have your objects ask for a DB connection, rather than getting one, you don't have to worry about using singletons or static class properties – you just let the dependency layer manage connections, and this can be done with a simple static variable inside a closure (see below). 

This answer is verbose, because I'm going to assume ignorance and try to explain Dependency Injection in as simple terms as possible (I still haven't found a concise explanation of DI). Afterwards, I'll explain how you can use DI to ensure no more than one DB connection is created.

You need to create a very generic container object to contain dependencies. At runtime, you insert these dependencies into this container (typically before you do anything else). Then, you pass this container to the constructor of any object with a dependency. The object then retrieves the dependency it needs from the container. 

This allows the dependent object to be completely ignorant of how the dependency was constructed: e.g. a database object could have been constructed from PDO rather than MySQLi (though you'd want them to share the same API). This aids in making your code much easier to test by keeping object graph construction and application logic separate.

If you're using PHP 5.3+, I'd recommend looking into PIMPLE. Here's how you'd set things up.

// Construct the container and all dependencies
// This is usually done in a separate file

$container = new Pimple();
$container['db'] = function() {
    $db = ...; // Construct the DB connection
    return $db;
}

// Define a class that depends on the DB
class SomeObjectThatUsesDB {
    function __construct($container) {
        $this-&gt;container = $container;

        // No `new` keyword – this is a good thing!
    }

    function doSomething() {
        $db = $this-&gt;container['db'];
        // Do something with the DB
    }
}

// Use the class to do some work with the DB
$obj = new SomeObjectThatUsesDB($container);
$obj-&gt;doSomething();


The advantage here is $container['db'] can be anything as long as it shares the same API.

OK, so now let's talk about ensuring only one DB connection exists at any given time. Since the DI dependencies are just anonymous functions, you can just use the static keyword inside of the dependency definition; however, Pimple makes this even easier by providing a share() method that does this for you. As per the documentation:


  By default, each time you get an object, Pimple returns a new instance
  of it. If you want the same instance to be returned for all calls,
  wrap your anonymous function with the share() method


Here's what it looks like:

$container['db'] = $container-&gt;share(function($container) {
    $db = ...; // Construct the DB connection
    return $db;
});


This will make sure that sure only one $db is ever created. Here's the source code from Pimple's share() method for demonstration purposes:

/**
 * Returns a closure that stores the result of the given closure for
 * uniqueness in the scope of this instance of Pimple.
 *
 * @param Closure $callable A closure to wrap for uniqueness
 *
 * @return Closure The wrapped closure
 */
public static function share(Closure $callable)
{
    return function ($c) use ($callable) {
        static $object;

        if (null === $object) {
            $object = $callable($c);
        }

        return $object;
    };
}