web-dev-qa-db-fra.com

Utilisation du PDO en cours

J'ai quelques classes qui effectuent des requêtes MySQL et des instructions préparées. Cependant, je ne sais plus comment incorporer mon objet PDO dans ces classes. Par exemple, je veux faire quelque chose comme ceci:

<?php

$dbh = new PDO(...);

class Foo extends PDO {
    public $dbh;

    public function bar() {
        $this->dbh->prepare('SELECT * FROM table');
        $this->dbh->execute();

    }
}


?>

Malheureusement, ça ne marche pas. Quelqu'un peut-il suggérer un moyen élégant de le faire? Merci pour votre temps. Désolé, je suis nouveau dans ce domaine, s'il vous plaît laissez des commentaires si vous n'êtes pas clair sur quelque chose et je ferai de mon mieux pour répondre!

26
axsuul

Vous pouvez instancier votre connexion à la base de données dans une classe qui implémente le modèle singleton . La connexion sera établie une fois et cette classe sera facilement accessible par tous vos autres objets/scripts.

j'utilise une classe appelée "Core" dans l'exemple suivant;

class Core
{
    public $dbh; // handle of the db connexion
    private static $instance;

    private function __construct()
    {
        // building data source name from config
        $dsn = 'pgsql:Host=' . Config::read('db.Host') .
               ';dbname='    . Config::read('db.basename') .
               ';port='      . Config::read('db.port') .
               ';connect_timeout=15';
        // getting DB user from config                
        $user = Config::read('db.user');
        // getting DB password from config                
        $password = Config::read('db.password');

        $this->dbh = new PDO($dsn, $user, $password);
    }

    public static function getInstance()
    {
        if (!isset(self::$instance))
        {
            $object = __CLASS__;
            self::$instance = new $object;
        }
        return self::$instance;
    }

    // others global functions
}

cette classe prend les paramètres d'une classe statique appelée "Config" où vous pouvez stocker votre configuration:

<?php
class Config
{
    static $confArray;

    public static function read($name)
    {
        return self::$confArray[$name];
    }

    public static function write($name, $value)
    {
        self::$confArray[$name] = $value;
    }

}

// db
Config::write('db.Host', '127.0.0.1');
Config::write('db.port', '5432');
Config::write('db.basename', 'mydb');
Config::write('db.user', 'myuser');
Config::write('db.password', 'mypassword');

dans tous vos scripts/objets, vous devez simplement obtenir l'instance de Core, puis interroger le DB

$sql = "select login, email from users where id = :id";

try {
    $core = Core::getInstance();
    $stmt = $core->dbh->prepare($sql);
    $stmt->bindParam(':id', $this->id, PDO::PARAM_INT);

    if ($stmt->execute()) {
        $o = $stmt->fetch(PDO::FETCH_OBJ);
        // blablabla....

Si vous avez besoin de plus d'informations sur singleton, consultez le PHP doc http://php.net/manual/fr/language.oop5.patterns.php

61
Guillaume Boschini

Voici un exemple très complet de copier-coller fonctionnant parfaitement de la réponse de Guillaume Boschini ci-dessus.

Une table de base de données remplie (MySQL):

CREATE TABLE `useraddress` (                                                                                                                                        
  `addressid` int(10) unsigned NOT NULL AUTO_INCREMENT,                                                                                                                             
  `userid` int(10) unsigned NOT NULL,                                                                                                                                               
  `addresstitle` char(100) NOT NULL,                                                                                                                        
  `streetaddressa` char(100) NOT NULL,
  `streetaddressb` char(100) DEFAULT NULL,
  `unit` char(50) DEFAULT NULL,
  `city` char(50) NOT NULL,
  `state` char(2) NOT NULL,
  `Zip` int(5) NOT NULL,
  `zipplusfour` int(4) DEFAULT NULL,
  PRIMARY KEY (`addressid`),
  KEY `userid` (`userid`),
  CONSTRAINT `useraddress_fk_1` FOREIGN KEY (`userid`) REFERENCES `user` (`userid`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Dans /DBLibrary/pdocore.php:

<?php

    Config::write('db.Host', 'localhost');
    Config::write('db.port', '3306');
    Config::write('db.basename', 'DBName');
    Config::write('db.user', 'DBUser');
    Config::write('db.password', 'DBPassword');

    class Config {

        static $confArray;

        public static function read($name) {
            return self::$confArray[$name];
        }

        public static function write($name, $value) {
            self::$confArray[$name] = $value;
        }

    }

    class Core {
        public $dbh; // handle of the db connection
        private static $instance;

        private function __construct()  {

            // building data source name from config
            $dsn = 'mysql:Host=' . Config::read('db.Host') . ';dbname=' . Config::read('db.basename') . ';port=' . Config::read('db.port') .';connect_timeout=15';

            // getting DB user from config
            $user = Config::read('db.user');

            // getting DB password from config
            $password = Config::read('db.password');

            $this->dbh = new PDO($dsn, $user, $password);
            $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

        }

        public static function getInstance() {
            if (!isset(self::$instance)) {
                $object = __CLASS__;
                self::$instance = new $object;
            }
            return self::$instance;
        }

        // others global functions
    }
?>

Dans /objectsLibrary/SYS_UserAddress.php:

<?php

    define('k_uaddress_addressid','addressid');
    define('k_uaddress_userid','userid');
    define('k_uaddress_addresstitle','addresstitle');
    define('k_uaddress_addressa','streetaddressa');
    define('k_uaddress_addressb','streetaddressb');
    define('k_uaddress_unit','unit');
    define('k_uaddress_city','city');
    define('k_uaddress_state','state');
    define('k_uaddress_Zip','Zip');
    define('k_uaddress_zipplusfour','zipplusfour');

    require_once '../DBLibrary/pdocore.php';

    class SYS_UserAddress {

        public $addressid;
        public $userid;
        public $addresstitle;
        public $addressa;
        public $addressb;
        public $unit;
        public $city;
        public $state;
        public $Zip;
        public $zipplusfour;

        public function SYS_UserAddressByAddressId($_addressid) {

            $returnValue=FALSE;

            $query='select * from useraddress where ' . k_uaddress_addressid . '=:addressid';

            try {
                $pdoCore = Core::getInstance();
                $pdoObject = $pdoCore->dbh->prepare($query);

                $queryArray = array(':addressid'=>$_addressid);

                if ($pdoObject->execute($queryArray)) {

                    $pdoObject->setFetchMode(PDO::FETCH_ASSOC);;

                    while ($addressrow = $pdoObject->fetch()) {

                        $this->addressid=$addressrow[k_uaddress_addressid];
                        $this->userid=$addressrow[k_uaddress_userid];
                        $this->addresstitle=$addressrow[k_uaddress_addresstitle];
                        $this->addressa=$addressrow[k_uaddress_addressa];
                        $this->addressb=$addressrow[k_uaddress_addressb];
                        $this->unit=$addressrow[k_uaddress_unit];
                        $this->city=$addressrow[k_uaddress_city];
                        $this->Zip=$addressrow[k_uaddress_Zip];
                        $this->zipplusfour=$addressrow[k_uaddress_zipplusfour];

                    }
                    $returnValue=TRUE;
                }
            }
            catch(PDOException $pe) {
                trigger_error('Could not connect to MySQL database. ' . $pe->getMessage() , E_USER_ERROR);
            }

            return $returnValue;

        }
    }

    $test=1;
    $testAddressId=2;

    if($test>0) {

        $testAddress = new SYS_UserAddress();

        $testAddress->SYS_UserAddressByAddressId($testAddressId);

        echo '<pre>';
        echo print_r($testAddress);
        echo '</pre>';

    }

?>

Le post ci-dessus m'a vraiment aidé. Ce post que je fais maintenant m'aurait amené là où je voulais être plus rapide. C'est tout. Si quelque chose ne va pas, je serai là pour le réparer.

6
BradChesney79

$dbh n'est pas dans la portée de Foo, faites ceci à la place:

class Foo /*extends PDO*/
{
    public $dbh;

    public function __construct()
    {
        $dbh = new PDO(/*...*/);
    }

    public function bar()
    {
        $this->dbh->prepare('SELECT * FROM table');
        return $this->dbh->execute();
    }
}

De plus, Foo n'a pas besoin d'étendre PDO.

3
Alix Axel

j'ai trouvé une meilleure solution: lorsque vous avez une connexion PDO en dehors de votre classe et que vous ne pouvez pas utiliser cette connexion dans la classe, envoyez cet objet PDO au constructeur en tant que paramètre 

/// c'est ma connexion pdo

$pdo_object = new PDO('mysql:Host=localhost;dbname=blabla','user','pw');

/// im créant l'instance de cette classe en tant qu'obj 

$dataObj=new class_name($pdo_obj);

///// dans la classe ::: simplifié

class class_name{

private $handler;//// this is what i use for PDO connection inside the class

public function __construct($connection_name){

    if(!empty($connection_name)){
        $this->handler=$connection_name;
  ///its a great thing that holy php doesnt care much about variant types. any variant is able to carry any object (like PDO obj)
    }else{
        throw new Exception("cant connect bla bla...");
    }



}/////contruct fx

////how i use that pdo connection which is implamented to a local var called handler  with any sql query is : 

$dataSet= $this->handler->query("SELECT * FROM users WHERE ....");



}////endof class
0
ulas korpe