3

I know singletons are bad. But is it bad for this, too?

class DaoMySQL {

    private static $instance;
    private $PDO;

    private function __construct() {
        $this->PDO = new PDO('mysql:dbname='.MYSQL_DEFAULT_DATABASE.';host='.MYSQL_HOSTNAME, MYSQL_USERNAME, MYSQL_PASSWORD);
        $this->PDO->query('SET NAMES \'utf8\'');
    }

    /**
     * @return DaoMySQL
     */
    static public function singleton() {
        if (!isset(self::$instance)) {
            $c = __CLASS__;
            self::$instance = new $c();
        }
        return self::$instance;
    }

    /**
     * @return PDO
     */
    public function getPDO() {
        return $this->PDO;
    }

}

To use this, I do something like this. (This is from my Bean class which all data objects extends.)

public function delete() {
    $calledClassName = get_called_class();
    $query = "DELETE FROM `" . $calledClassName::table . "` WHERE `id` = $this->id";
    return DaoMySQL::singleton()->getPDO()->exec($query);
}

2 Answers2

2

The thing (well, one of them) that's wrong with Singletons is that the application should really be responsible for determining an object's life-cycle.

Have a read of Steve Yegge's article Singleton Considered Stupid

ocodo
  • 29,401
  • 18
  • 105
  • 117
  • But I've often had the same problem. You want to put the application in control, but the database is used by code everywhere.. Especially that seams to happen to me in php. – Thomas Ahle Feb 18 '11 at 00:31
  • The code everywhere still has to use the singleton incantation, why not just reference it as a property of the app? – ocodo Feb 18 '11 at 00:32
2

Many people are starting to use Dependency Injection containers to manage their objects instead of using singletons. Perhaps it's worth a look? Then all you need to ensure is that objects can access the container. You can fetch everything else from there.

Personally I use sfServiceContainer from Symfony Components. It's a stand-alone DI container and seems quite popular these days.

Update

You don't need to use a framework or a library. Fabien Potencier's articles on dependency injection should give you a good enough grasp of DI to implement your own. But why reinvent the wheel? Not using a good, existing library smells of NIH.

Note that there are many other DI libraries besides the sfServiceContainer that I use. Also note that sfServiceContainer is a completely stand-alone library. It does not need Symfony or any other framework. All it requires is plain old PHP.

Sander Marechal
  • 22,978
  • 13
  • 65
  • 96
  • Could you explain to me why I need (or should use) a framework or library for this? –  Feb 18 '11 at 02:54
  • I second the DI container approach with the additional note that Singletons make the code lest testable in case you ever wanted to implement unit testing. – Luke Cordingley Jul 19 '13 at 00:53