php pdo - Modèle de connexion à la base de données singleton PHP




1 Answers

L'utilisation de singletons en PHP est considérée comme une mauvaise pratique. D'après mon expérience, le problème le plus problématique avec eux est le test unitaire. Il est difficile de s'assurer que deux tests sont indépendants lors du test des singletons.

Je déléguerais la responsabilité de la contrainte "une seule instance devrait exister" au code comment crée l'objet Db.

Aussi, il me semble que vous ne compreniez pas Singletons en PHP. Si vous avez 10.000 requêtes simultanées, chaque requête s'exécute dans un processus ou un thread séparé, ce qui signifie qu'elles auront toutes leur propre instance du "singleton".

Il n'y a pas de "pooling de connexion" en PHP, mais vous pouvez utiliser les connexions persistantes mysqli . Cela peut être réalisé en passant le p: devant le nom d'hôte lors de la construction mysqli. Cela pourrait aider ici, mais manipulez-le avec soin ( c'est-à-dire lisez d'abord la documentation )

Cependant, juste pour la théorie, un singleton en PHP doit être conscient du fait que quelqu'un pourrait utiliser le clone . Ce qui signifie dans votre cas, il serait possible de faire cela:

$db = DB::getInstance();
$db2 = clone $db; 

Pour éviter cela, implémentez la méthode __clone() comme ceci:

public function __clone() {
    throw new Exception("Can't clone a singleton");
}

Cependant, c'était juste pour la théorie, je vous encourage à refactoriser la classe et à jeter le motif de Singleton.

class

J'ai travaillé sur un petit projet utilisant PHP et MySQL. J'ai beaucoup lu sur les meilleures pratiques en matière de gestion d'une connexion, etc.

J'ai également implémenté (suite à certains articles trouvés) une classe singleton pour gérer les connexions MySQL.

require_once 'config.inc.php';
class DbConn {

    private static $instance;
    private $dbConn;

    private function __construct() {}

    /**
     *
     * @return DbConn
     */
    private static function getInstance(){
        if (self::$instance == null){
            $className = __CLASS__;
            self::$instance = new $className;
        }

        return self::$instance;
    }

    /**
     *
     * @return DbConn
     */
    private static function initConnection(){
        $db = self::getInstance();
        $connConf = getConfigData();
        $db->dbConn = new mysqli($connConf['db_host'], $connConf['db_user'], $connConf['db_pwd'],$connConf['db_name']);
        $db->dbConn->set_charset('utf8');
        return $db;
    }

    /**
     * @return mysqli
     */
    public static function getDbConn() {
        try {
            $db = self::initConnection();
            return $db->dbConn;
        } catch (Exception $ex) {
            echo "I was unable to open a connection to the database. " . $ex->getMessage();
            return null;
        }
    }
}

Mais ... Si mon site Web a 10K visiteurs en même temps et que j'appelle à chaque fois mon objet singleton, devrais-je m'attendre à des problèmes de performance? Je voulais dire, ne devrais-je pas avoir une sorte de pool de connexions au lieu d'un singleton?




Related

php mysql mysqli singleton