begin process at 2012 05 27 17:57:46
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Class et Objet ( POO )

 > [PHP5.2] CLASSE PDO

[PHP5.2] CLASSE PDO


 Information sur la source

Note :
Aucune note
Catégorie :Class et Objet ( POO ) Classé sous :php5, classe, POO, PDO, MYSQL Niveau :Débutant Date de création :01/03/2010 Vu / téléchargé :5 560 / 350

Auteur : hornetbzz

Ecrire un message privé
Commentaire sur cette source (1)
Ajouter un commentaire et/ou une note

 Description

Ci-joints les fichiers et ce qu'ils font :

- PDO2.classe.php: Création d'un singleton par extension de la classe PDO (reprise existant),
- PDO3.classe.php: Lister les tables de la base de données par ordre de taille,
- PDO3.classe.php: Lister les champs d'une table soit en mode résumé, soit détaillé
- PDO3.classe.php: Insérer facilement un tableau de données dans la table souhaitée
- test_pdo.php   : Montrer comment la classe et ses méthodes s'utilisent.
- fonctions_classe.php: c'est simplement la fonction d'autoload des classes à leur instanciation (SPL)

Les méthodes utilisées requièrent pour la plupart au minimum PHP5.1, donc vous pouvez essayer avec cette version, mais j'ai tout testé avec PHP5.2.9.

Bon, c'est ma première classe POO en PHP5, donc ce n'est pas aussi transcendant que quelques autres que j'ai vues sur ce site, mais elle fonctionne bien et me parait simple à améliorer et très pratique d'utilisation.

Source

  • // Je ne place QUE la classe PDO3 pour un accès direct, mais il faut télécharger les autres.
  • <?php
  • /**
  • * Extension de la Classe PDO2
  • * @author : hornetbzz pour CAMACASA(TM)
  • * @creation : 28/02/2010
  • * @licence : non assessed
  • * @doc : http://julien-pauli.developpez.com/tutoriels/php/pdo/?page=exemple
  • * @doc : http://forum.alsacreations.com/topic-20-41053-1-ResoluPHP-BD-Quand-se-connecter-a-la-BD-.html
  • * @todo : gestion des exceptions, recherche des index, resetAI uniquement lors de suppressions de blocs sur tables indépendantes
  • */
  • class PDO3 extends PDO2 {
  • /* Variables de la classe */
  • protected $_pdo = NULL; // ne doit pas être "private" car héritage de PDO2
  • private $_delimiter = ', '; // ne pas modifier !
  • private $_debug = false; // MODIF si vous voulez
  • /* Constructeur : héritage public obligatoire par héritage de PDO */
  • public function __construct($pdo)
  • {
  • if (isset($pdo) ) {
  • $this->_pdo = $pdo;
  • $this->checkPdoExtension();
  • }
  • else {
  • throw new PDOException("No pdo connection");
  • }
  • }
  • /* Destructeur */
  • public function __destruct() // nota: ne surtout pas mettre de parametre
  • {
  • $this->close();
  • }
  • /** 28/02/2010
  • * ferme la connexion à la dB (portage dans la classe PDO de la fonction mysql_close)
  • */
  • public function close()
  • {
  • $this->_pdo = NULL;
  • }
  • /* Methode magique */
  • public function __toString($object)
  • {
  • $string = (string) $object ;
  • return $string;
  • }
  • /**
  • * Retourne la liste résumée des tables de la base
  • * @doc : http://cedric-duprez.developpez.com/tutoriels/mysql/catalogue/#LV
  • * @return : (array) $data_array
  • */
  • public function getFieldsSummary($limit = false)
  • {
  • $data_array = array();
  • $limit = ($limit == false)? '' : 'LIMIT '. (int) $limit;
  • // Les tables, dans l'ordre = f(taille)
  • $sql = "SELECT TABLE_NAME, ROUND((DATA_LENGTH + INDEX_LENGTH) / (1024 * 1024), 2) AS SIZE_MO, TABLE_ROWS, AUTO_INCREMENT
  • FROM INFORMATION_SCHEMA.TABLES
  • WHERE TABLE_SCHEMA = '". $this->_dbname . "'
  • ORDER BY DATA_LENGTH + INDEX_LENGTH DESC ". $limit;
  • $result = $this->_pdo->query($sql);
  • $rows = $result->fetchAll(PDO::FETCH_ASSOC);
  • foreach($rows as $key => $value) {
  • $data_array[$key] = $value;
  • }
  • return $data_array;
  • }
  • /**
  • * Retourne la liste détaillée des tables de la base
  • * @doc : http://cedric-duprez.developpez.com/tutoriels/mysql/catalogue/#LV
  • * @return : (array) $data_array
  • */
  • public function getFieldsDetails($limit = false)
  • {
  • $data_array = array();
  • $limit = ($limit == false)? false : (int) $limit;
  • // Summary: reprise de ces infos comme base de recherche des détails
  • $source_array = $this->getFieldsSummary($limit);
  • // Details
  • foreach( $source_array as $key => $field_datas) {
  • if (is_array($field_datas)) {
  • // Transfert du Summary dans le tableau de détails
  • $data_array[$key] = $field_datas;
  • // Details de chaque table
  • $table_encours = $field_datas['TABLE_NAME'];
  • $sql = "SELECT COLUMN_NAME, COLUMN_TYPE, COLUMN_KEY, EXTRA
  • FROM INFORMATION_SCHEMA.COLUMNS
  • WHERE TABLE_SCHEMA = '". $this->_dbname . "'
  • AND TABLE_NAME = '" . $table_encours . "'";
  • $result = $this->_pdo->query($sql);
  • $rows = $result->fetchAll(PDO::FETCH_ASSOC);
  • // Field List
  • $field_list= '';
  • $memo_auto_inc = '' ;
  • $count = count($rows);
  • foreach($rows as $k => $value) {
  • $memo_auto_inc = ($value['EXTRA'] == 'auto_increment')? $value['COLUMN_NAME'] : $memo_auto_inc ;
  • $field_list .= '<b>'. $value['COLUMN_NAME'] . '</b> (' . $value['COLUMN_TYPE'] . ') ' . ' (' . $value['COLUMN_KEY'] . ')'. $this->_delimiter;
  • }
  • // Marqueur éventuel sur l'AI
  • $data_array[$key]['AI_RESET_NEED'] = ($data_array[$key]['AUTO_INCREMENT'] > $count) ? 'true' : 'false' ;
  • $data_array[$key]['AI_FIELD'] = $memo_auto_inc ;
  • // Array Push
  • $data_array[$key]['FIELDS_COUNT'] = $count;
  • $data_array[$key]['FIELDS_LIST'] = $field_list;
  • }
  • }
  • return $data_array;
  • }
  • /** 28/02/2010 portage dans la classe PDO de la fonction db_pdo.php
  • * retourne la liste des champs d'une table sous forme de vecteur colonne
  • * @param : (string) $table_name nom de la table dont on veut la liste des champs
  • * @return : (array) $fieldNames liste des noms de champs de $table_name
  • */
  • public function getFieldsName($table_name)
  • {
  • // Field Details: reprise de ces infos comme base de recherche des détails
  • $source_array = $this->getFieldsDetails(false);
  • // 1ere méthode: lourde et peu élégante
  • /*
  • $fieldNames = array() ;
  • foreach ($source_array as $key => $table_datas) {
  • if (is_array($table_datas)) {
  • if ($table_datas['TABLE_NAME'] == $table_name) {
  • $fieldNames = explode( $this->_delimiter , $table_datas['FIELDS_LIST'] ) ;
  • }
  • }
  • }
  • array_pop($fieldNames) ;
  • */
  • // 2eme méthode: plus directe et élégante : recupération récursive de la clé correspondante à la table
  • $key = $this->recursiveArraySearch($table_name , $source_array ) ;
  • $fieldNames = explode( $this->_delimiter , $source_array[$key]['FIELDS_LIST'] ) ;
  • array_pop($fieldNames);
  • // 3eme methode: brut accès direct aux infos dB sans utiliser d'autres fonctions
  • /*
  • $recordset = $this->_pdo->query("SHOW COLUMNS FROM $table_name");
  • $fields = $recordset->fetchAll(PDO::FETCH_ASSOC);
  • foreach ($fields as $field) {
  • $fieldNames[] = $field['Field'];
  • }
  • */
  • return $fieldNames;
  • }
  • /**
  • * Ré initialise l'auto-increment d'une table à une valeur initiale donnée
  • * ######## A EVITER : la plupart des tables sont liées par les id AI ... ########
  • * @doc :// http://sqlpro.developpez.com/cours/clefs/#L3.2
  • * @return : true
  • */
  • public function resetAI($table_name, $init_AI = 200)
  • {
  • // 1) Vérifier que cette table n'est pas liée à d'autres par ses ID et à appliquer uniquement après suppression de blocs de datas...
  • // 2) Combien de datas dans la table
  • // 3) Quelle valeur de AI initial
  • // 4) Quelle valeur de AI courante
  • // 5) Justification de remettre AI à flot
  • // 6) Reset des AI existants
  • // 7) Mise à jour de l'AI de cette table
  • }
  • /** 28/02/2010 portage dans la classe PDO de la fonction incluse dans db_pdo.php
  • * sauve des datas (variables ou array) INSERT ou UPDATE dans la table $table de la dB
  • * @NOTA : fonction dépréciée au profit de la fonction saveData
  • * @param : $table_name, $data_array
  • * @return : true si tout s'est bien passé, false sinon
  • * @doc : http://fr.php.net/manual/fr/function.mysql-query.php#84962
  • */
  • public function addData($table_name, $excluded_fields = '', $data_array, $sql_type = 'insert', $sql_condition = NULL )
  • {
  • // Init
  • $fields = '';
  • $values = '';
  • $debug = $this->_debug ;
  • $pattern = '/tel|phone|fax|siret|number|numero/';
  • // format input fields into sql (explode du tableau associatif en requete SQL)
  • foreach ($data_array as $field => $value) {
  • if (!strstr($excluded_fields, $field)) {
  • // construction de la sql pour INSERT
  • if (strtolower($sql_type) == 'insert') {
  • $fields .= "$field, ";
  • $values .= "'$value', ";
  • }
  • // construction de la sql pour UPDATE
  • else {
  • if (!is_numeric($value)) {
  • $fields .= "$field = '$value', "; // string
  • }
  • else {
  • // exceptions: pour le num de tel/fax/siret qui peut commencer par un zero et peut ainsi être assimilé à un numeric, ce qui n'est pas le cas ds la dB
  • if ( !preg_match( $pattern, $field ) ) {
  • $fields .= "$field = $value, "; // numeric
  • }
  • else {
  • $fields .= "$field = '$value', ";// si tel/phone/fax/siret => string
  • }
  • }
  • }
  • }
  • }
  • // remove trailing ", " from $fields and $values
  • $fields = preg_replace('/, $/', '', $fields);
  • $values = preg_replace('/, $/', '', $values);
  • // create sql statement
  • if (strtolower($sql_type) == 'insert') {
  • $sql = "INSERT INTO $table_name ($fields) VALUES ($values)";
  • }
  • elseif (strtolower($sql_type) == 'update') {
  • if (!isset($sql_condition)) {
  • echo 'ERROR: You must enter a sql condition!';
  • exit;
  • }
  • $sql = "UPDATE $table_name SET $fields WHERE $sql_condition";
  • }
  • else {
  • echo 'ERROR: Invalid input for argument $sql_type: must be "insert" or "update"';
  • exit;
  • }
  • // prepare & execute sql
  • $query = $this->_pdo->prepare($sql) ;
  • $result = $query->execute() ;
  • //$result->closeCursor(); // not always necessary: depends on SQL driver needs
  • if ( $result ) {
  • return true;
  • }
  • else if ( $result === false ){
  • if ($debug) {
  • return 'err sql: ' ; //. mysql_error();
  • }
  • else {
  • return false;
  • }
  • }
  • } /* fin addData */
  • /** 01/03/2010
  • * sauve $data_array dans $table (la condition d'UPDATE devenant optionnelle si elle ne porte que sur l'id PK)
  • * @param : $table_name destination, $data_array à sauver, $sql_type='insert' ou 'update', $optional_condition
  • * @doc : http://www.php.net/manual/fr/pdostatement.execute.php#80499
  • * @return : true si tout s'est bien passé, false sinon
  • */
  • public function saveData($table_name, $data_array, $sql_type='insert', $optional_condition=NULL )
  • {
  • // Init
  • $debug = $this->_debug;
  • $sql ='';
  • $pattern_field = '/^(?:\<b\>)(\w+)(?:\<\/b\>)(?:\s{0,})\((.+)\)(?:\s{0,})\((.+)?\)$/';
  • $field_name = $field_format = $field_key = array() ;
  • // Initial checks
  • // Data_array in line with table fields
  • // db fields
  • $db_fields = $this->getFieldsName($table_name) ;
  • if ( empty($db_fields) ) return false ;
  • foreach ( $db_fields as $field) {
  • unset($matches);
  • if ( preg_match($pattern_field, $field, $matches) ) {
  • $field_name[] = trim($matches[1]);
  • $field_format[] = trim($matches[2]);
  • $field_key[] = trim($matches[3]);
  • }
  • }
  • /*
  • if ($debug) {
  • $this->arr_dump(array('keys'=>$field_key, 'names'=>$field_name, 'formats'=>$field_format) , 'Matching results');
  • }
  • */
  • // Comparison $db_fields with $data_array: can accept missing fields but no mismatching fields (thus avoiding typos in $data_array)
  • $mismatching_fields = array_diff(array_keys($data_array), $field_name);
  • if ( count($mismatching_fields) != 0) {
  • if ($debug) {
  • echo '<br/>PDO3 db Vs data fields issue';
  • $this->arr_dump($mismatching_fields, 'mismatch' );
  • }
  • return false;
  • }
  • // Check data_array format Vs dB_fields format
  • // #########
  • // # To do
  • // #########
  • // Build SQL statement
  • // INSERT $sql = "INSERT INTO $table_name ($fields) VALUES ($values)";
  • $fields = '';
  • $values = '';
  • if ( strtolower($sql_type) == 'insert') {
  • foreach($data_array as $field => $data) {
  • $fields .= "$field, ";
  • $values .= "'$data', ";
  • }
  • $fields = preg_replace('/, $/', '', $fields);
  • $values = preg_replace('/, $/', '', $values);
  • $sql = "INSERT INTO $table_name ($fields) VALUES ($values)";
  • if ($debug) echo '<br/>sql statement: ' . $sql;
  • }
  • // UPDATE
  • if ( strtolower($sql_type) == 'update') {
  • //if ($debug) echo '<br/>Starting update....' ;
  • // Update Condition $sql_condition
  • $sql_condition = '';
  • // dB primary key field required
  • $needle = 'PRI';
  • $pk_key = trim($this->recursiveArraySearch($needle, $field_key) ) ;
  • if (false === $pk_key ) { // NOTA: '===' is a must as $pk_key canb be 0 and then understood as 'false'
  • if ($debug) {
  • echo '<br/>PDO3 Err: no primary key found' ;
  • $this->arr_dump( array('pk key'=> $pk_key , 'needle'=>$needle, 'fields' => $field_key), 'Check needle & arrays') ;
  • }
  • return false;
  • }
  • else {
  • if ($debug) {
  • echo '<br/>found primary key in db datas array <b>keys</b> :' . $pk_key;
  • // $this->arr_dump( $field_key , 'field_key');
  • }
  • }
  • // data_array field content check
  • $pk_value = (array_key_exists($field_name[$pk_key], $data_array))? $data_array[$field_name[$pk_key]] : false ;
  • if (false === $pk_value || empty($pk_value) ) {
  • if ($debug) $this->arr_dump( array('key'=>$pk_key, 'value'=>$pk_value, 'data'=>$data_array) , 'PDO3 Err: no data content for primary key sql condition');
  • return false ;
  • }
  • else if ($debug) echo '<br/>found primary key value in db datas array <b>values</b>:' . $pk_value;
  • // db_field: check if table field of row(pk) exists (in order to being able to properly set the sql_condition)
  • // #########
  • // # to do
  • // #########
  • // Sql condition base
  • $sql_condition = $field_name[$pk_key] . '=' . $pk_value;
  • if ($debug) echo '<br/>sql update condition base: ' . $sql_condition ;
  • // Sql condition options
  • // #########
  • // # to do: check if necessary (prepared request) that the optional sql condition is not matching with forbidden conditions like 1=1 or DELETE..
  • // #########
  • $sql_condition .= ($optional_condition)? ' AND ' . $optional_condition : '' ;
  • // Build sql statement (not necessary to remove PK field from fields to update)
  • $fields = '';
  • foreach($data_array as $field => $data) {
  • $fields .= "$field = '$data', ";
  • }
  • // remove trailing ','
  • $fields = preg_replace('/, $/', '', $fields);
  • // Sql statement
  • $sql = "UPDATE $table_name SET $fields WHERE $sql_condition";
  • if ($debug) echo '<br/>sql statement: ' . $sql;
  • }
  • // Prepare & Execute Sql statement (sothat there is no need to use "quote" method for data protection against SQL injection)
  • if ($sql) {
  • $query = $this->_pdo->prepare($sql) ;
  • $result = $query->execute() ;
  • $count = $query->rowCount(); // Check affected rows by INSERT or UPDATE (nota : this methode does not work for SELECT)
  • }
  • // Return Value
  • if ($result && $count > 0) {
  • return true;
  • }
  • else{
  • return false;
  • }
  • } /* fin saveData */
  • /**
  • * Recherche récursive de la clé de niveau 0 d'une valeur située dans un tableau multidimensionnel de profondeur D
  • * @source : http://fr.php.net/manual/fr/function.array-search.php#91365
  • * @return : $key($needle)
  • */
  • private function recursiveArraySearch($needle, $haystack) {
  • foreach($haystack as $key=>$value) {
  • $current_key=$key;
  • if($needle===$value OR (is_array($value) && $this->recursiveArraySearch($needle, $value) !== false)) {
  • return $current_key;
  • }
  • }
  • return false;
  • }
  • /** 01/02/2010
  • * Vérifie que l'extension pdo est bien chargée et est bien en phase avec le type des requetes émises dans la classe PDO2
  • * @source : http://php.developpez.com/faq/?page=pdo#pdo-loaded-drivers
  • * @return : true ou false
  • */
  • // ######### à ré-implémenter en amont dans PDO2 avec gestion erreur ################
  • private function checkPdoExtension() {
  • if ($this->_debug) echo '<br/>Checking for PDO extension loaded';
  • $pdo_ext = false;
  • foreach(get_loaded_extensions() as $extension) {
  • if(strpos(strtolower($extension), 'pdo') !== 'pdo') {
  • $pdo_ext = true;
  • }
  • }
  • if ($this->_debug && false == $pdo_ext) echo '<br/>PDO extension not loaded';
  • return $pdo_ext;
  • }
  • /**
  • * fonction de debugage
  • */
  • private function arr_dump($array, $text='') {
  • echo '<br/>Dump('.$text.')<pre>'; print_r($array); echo '</pre>' ;
  • }
  • } /* fin de la Classe */
  • ?>
// Je ne place QUE la classe PDO3 pour un accès direct, mais il faut télécharger les autres.

<?php

/**
 * Extension de la Classe PDO2
 * @author		: hornetbzz pour CAMACASA(TM)
 * @creation	: 28/02/2010
 * @licence		: non assessed
 * @doc			: http://julien-pauli.developpez.com/tutoriels/php/pdo/?page=exemple
 * @doc			: http://forum.alsacreations.com/topic-20-41053-1-ResoluPHP-BD-Quand-se-connecter-a-la-BD-.html
 * @todo		: gestion des exceptions, recherche des index, resetAI uniquement lors de suppressions de blocs sur tables indépendantes
 */

class PDO3 extends PDO2 {

	/* Variables de la classe */
	protected $_pdo		= NULL;				// ne doit pas être "private" car héritage de PDO2
	private $_delimiter	= ',   '; 			// ne pas modifier !
	private $_debug		= false; 			// MODIF si vous voulez
	
	
	/* Constructeur : héritage public obligatoire par héritage de PDO */
	public function __construct($pdo)
	{
		if (isset($pdo) ) {
			$this->_pdo = $pdo;
			$this->checkPdoExtension();
		}
		else {
			throw new PDOException("No pdo connection");
		}
	}


	
	/* Destructeur */
	public function __destruct() // nota: ne surtout pas mettre de parametre
	{
		$this->close();
	}

	
	
	/** 28/02/2010
	* ferme la connexion à la dB (portage dans la classe PDO de la fonction mysql_close)
	*/
	public function close()
	{
		$this->_pdo = NULL;
	}


	
	/* Methode magique */
	public function __toString($object)
	{
		$string = (string) $object ;
		return $string;
	}
	

	
	/**
	* Retourne la liste résumée des tables de la base
	* @doc		: http://cedric-duprez.developpez.com/tutoriels/mysql/catalogue/#LV
	* @return	: (array) $data_array
	*/
	public function getFieldsSummary($limit = false)
	{
		$data_array = array();
		$limit = ($limit == false)? '' : 'LIMIT '. (int) $limit;

		// Les tables, dans l'ordre = f(taille)
		$sql = "SELECT TABLE_NAME, ROUND((DATA_LENGTH + INDEX_LENGTH) / (1024 * 1024), 2) AS SIZE_MO, TABLE_ROWS, AUTO_INCREMENT
		FROM INFORMATION_SCHEMA.TABLES
		WHERE TABLE_SCHEMA = '". $this->_dbname . "'
		ORDER BY DATA_LENGTH + INDEX_LENGTH DESC ". $limit; 
		$result = $this->_pdo->query($sql);
		$rows = $result->fetchAll(PDO::FETCH_ASSOC);

		foreach($rows as $key => $value) {
			$data_array[$key] = $value;
		}

		return $data_array;
	}


	
	/**
	* Retourne la liste détaillée des tables de la base
	* @doc		: http://cedric-duprez.developpez.com/tutoriels/mysql/catalogue/#LV
	* @return	: (array) $data_array
	*/
	public function getFieldsDetails($limit = false)
	{
		$data_array = array();
		$limit = ($limit == false)? false : (int) $limit;

		// Summary: reprise de ces infos comme base de recherche des détails
		$source_array = $this->getFieldsSummary($limit);
				
		// Details
		foreach( $source_array as $key => $field_datas) {

			if (is_array($field_datas)) {
			
				// Transfert du Summary dans le tableau de détails
				$data_array[$key] = $field_datas;
				
				// Details de chaque table
				$table_encours = $field_datas['TABLE_NAME'];
				$sql = "SELECT COLUMN_NAME, COLUMN_TYPE, COLUMN_KEY, EXTRA
						FROM INFORMATION_SCHEMA.COLUMNS
						WHERE TABLE_SCHEMA = '". $this->_dbname . "'
						AND TABLE_NAME = '" . $table_encours . "'";
				$result = $this->_pdo->query($sql);
				$rows = $result->fetchAll(PDO::FETCH_ASSOC);

				// Field List
				$field_list= '';
				$memo_auto_inc = '' ;
				$count = count($rows);
				
				foreach($rows as $k => $value) {
					$memo_auto_inc = ($value['EXTRA'] == 'auto_increment')? $value['COLUMN_NAME'] : $memo_auto_inc ;
					$field_list .= '<b>'. $value['COLUMN_NAME'] . '</b> (' . $value['COLUMN_TYPE'] . ') ' . ' (' . $value['COLUMN_KEY'] . ')'. $this->_delimiter; 
				}
				
				// Marqueur éventuel sur l'AI
				$data_array[$key]['AI_RESET_NEED']	= ($data_array[$key]['AUTO_INCREMENT'] > $count) ?  'true' : 'false' ;
				$data_array[$key]['AI_FIELD']		= $memo_auto_inc ;

				// Array Push
				$data_array[$key]['FIELDS_COUNT']	= $count;
				$data_array[$key]['FIELDS_LIST']	= $field_list;
			}
		}
		
		return $data_array;
	}


	
	/** 28/02/2010 portage dans la classe PDO de la fonction db_pdo.php
	 * retourne la liste des champs d'une table sous forme de vecteur colonne
	 * @param	: (string) $table_name nom de la table dont on veut la liste des champs
	 * @return	: (array) $fieldNames liste des noms de champs de $table_name
	 */
	public function getFieldsName($table_name)
	{
		// Field Details: reprise de ces infos comme base de recherche des détails
		$source_array = $this->getFieldsDetails(false);
		
		// 1ere méthode: lourde et peu élégante
		/*
		$fieldNames = array() ;
		foreach ($source_array as $key => $table_datas) {
			if (is_array($table_datas)) {
				if ($table_datas['TABLE_NAME'] == $table_name) {
					$fieldNames = explode( $this->_delimiter , $table_datas['FIELDS_LIST'] )  ;
				}
			}
		}
		array_pop($fieldNames) ;
		*/
		
		// 2eme méthode: plus directe et élégante : recupération récursive de la clé correspondante à la table
		$key = $this->recursiveArraySearch($table_name , $source_array ) ;
		$fieldNames = explode( $this->_delimiter , $source_array[$key]['FIELDS_LIST'] )  ;
		array_pop($fieldNames);
		
		// 3eme methode: brut accès direct aux infos dB sans utiliser d'autres fonctions
		/*
		$recordset = $this->_pdo->query("SHOW COLUMNS FROM $table_name");
		$fields = $recordset->fetchAll(PDO::FETCH_ASSOC);
		foreach ($fields as $field) {
			$fieldNames[] = $field['Field'];
		}
		*/
		
		return $fieldNames;
	}


	
	/**
	* Ré initialise l'auto-increment d'une table à une valeur initiale donnée
	* ######## A EVITER : la plupart des tables sont liées par les id AI ... ########
	* @doc		:// http://sqlpro.developpez.com/cours/clefs/#L3.2
	* @return	: true
	*/
	public function resetAI($table_name, $init_AI = 200)
	{
		// 1) Vérifier que cette table n'est pas liée à d'autres par ses ID et à appliquer uniquement après suppression de blocs de datas...
		// 2) Combien de datas dans la table
		// 3) Quelle valeur de AI initial
		// 4) Quelle valeur de AI courante
		// 5) Justification de remettre AI à flot
		// 6) Reset des AI existants
		// 7) Mise à jour de l'AI de cette table
	}
	


	/** 28/02/2010 portage dans la classe PDO de la fonction incluse dans db_pdo.php
	 * sauve des datas (variables ou array) INSERT ou UPDATE dans la table $table de la dB
	 * @NOTA 	: fonction dépréciée au profit de la fonction saveData
	 * @param 	: $table_name, $data_array
	 * @return	: true si tout s'est bien passé, false sinon
	 * @doc		: http://fr.php.net/manual/fr/function.mysql-query.php#84962
	 */
	public function addData($table_name, $excluded_fields = '', $data_array, $sql_type = 'insert', $sql_condition = NULL )
	{
		
			// Init
			$fields = '';
			$values = '';
			$debug = $this->_debug ;
			$pattern = '/tel|phone|fax|siret|number|numero/';

			
			// format input fields into sql (explode du tableau associatif en requete SQL)
			foreach ($data_array as $field => $value) {

				if (!strstr($excluded_fields, $field)) {

				  // construction de la sql pour INSERT
				  if (strtolower($sql_type) == 'insert') {
					$fields .= "$field, ";
					$values .= "'$value', ";
				  }
				  // construction de la sql pour UPDATE
				  else {
					if (!is_numeric($value)) {
						$fields .= "$field = '$value', ";	// string
					}
					else {
						// exceptions: pour le num de tel/fax/siret qui peut commencer par un zero et peut ainsi être assimilé à un numeric, ce qui n'est pas le cas ds la dB
						if ( !preg_match( $pattern, $field  ) ) {
							$fields .= "$field = $value, "; // numeric
						}
						else {
							$fields .= "$field = '$value', ";// si tel/phone/fax/siret => string
						}
					}
				  }
				}
			}

			// remove trailing ", " from $fields and $values
			$fields = preg_replace('/, $/', '', $fields);
			$values = preg_replace('/, $/', '', $values);

			// create sql statement
			if (strtolower($sql_type) == 'insert') {
				$sql = "INSERT INTO $table_name ($fields) VALUES ($values)";
			}
			elseif (strtolower($sql_type) == 'update') {
				if (!isset($sql_condition)) {
				  echo 'ERROR: You must enter a sql condition!';
				  exit;
				}
				$sql = "UPDATE $table_name SET $fields WHERE $sql_condition";
				
			}
			else {
				echo 'ERROR: Invalid input for argument $sql_type: must be "insert" or "update"';
				exit;
			}

			// prepare & execute sql
			$query = $this->_pdo->prepare($sql) ;
			$result = $query->execute() ;
			//$result->closeCursor(); // not always necessary: depends on SQL driver needs
			
			if ( $result ) {
				return true;
			}
			else if ( $result === false ){
				if ($debug) {
					return 'err sql: ' ; //. mysql_error();	
				}
				else {
					return false;
				}
			}
		
	} /* fin addData */


	/** 01/03/2010
	 * sauve $data_array dans $table (la condition d'UPDATE devenant optionnelle si elle ne porte que sur l'id PK)
	 * @param 	: $table_name destination, $data_array à sauver, $sql_type='insert' ou 'update', $optional_condition
	 * @doc		: http://www.php.net/manual/fr/pdostatement.execute.php#80499
	 * @return	: true si tout s'est bien passé, false sinon
	 */
	public function saveData($table_name, $data_array, $sql_type='insert', $optional_condition=NULL )
	{

		// Init
		$debug			= $this->_debug;
		$sql			='';
		$pattern_field	= '/^(?:\<b\>)(\w+)(?:\<\/b\>)(?:\s{0,})\((.+)\)(?:\s{0,})\((.+)?\)$/';
		$field_name		= $field_format = $field_key = array() ;
		
		// Initial checks
			// Data_array in line with table fields
				
				// db fields
				$db_fields = $this->getFieldsName($table_name) ;
				if ( empty($db_fields) ) return false ;
				foreach ( $db_fields as $field) {
					unset($matches);
					if ( preg_match($pattern_field, $field, $matches) ) {
						$field_name[]	= trim($matches[1]);
						$field_format[]	= trim($matches[2]);
						$field_key[]	= trim($matches[3]);
					}
				}
				/*
				if ($debug) {
					$this->arr_dump(array('keys'=>$field_key, 'names'=>$field_name, 'formats'=>$field_format) , 'Matching results');
				}
				*/
				
				// Comparison $db_fields with $data_array: can accept missing fields but no mismatching fields (thus avoiding typos in $data_array)
				$mismatching_fields = array_diff(array_keys($data_array), $field_name);
				if ( count($mismatching_fields) != 0) {
					if ($debug) {
						echo '<br/>PDO3 db Vs data fields issue';
						$this->arr_dump($mismatching_fields, 'mismatch' );
					}
					return false;
				}
				
				// Check data_array format Vs dB_fields format
				// #########
				// # To do
				// #########
				
				
		// Build SQL statement
			// INSERT $sql = "INSERT INTO $table_name ($fields) VALUES ($values)";
				$fields = '';
				$values = '';
				if ( strtolower($sql_type) == 'insert') {
					foreach($data_array as $field => $data) {
						$fields .= "$field, ";
						$values .= "'$data', ";
					}
					$fields = preg_replace('/, $/', '', $fields);
					$values = preg_replace('/, $/', '', $values);
					$sql = "INSERT INTO $table_name ($fields) VALUES ($values)";
					if ($debug) echo '<br/>sql statement: ' . $sql;
				}
				
			// UPDATE
				if ( strtolower($sql_type) == 'update') {
					//if ($debug) echo '<br/>Starting update....' ;

					
					// Update Condition $sql_condition
						$sql_condition = '';
						
						// dB primary key field required
							$needle = 'PRI';
							$pk_key = trim($this->recursiveArraySearch($needle, $field_key) ) ;
							if (false === $pk_key ) {		// NOTA: '===' is a must as $pk_key canb be 0 and then understood as 'false'
								if ($debug) {
									echo '<br/>PDO3 Err: no primary key found' ;
									$this->arr_dump( array('pk key'=> $pk_key , 'needle'=>$needle, 'fields' => $field_key), 'Check needle & arrays') ;
								}
								
								return false;
							}
							else {
								if ($debug) {
								echo '<br/>found primary key in db datas array <b>keys</b> :' . $pk_key;
								// $this->arr_dump( $field_key , 'field_key');
								}
							}
							
						// data_array field content check
						$pk_value = (array_key_exists($field_name[$pk_key], $data_array))? $data_array[$field_name[$pk_key]] : false ;
						if (false === $pk_value || empty($pk_value) )  {
							if ($debug) $this->arr_dump( array('key'=>$pk_key, 'value'=>$pk_value, 'data'=>$data_array) , 'PDO3 Err: no data content for primary key sql condition');
							return false ;
						}
						else if ($debug) echo '<br/>found primary key value in db datas array <b>values</b>:' . $pk_value;
						
						// db_field: check if table field of row(pk) exists (in order to being able to properly set the sql_condition)
						// #########
						// # to do
						// #########
						
						// Sql condition base
						$sql_condition = $field_name[$pk_key] . '=' . $pk_value;
						if ($debug) echo '<br/>sql update condition base: ' . $sql_condition ;

						// Sql condition options
						// #########
						// # to do: check if necessary (prepared request) that the optional sql condition is not matching with forbidden conditions like 1=1 or DELETE..
						// #########
						$sql_condition .= ($optional_condition)? ' AND ' . $optional_condition : '' ;
						
						// Build sql statement (not necessary to remove PK field from fields to update)
						$fields = '';
						foreach($data_array as $field => $data) {
							$fields .= "$field = '$data', ";
						}
						// remove trailing ','
						$fields = preg_replace('/, $/', '', $fields);
					
					
					// Sql statement
						$sql = "UPDATE $table_name SET $fields WHERE $sql_condition";
						if ($debug) echo '<br/>sql statement: ' . $sql;
				}
			
			
		// Prepare & Execute Sql statement (sothat there is no need to use "quote" method for data protection against SQL injection)
			if ($sql) {
				$query	= $this->_pdo->prepare($sql) ;
				$result	= $query->execute() ;
				$count	= $query->rowCount(); // Check affected rows by INSERT or UPDATE (nota : this methode does not work for SELECT)
			}
			
		// Return Value
			if ($result && $count > 0) {
				return true;
			}
			else{
				return false;
			}
				
		
	} /* fin saveData */



	
	/**
	* Recherche récursive de la clé de niveau 0 d'une valeur située dans un tableau multidimensionnel de profondeur D
	* @source	: http://fr.php.net/manual/fr/function.array-search.php#91365
	* @return	: $key($needle)
	*/
	private function recursiveArraySearch($needle, $haystack) {
		foreach($haystack as $key=>$value) {
			$current_key=$key;
			if($needle===$value OR (is_array($value) && $this->recursiveArraySearch($needle, $value) !== false)) {
				return $current_key;
			}
		}
		return false;
	}

	/** 01/02/2010
	* Vérifie que l'extension pdo est bien chargée et est bien en phase avec le type des requetes émises dans la classe PDO2
	* @source	: http://php.developpez.com/faq/?page=pdo#pdo-loaded-drivers
	* @return	: true ou false
	*/
	// ######### à ré-implémenter en amont dans PDO2 avec gestion erreur ################
 	private function checkPdoExtension() {
		if ($this->_debug) echo '<br/>Checking for PDO extension loaded';
		$pdo_ext = false;
		foreach(get_loaded_extensions() as $extension) {
			if(strpos(strtolower($extension), 'pdo') !== 'pdo') {
				$pdo_ext = true;
			}
		}
		if ($this->_debug && false == $pdo_ext) echo '<br/>PDO extension not loaded';
		return $pdo_ext;
	}


	/**
	* fonction de debugage
	*/	
	private function arr_dump($array, $text='') {
		echo '<br/>Dump('.$text.')<pre>'; print_r($array); echo '</pre>' ;
	}


} /* fin de la Classe */

?>

 Conclusion

J'attends avec un frémissement non dissimulé les critiques constructives :-)

 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Sources du même auteur

TESTEUR DE REGEX
BARRES PARAMÉTRABLES EN DÉGRADÉ DE COULEUR ET AVEC TEXTE DA...

 Sources de la même categorie

Source avec Zip GÉNÉRATION AUTOMATIQUE DE FICHIER .CLASS.PHP EN FONCTION D'U... par ig3
CLASSE D'OBJET DE CRYPTAGE ET DÉCRYPTAGE DE CHAINES DE CARAC... par 8Tnerolf8
Source avec Zip MY.DEVIANTART API par inwebo
CLASSE DE GESTION DE "VARIABLES GLOBALES D'ENVIRONNEMENT" par pifou25
Source avec Zip COLLECTION.CLASS.MIN.PHP par thunderhunter

 Sources en rapport avec celle ci

CLASSE MYSQL UTILISANT LES FONCTIONS PDO par Vince66
Source avec Zip Source avec une capture DBOC - V3.1 [AJAX][PHP5] par Morphinof
Source avec Zip [POO][PHP5]UN SITE MULTILANGUE VIA XML par destinyfr
Source avec Zip PHP5 MY EXPLORER : AFFICHE L'ARBORESCENCE DE DOSSIERS par ranouf
Source avec Zip ABSTRACTION PDO par dorian91

Commentaires et avis

Commentaire de hornetbzz le 08/03/2010 14:25:57

Deux petites remarques :
- la classe PDO3 pourrait être surchargée en PHP5.3 grâce à la méthode magique __call() afin d'utiliser les méthodes natives de PDO directement avec un objet de la classe PDO3.
- l'utilisation des méthodes natives de PDO (PDO::Statement) s'effectue grâce au singleton de la classe PDO2

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

Formulaire avec select et update de bdd mysql [ par arnold002 ] Bonjour &#224; tous,J'ai un formulaire qui contient 2 champs de type select : classe et annee.Je veux associer chaque classe &#224; chaque ann&#233;e passage de variables de form vers bdd mysql [ par arnold002 ] Bonjour,Mon probl&#232;me n'avance pas...Mon form contient 2 champs select for($i<FONT color=#008000 s Recherche mysql [ par simon0000 ] salut tous le monde ,j'ai une table mysql nom&#233;&nbsp;ecole ou il ya Connection mysql avec php5 [ par Chess0 ] Bonjour, j'ai install&#233; r&#233;cemment la derni&#232;re version de mysql ainsi que la derni&#232;re version de php (5). J'ai essay&#233; la connec Retour des données d'une classe MySQL [ par Jerem_ ] Salut, Depuis ce matin, j'asseye de coter une classe MySQL pour mon site. La classe marche tr&#232;s bien quand je fait une requete INSERT, etc .. M Pb passage PHP4 -> PHP5 [ par Galmiza ] Salut,J'ai acheté un bouquin pour débuter le PHP.J'ai suivi a la lettre les instructions du livre:-installer EasyPHP 1.7-installer PHP 5.0..-lancer Ea Problème affichage BD multiples [ par ekipage2 ] Bonjour,j'ai plusieurs BD : eleve / matières / et exercicesLorque l'élèv se connecte, il peut afficher la liste des exercices correspondants à sa clas PHP5 et MySQL 4.1.7 [ par TMT ] J'ai installé PHP5 et MySQL sur mon Windows XP avec IIS. J'ai bien activé le module php_mysql dans le fichier php.ini Là mon problème est qu-à chaque Problème d'un script [ par stu76 ] Bonsoir,J'ai &#233;cris un petit script qui me permet d'afficher les &#233;l&#232;ves stocker dans une base de donn&#233;es. Mon prob est que l'affich Bug dans une double liste [ par stu76 ] Bonjour, Malalam m'a donné des infos hier sur les doubles liste, et je le remercie car ca ma été super utile. J'ai presque résolu le prob sauf que je


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

Photothèque

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,655 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales