Accueil > > > [PHP5.2] CLASSE PDO
[PHP5.2] CLASSE PDO
Information sur la source
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 :-)
Sources du même auteur
Sources de la même categorie
Commentaires et avis
Discussions en rapport avec ce code source dans le forum
Formulaire avec select et update de bdd mysql [ par arnold002 ]
Bonjour à tous,J'ai un formulaire qui contient 2 champs de type select : classe et annee.Je veux associer chaque classe à chaque année
passage de variables de form vers bdd mysql [ par arnold002 ]
Bonjour,Mon problè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é ecole ou il ya
Connection mysql avec php5 [ par Chess0 ]
Bonjour, j'ai installé récemment la dernière version de mysql ainsi que la dernière version de php (5). J'ai essayé 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è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 écris un petit script qui me permet d'afficher les élèves stocker dans une base de donné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
|
Derniers Blogs
IMAGINE CUP 2012, MAKE A SIGN EN FINALEIMAGINE CUP 2012, MAKE A SIGN EN FINALE par junarnoalg
Voilà qui est fait, la nouvelle est officielle ! L'équipe belge "Make a Sign" va au pays des kangourous défendre son projet dans la catégorie Software Design. http://www.imaginecup.com/CompetitionsContent/Competition/WorldwideFinalists.aspx V...
Cliquez pour lire la suite de l'article par junarnoalg KINECT 1.5 IS OUT !KINECT 1.5 IS OUT ! par Vko
La version 1.5 du Kinect For Microsoft vient tout juste de sortir ! Plein de nouveautés: Tracking de squelette en Near Mode Détection en position assise Détection faciale avec un SDK dédié Documentation et des guideline (enfin) Un out...
Cliquez pour lire la suite de l'article par Vko LES ACTUALITéS DE LA SEMAINE SUR C2I.FR (14 MAI - 20 MAI) LES ACTUALITéS DE LA SEMAINE SUR C2I.FR (14 MAI - 20 MAI) par richardc
Mise à jour des Web API du 14 Mai
Réservez dès maintenant votre journée du 20 juin pour le Windows Azure Dev Camp 2012 à Paris
Mise à jour de Team Foundation Service
MechCommander 2 sur Windows 8
Entity Framework 5 Release Candidate e...
Cliquez pour lire la suite de l'article par richardc REACTIVE EXTENSIONS : CONSOMMER DES SERVICES AVEC RX PARTIE 3, LES PIèGES à éVITERREACTIVE EXTENSIONS : CONSOMMER DES SERVICES AVEC RX PARTIE 3, LES PIèGES à éVITER par Groc
Une mauvaise utilisation de rx lors de l'écriture d'une couche d'accès à des services peut conduire à des cas embarassants avec des erreurs mal gérées, des appels qui ne partent lorsqu'ils le devraient, et même des résultats incorrects . le tout nuis...
Cliquez pour lire la suite de l'article par Groc SHAREPOINT BLOG SITE, PROBLèME D'ARCHIVESSHAREPOINT BLOG SITE, PROBLèME D'ARCHIVES par junarnoalg
Dernièrement, nous avons migré le site
myTIC
vers un nouveau serveur SharePoint 2010. Dans les contenus que nous vouloins récupérer, nous avions un certain nombre de blogs.
Nous avons utilisé les commandes Power...
Cliquez pour lire la suite de l'article par junarnoalg
Logiciels
sDEVIS-FACTURES vlPRO (8.1.0.3)SDEVIS-FACTURES VLPRO (8.1.0.3)sDEVIS-FACTURES vlPRO a été mis au point pour les particuliers, créateurs, entrepreneurs, artisa... Cliquez pour télécharger sDEVIS-FACTURES vlPRO 974 Application Server (12.2.4.6)974 APPLICATION SERVER (12.2.4.6)Développez de puissantes applications dans un environnement de 'cloud computing', clusterisé, séc... Cliquez pour télécharger 974 Application Server vPicture (1.4.2.1)VPICTURE (1.4.2.1)Avec vPicture, hébergez vos images facilement et rapidement.
vPicture est un utilitaire simple, ... Cliquez pour télécharger vPicture Easy-Planning (2.2.1.6)EASY-PLANNING (2.2.1.6)Easy-Planning permet de créer des plannings sous la représentation de diagrammes et est adapté au... Cliquez pour télécharger Easy-Planning COM-BACKUP (2.0)COM-BACKUP (2.0)
COM-BACKUP est un logiciel de sauvegarde qui permet de planifier les sauvegardes de vos dossiers ...
Cliquez pour télécharger COM-BACKUP
|