classe pdo

Eléphant du PHP | 107 Messages

20 janv. 2010, 17:55

Bonjour à tous

je voudrais créer une classe d'accès à des sgbd et faisant des traitements standards (ex :CRUD ) à l'aide de PDO

je voudrais une structure comme ça
class BaseDBAccess {
	function Insert($sql);
}

class PostgreSQLDBAccess extends BaseDBAccess {
	function Insert($sql)
	{
		//postgresql specific code
	}
}

class MySQLDBAccess extends BaseDBAccess {
	function Insert($sql)
	{
		//MySQL specific code
	}
}
que j'utilise dans une autre classe comme ça :
class Serializer
{
	$dbAccess = new MySQLDBAccess(.....)

	function SaveSomethingIntoDB($something)
	{
		$dbAccess-> Insert($something)
	}
}
Pour la première classe j'ai trouvé ça :
<?php 
class BaseDBAccess
{

    private $db;

    /**
     *
     * Set variables
     *
     */
    public function __set($name, $value)
    {
        switch($name)
        {
            case 'username':
            $this->username = $value;
            break;

            case 'password':
            $this->password = $value;
            break;

            case 'dsn':
            $this->dsn = $value;
            break;

            default:
            throw new Exception("$name is invalid");
        }
    }

    /**
     *
     * @check variables have default value
     *
     */
    public function __isset($name)
    {
        switch($name)
        {
            case 'username':
            $this->username = null;
            break;

            case 'password':
            $this->password = null;
            break;
        }
    }

        /**
         *
         * @Connect to the database and set the error mode to Exception
         *
         * @Throws PDOException on failure
         *
         */
        public function conn()
        {
            isset($this->username);
            isset($this->password);
            if (!$this->db instanceof PDO)
            {
				try{
	            	$this->db = new PDO($this->dsn, $this->username, $this->password);
    	            $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
				}catch(Exception $e){
    				echo 'Erreur : '.$e->getMessage().'<br />';
    				echo 'N° : '.$e->getCode();
					
				}
				
            }
        }


        /***
         *
         * @select values from table
         *
         * @access public
         *
         * @param string $table The name of the table
         *
         * @param string $fieldname
         *
         * @param string $id
         *
         * @return array on success or throw PDOException on failure
         *
         */
        public function dbSelect($table, $fieldname=null, $id=null)
        {
            $this->conn();
            $sql = "SELECT * FROM `$table` WHERE `$fieldname`=:id";
            $stmt = $this->db->prepare($sql);
            $stmt->bindParam(':id', $id);
            $stmt->execute();
            return $stmt->fetchAll(PDO::FETCH_ASSOC);
        }


        /**
         *
         * @execute a raw query
         *
         * @access public
         *
         * @param string $sql
         *
         * @return array
         *
         */
        public function rawSelect($sql)
        {
            $this->conn();
            return $this->db->query($sql);
        }

        /**
         *
         * @run a raw query
         *
         * @param string The query to run
         *
         */
        public function rawQuery($sql)
        {
            $this->conn();
            $this->db->query($sql);
        }


        /**
         *
         * @Insert a value into a table
         *
         * @acces public
         *
         * @param string $table
         *
         * @param array $values
         *
         * @return int The last Insert Id on success or throw PDOexeption on failure
         *
         */
        public function dbInsert($table, $values)
        {
            $this->conn();
            /*** snarg the field names from the first array member ***/
            $fieldnames = array_keys($values[0]);
            /*** now build the query ***/
            $size = sizeof($fieldnames);
            $i = 1;
            $sql = "INSERT INTO $table";
            /*** set the field names ***/
            $fields = '( ' . implode(' ,', $fieldnames) . ' )';
            /*** set the placeholders ***/
            $bound = '(:' . implode(', :', $fieldnames) . ' )';
            /*** put the query together ***/
            $sql .= $fields.' VALUES '.$bound;

            /*** prepare and execute ***/
            $stmt = $this->db->prepare($sql);
            foreach($values as $vals)
            {
                $stmt->execute($vals);
            }
        }

        /**
         *
         * @Update a value in a table
         *
         * @access public
         *
         * @param string $table
         *
         * @param string $fieldname, The field to be updated
         *
         * @param string $value The new value
         *
         * @param string $pk The primary key
         *
         * @param string $id The id
         *
         * @throws PDOException on failure
         *
         */
        public function dbUpdate($table, $fieldname, $value, $pk, $id)
        {
            $this->conn();
            $sql = "UPDATE `$table` SET `$fieldname`='{$value}' WHERE `$pk` = :id";
            $stmt = $this->db->prepare($sql);
            $stmt->bindParam(':id', $id, PDO::PARAM_STR);
            $stmt->execute();
        }


        /**
         *
         * @Delete a record from a table
         *
         * @access public
         *
         * @param string $table
         *
         * @param string $fieldname
         *
         * @param string $id
         *
         * @throws PDOexception on failure
         *
         */
        public function dbDelete($table, $fieldname, $id)
        {
            $this->conn();
            $sql = "DELETE FROM `$table` WHERE `$fieldname` = :id";
            $stmt = $this->db->prepare($sql);
            $stmt->bindParam(':id', $id, PDO::PARAM_STR);
            $stmt->execute();
        }
    } /*** end of class ***/


?>
Pour les 3 autres classes j'ai tenter de faire comme ça mais je pense que je suis mal parti :
<?php 
class MysqlDBAccess extends BaseDBAccess
{
	public function __construct()
	{
	
	}
	
	public function MysqlConnectDb()
	{
		$MysqlConnect = new BaseDBAccess();
		/*** The DSN ***/
    	$MysqlConnect->dsn = "mysql:dbname=mabase;host=localhost";
    	
    	/*** MySQL username and password ***/
   		$MysqlConnect->username = 'username';
    	$MysqlConnect->password = 'password';	
	}
	
	public function Mysqlinsert()
	{
		$Connect = new BaseDBAccess();
		/*** array of values to insert ***/
    	$values = array(
            array('animal_name'=>'bruce', 'animal_type'=>'dingo'),
            array('animal_name'=>'bruce', 'animal_type'=>'wombat'),
            array('animal_name'=>'bruce', 'animal_type'=>'kiwi'),
            array('animal_name'=>'bruce', 'animal_type'=>'kangaroo')
            );
   		 /*** insert the array of values ***/
   		 $MysqlConnect->dbInsert('animals', $values);
	}
	
	public function exec_nquery($p_query)
	{
                try{   
                        $stmt = $this->dbh->prepare($p_query);
                        $this->dbh->beginTransaction();
                        $stmt->execute();
                        $this->dbh->commit();
                }catch (PDOException $e){
                        echo "__warning\nErreur [DB] => " . $e->getMessage();
                }

        }
	
	
   
}
 /*** end of class ***/


?>
class PostgresqlDBAccess extends BaseDBAccess
{
	public function __construct()
	{
	
	}
	
	public function PgsqlConnectDb()
	{
		$PgSQLConnect = new BaseDBAccess();
		/*** The DSN ***/
    	$PgSQLConnect->dsn = "pgsql:dbname=mabase;host=localhost";
    	
    	/*** MySQL username and password ***/
   		$PgSQLConnect->username = 'username';
    	$PgSQLConnect->password = 'password';	
	}
	
	public function Mysqlinsert()
	{
		$PgSQLConnect = new BaseDBAccess();
		/*** array of values to insert ***/
    	$values = array(
            array('animal_name'=>'bruce', 'animal_type'=>'dingo'),
            array('animal_name'=>'bruce', 'animal_type'=>'wombat'),
            array('animal_name'=>'bruce', 'animal_type'=>'kiwi'),
            array('animal_name'=>'bruce', 'animal_type'=>'kangaroo')
            );
   		 /*** insert the array of values ***/
   		 $PgSQLConnect->dbInsert('evostream', $values);
	}
	
   
}
class Serializer
{
	var $Pgsqlconnet;
	var $urlXML;

	public function OpenPgsqlConnect($_Pgsqlconnet)
	{
		$this->Pgsqlconnet = $_Pgsqlconnet;
		$Postgres = new PostgresqlDBAccess();
		$this->Pgsqlconnet = $Postgres->PgsqlConnectDb();
	} 
	
	public function parseXml($urlXMLtoparse)
	{
		$this->urlXML = $urlXMLtoparse;
		//Charging data of the XML
		$xml = simplexml_load_file($this->urlXML);
		if($xml)
		{
			return $xml;
		}	
		
	}
}
Etant débutant dans le concept POO en général je suis un peu bloqué pour la suite
Si quelqun a des idées ,tuto ou url
je suis preneurs

merci d'avance pour votre aide

Eléphant du PHP | 63 Messages

20 janv. 2010, 19:20

Je te recommande d'utiliser le pattern Strategy.

En revanche d'après ce que je vois c'est que tu t'aventures dans un terrain que tu ne maitrises pas du tout ! Avant de t'attaquer à quelque-chose d'aussi compliqué peut être serait-il plus sage de te renseigner sur les différents design patterns (cf Google). Ensuite, si tu as vraiment besoin d'une telle fonctionnalité dans ton application, il existe de très bonnes bibliothèques te permettant d'arriver au même résultat (Zend Framework pour n'en citer qu'un).

Eléphant du PHP | 453 Messages

22 janv. 2010, 03:20

Hello,

En effet, le strategy serait une bonne solution. Regarde ce diagramme et ce code php. Logiquement, tu devrais comprendre.

diagramme 1, diagramme 2 (trouvé sur le net)
php :
    abstract class ArchiveStrategy{
        abstract function creerLien($nomFichier);
    }
    
    class ZipArchive extends ArchiveStrategy{
        public function creerLien($nomFichier){
            return "http://domain.com/".$nomFichier.".zip";
        }
    }
    
    class TarGzArchive extends ArchiveStrategy{
        public function creerLien($nomFichier){
            return "http://domain.com/".$nomFichier."tar.gz";
        }
    }
    
    if(strstr($_SERVER["HTTP_USER_AGENT"],"Win")){
        $lien = new ZipArchive();
    }else{
        $lien = new TarGzArchive();
    }
    
    $calc = $lien->creerLien("calcule");
    $stats = $lien->creerLien("stats");
    
echo <<<LIEN
$calc <br />$stats
LIEN;
*paye ton polyphormise avec la classe mère abstraite qui va bien. :)
Bonne soirée
La Tux attitude avec les kiw'z syou plait
Komodo Edit - Inkscape - Dia

Eléphant du PHP | 107 Messages

25 janv. 2010, 08:49

onjour
en cherchant sur le net

j'ai finalement pu écrire ma classe

mais comme j'utilise postgresql comme base

je suis face à une nouvelle probleme

voici la classe principale

class BaseDBAccess
{
    var $sDriver='';
    var $sHost='';
    var $sDatabase='';
    var $sUser='';
    var $sPassword='';
    private static $oDatabase;
	var $oPdo=null;
	var $sQuery='';
	var $oPDOStatement=null;
	
 
    /**
     * Constructor for database connection
	 * @param string $sDriver
	 * @param string $sHost
	 * @param string $sDatabase
	 * @param string $sUser
	 * @param string $sPassword
	 */
     private function __construct($sDriver='',$sHost='',$sDatabase='',$sUser='',$sPassword='')
     {
	     	try{
				$this->setDriver($sDriver);
				$this->setHost($sHost);
				$this->setDatabase($sDatabase);
				$this->setUser($sUser);
				$this->setPassword($sPassword);
				$sDrive = $this->sDriver.':dbname='.$this->sDatabase.";host=".$this->sHost;
				$this->oPdo=new PDO($sDrive, $this->sUser, $this->sPassword);
				$this->oPdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
			}catch(PDOException $e){
				echo 'Erreur : '.$e->getMessage().'<br />';
    			echo 'N° : '.$e->getCode();	
			}
			return $this->oPdo;
     }
        
        
	/**
	 * Method for setting all variables
	 * @return unknown_type
	 */
    public function setDriver($sDriver){
			$this->sDriver=$sDriver;
	}
	
	public function setHost($sHost){
			$this->sHost=$sHost;
	}
	
	public function setDatabase($sDatabase){
			$this->sDatabase=$sDatabase;
	}
	
	public function setUser($sUser){
			$this->sUser=$sUser;
	}
	
	public function setPassword($sPassword){
			$this->sPassword=$sPassword;
	}
	
	public function setQuery($sQuery){
			$this->sQuery=$sQuery;
	}
	
	protected function setPdo($oPdo){
			$this->oPdo=$oPdo;
	}  
        
	/**
	 * To get instance of Database
	 *
	 * @param string $sDriver
	 * @param string $sHost
	 * @param string $sDatabase
	 * @param string $sUser
	 * @param string $sPassword
	 * @return Database object
	 */
	public static function getInstance($sDriver='',$sHost='',$sDatabase='',$sUser='',$sPassword=''){
		if(is_null(self::$oDatabase)){
			self::$oDatabase = new BaseDBAccess($sDriver,$sHost,$sDatabase,$sUser,$sPassword);
		}
		return self::$oDatabase;
	}   
        
 
	/**
	 *  Initiates a transaction
	* @return <bool>  */
	public function beginTransaction()
	{
		return $this->oPdo->beginTransaction();
	}
	
	
	
	/* Commits a transaction
	@return <bool> */
	public function commit()
	{
		return $this->oPdo->commit();
	}
	
	/* Commits a transaction
	@return <bool> */
	public function prepared($oPDOStatement)
	{
		$this->oPDOStatement =$oPDOStatement;
		return $this->oPdo->prepare($oPDOStatement);
	}
	
	
	/* Fetch the SQLSTATE associated with the
	last operation on the database handle
	* @return <string> */
	public function errorCode()
	{
		return $this->oPdo->errorCode();
	}
	
	/* Fetch extended error information associated with
	the last operation on the database handle
	@return <array> */
	public function erroInfo()
	{
		return $this->oPdo->errorInfo();
	}
	
	/* Executes an SQL statement, return the number of affected row
	@param <String> $statement
	@return <int> */
	public function exec($statement)
	{
		return $this->oPdo->exec($statement);
	}   
	
	/* Rolls back a transaction
	@return <bool> */
	public function rollBack()
	{
		return $this->oPdo->rollBack();
	}
	
	public function lastInsertId()
	{
		return $this->oPdo->lastInsertId();
	}
	
      
 } /*** end of class ***/
 

et la classe pour postgres
<?php 
require_once ("BaseDBAccess.php");
class PostgresqlDBAccess extends BaseDBAccess
{
	var $PgsqlConnection = '';
	var $seq;
	
	public function __construct()
	{
	   // $this->PgsqlConnectDb();
	}
	
	public function PgsqlConnectDb()
	{
		$this->PgsqlConnection = $PgsqlConnection;
		$this->PgsqlConnection = BaseDBAccess::getInstance('pgsql','localhost','mabase','postgres','admin');
		return $this->PgsqlConnection;	
	}
	
	 /**
      * @Insert a value into a table
      * @acces public
      * @param string $table
      * @param array $values
      * @return int The last Insert Id on success or throw PDOexeption on failure
      */
	public function insert($table,$value)
	{	
	 	$this->PgsqlConnectDb();
	    /*** snarg the field names from the first array member ***/
        $fieldnames = array_keys($value[0]);
           
        /*** now build the query ***/
        $size = sizeof($fieldnames);
        $i = 1;
        $sql = "INSERT INTO $table";
            
        /*** set the field names ***/
        $fields = '( ' . implode(' ,', $fieldnames) . ' )';
        /*** set the placeholders ***/
        $bound = '(:' . implode(', :', $fieldnames) . ' )';
        /*** put the query together ***/
        $sql .= $fields.' VALUES '.$bound;
          
        /*** prepare and execute ***/
        $stmt = $this->PgsqlConnection->prepared($sql);
          
        try
        {
	           		 foreach($value as $vals)
	        		 {
		        		 	$this->PgsqlConnection->beginTransaction(); 
		           		 	$stmt->execute($vals);
		           		 	$this->PgsqlConnection->commit();
		           		 	$lastid = $this->PgsqlConnection->lastInsertId();
		           		 	var_dump($lastid);
	           		 }
        }catch(PDOException $e){
           		 			$this->PgsqlConnection->rollback();
           		 			echo 'Erreur : '.$e->getMessage().'<br />';
   							echo 'N° : '.$e->getCode();
   						
        }
	}
	
   
}
 /*** end of class ***/
 
 
?>

Mon probleme c'est que j'arrive pas à retourné le lastinsertid lors de l'appel de la methode insert

le var_dump me retourne du boolean bool(false) alors que ça doit être l'id du dernier enreg

si vous avez une idée pour le lastinsertid ? je vous remercie pour votre aide

Eléphant du PHP | 453 Messages

25 janv. 2010, 09:18

Hello,

J'ai lu en biais ta réponse. Avec Postgrsql, je crois qu'il faut spécifier au champ id SERIAL :
CREATE TABLE une_table(
id SERIAL PRIMARY KEY,
un_champ VARCHAR(32) NOT NULL
);
Sinon, si tu ne peux toujours pas accéder au dernier enregistrement via lastinsertid, ceci devrait résoudre ton problème :
SELECT MAX(id) FROM une_table;
Bonne journée
La Tux attitude avec les kiw'z syou plait
Komodo Edit - Inkscape - Dia

Eléphant du PHP | 107 Messages

25 janv. 2010, 14:24

j'ai trouver cet fonction dans le document officiel et que j'ai utilisé et qui m'a bien retourné le lastinsertid

public function pgsqlLastInsertId($sqlQuery, $pdoObject)
	{
   		 // Checks if query is an insert and gets table name
   		 if( preg_match("/^INSERT[\t\n ]+INTO[\t\n ]+([a-z0-9\_\-]+)/is", $sqlQuery, $tablename) )
    	 {
        		// Gets this table's last sequence value
        		$query = "SELECT currval('" . $tablename[1] . "_id_seq') AS last_value";

        		$temp_q_id = $this->prepared($query);
        		$temp_q_id->execute();

        		if($temp_q_id)
        		{
            			$temp_result = $temp_q_id->fetch(PDO::FETCH_ASSOC);
            			return ( $temp_result ) ? $temp_result['last_value'] : false;
        		}
    	}

    	return false;
	}
merci :-)