Abdmysql v1.4.8 accès aux bases de données mysql.

Soyez le premier à donner votre avis sur cette source.

Vue 7 307 fois - Téléchargée 724 fois

Description

Cette classe permet d'accéder aux bases de données MySQL.
Elle permet de se connecter, déconnecter, exécuter différentes requêtes, savoir si une table existe, la renommer, la supprimer, de connaitre le nombre de résultats d'une requête, d'exécuter plusieurs requêtes à la suite, de faire un remplacement de chaine de caractères, de sécuriser une valeur contre l'SQL Injection, de faire une sauvegarde d'une base de données (structure seule au format SQL, données seules (format SQL ou XML), ou les deux au format SQL) ou encore de savoir combien d'enregistrements contient une table (avec la possibilité d'ajouter des conditions), de récupérer le contenu d'une table dans un tableau associatif, etc. Cette classe intègre en plus une protection contre l'inclusion répétée du fichier et une gestion interne des erreurs via des constantes prédéfinies, la gestion d'exceptions, et la possibilité d'enregistrer les erreurs (paramétrable) dans un fichier journal au format XML.
Fonctionnalité très importante : La classe libère automatiquement toutes les ressources non libérées lors de sa destruction pour alléger le serveur !

Source / Exemple :


<?php

#  \
#   | Application			: ABDMySQL
#   | Version				: 1.4.8
#   | Auteur				: Psykocrash (SERRAJ Younes)
#   | Messagerie			: bonsite [at] hotmail [dot] com
#   | Date de modification	: Dimanche 20 mai 2007
#   | Langage				: PHP5
#   | URL					: http://www.phpcs.com/codes/ABDMYSQL_38954.aspx
#   | Licence				: http://www.gnu.org/licenses/lgpl.txt
#   | +-------------------------------------------------------+
#   | ABDMySQL. Accès aux bases de données MySQL.
#   | Copyright (C) 2007 SERRAJ Younes - Tous droits réservés.
#   | 
#   | Cette bibliothèque est un logiciel libre ; vous pouvez la redistribuer ou
#   | la modifier suivant les termes de la Licence Générale Publique Limitée
#   | GNU telle que publiée par la Free Software Foundation dans la version 2.1 
#   | de la License.
#   | 
#   | Cette bibliothèque est distribuée dans l?espoir qu?elle sera utile, mais
#   | SANS AUCUNE GARANTIE : sans même la garantie implicite de
#   | COMMERCIABILISABILITÉ ou d?ADÉQUATION À UN OBJECTIF PARTICULIER. Consultez
#   | la Licence Générale Publique Limitée pour plus de détails.
#   | 
#   | Vous devriez avoir reçu une copie de la Licence Générale Publique Limitée
#   | avec cette bibliothèque ; si ce n?est pas le cas, écrivez à la :
#   | Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
#   | MA 02111-1307, USA.
#   | +-------------------------------------------------------+
#  /

if (!defined("ABDMySQL_INCLUDED")) // Protection pour que le fichier ne soit inclus qu'une seule fois
{
	define("ABDMySQL_INCLUDED", true);
	
	# CLASSE DE GESTION DE BASE DE DONNEE MySQL #
	
	// CONSTANTES GLOBALES
	define('ABDMYSQL_XML_ENCODING', 'UTF-8');
	
	// CONSTANTES D'ERREURS
	define('ERR_ABDMYSQL_CANNOT_CONNECT', -15001);
	define('ERR_ABDMYSQL_NOT_CONNECTED', -15002);
	define('ERR_ABDMYSQL_ALREADY_CONNECTED', -15003);
	define('ERR_ABDMYSQL_CANNOT_CARRY_OUT_THE_REQUEST', -15004);
	define('ERR_ABDMYSQL_CANNOT_FOUND_FILE', -15005);
	define('ERR_ABDMYSQL_CANNOT_OPEN_FILE', -15006);
	define('ERR_ABDMYSQL_CANNOT_WRITE_FILE', -15007);
	define('ERR_ABDMYSQL_CANNOT_SELECT_DATABASE', -15008);
	define('ERR_ABDMYSQL_REQUIERE_VERSION_5', -15009);
	define('ERR_ABDMYSQL_INCOMPATIBLE_PARAMETERS', -15010);
	define('ERR_ABDMYSQL_CANNOT_OPEN_GZFILE', -15011);
	define('ERR_ABDMYSQL_CANNOT_WRITE_GZFILE', -15012);
	define('ERR_ABDMYSQL_INVALID_DATA_FORMAT', -15013);
	define('ERR_ABDMYSQL_DATA_MISSING', -15014);
	define('ERR_ABDMYSQL_INVALID_DATA', -15015);
	
	// MESSAGES D'ERREURS PREDEFINIS
	define('ERRMSG_ABDMYSQL_CANNOT_CONNECT', "Impossible d'établire une connexion.");
	define('ERRMSG_ABDMYSQL_NOT_CONNECTED', 'Non connecté.');
	define('ERRMSG_ABDMYSQL_ALREADY_CONNECTED', 'Connexion déjà établie.');
	define('ERRMSG_ABDMYSQL_CANNOT_CARRY_OUT_THE_REQUEST', "Impossible d'exécuter la requête.");
	define('ERRMSG_ABDMYSQL_CANNOT_OPEN_FILE', "Impossible d'ouvrir le fichier.");
	define('ERRMSG_ABDMYSQL_CANNOT_WRITE_FILE', "Impossible d'écrire dans le fichier.");
	define('ERRMSG_ABDMYSQL_CANNOT_SELECT_DATABASE', 'Impossible de sélectionner la base de données.');
	define('ERRMSG_ABDMYSQL_UNKNOWN_ERROR', 'Erreur inconnue.');
	define('ERRMSG_ABDMYSQL_REQUIERE_VERSION_5', "Cette action nécessite d'avoir au minimum la version 5 de MySQL.");
	define('ERRMSG_ABDMYSQL_INCOMPATIBLE_PARAMETERS', 'Paramètres incompatibles.');
	define('ERRMSG_ABDMYSQL_CANNOT_OPEN_GZFILE', "Impossible d'ouvrir le fichier compressé avec gzip.");
	define('ERRMSG_ABDMYSQL_CANNOT_WRITE_GZFILE', "Impossible d'écrire dans le fichier compressé avec gzip.");
	define('ERRMSG_ABDMYSQL_INVALID_DATA_FORMAT', 'Format de donnée(s) invalide pour cette opération.');
	define('ERRMSG_ABDMYSQL_DATA_MISSING', 'Paramètre(s) manquant(s).');
	define('ERRMSG_ABDMYSQL_INVALID_DATA', 'Paramètre(s) incorrect(s).');
	
	// INTERFACE
	
	interface ABDMySQL_Datetime_Interface
	{
		public function getDate();
		public function getTime();
		public function getDatetime();
	}
	
	interface ABDMySQL_Interface
	{
		// Fonctions générales
		public function connect($hostname='localhost', $username, $password, $database='');
		public function getMySQLLink();
		public function getRequestsCount();
		public function getLastInsertID();
		public function close();
		public function makeSafe(&$value);
		
		// Bases de données
		public function selectDatabase($name);
		public function getDatabasesList();
		public function databaseExists($name);
		public function databasesExists();
		public function deleteDatabase($name);
		
		// Tables
		public function tableExists($name);
		public function tablesExists();
		public function getTablesList();
		public function getTableStruct($name);
		public function getTableData($name);
		public function getFullTable($name);
		public function renameTable($oldName, $newName);
		public function deleteTable($name);
		
		// Vues
		public function createView($name, $columns, $table);
		public function deleteView($name);
		
		// Logs
		public function activate_errorsLog($filepath, $includeDetails=false, $includeMySQLError=false);
		public function desactivate_errorsLog();
		
		// Requêtes
		public function select($request);
		public function insert($request);
		public function update($request);
		public function replace($table, $row, $substring, $replacewith, $condition='');
		public function query_without_results($request);
		public function query($requests, $regexp_separator = '/;\n/m');
		public function delete($table, $condition='');
		public function rowsCount($table, $condition='');
		
		// Traitement des ressources
		public function isMySQLResource($resource);
		public function fetchAll($result, $resultType = MYSQL_ASSOC);
		public function freeResult($result);
		public function freeResults();
		public function resultsCount($result);
		
		// Backups
		public function saveCurrentDatabaseStruct_SQL($auto_increment=false, $output_file='', $append=false, $compressed=false);
		public function saveCurrentDatabaseData_SQL($output_file='', $append=false, $compressed=false);
		public function saveCurrentDatabaseData_XML($output_file='', $append=false, $compressed=false);
	}
	
	// CLASSES
	class ABDMySQL_Datetime implements ABDMySQL_Datetime_Interface
	{
		public function getDate()
		{
			return gmdate('Y-m-d');
		}
		
		public function getTime()
		{
			return gmdate('H:i:s');
		}
	
		public function getDatetime()
		{
			return gmdate('Y-m-d H:i:s');
		}
	}
	
	class ABDMySQL implements ABDMySQL_Interface
	{
		protected $app_name = 'ABDMySQL';
		protected $app_version = '1.4.8';
		
		protected $mysql_link = 0;
		private $mysql_version = false;
		protected $database = '';
		protected $requestsCount = 0;
		protected $logErrors = false;
		protected $errorsLogPath = '';
		protected $includeDetails = false;
		protected $includeMySQLError = false;
		protected $results = array();
		
		public $MySQLDatetime = NULL;
		
		function __destruct()
		{
			$this->close();
		}
		
		# Fonctions générales #
		public function connect($hostname='localhost', $username, $password, $database='')
		{ // Connexion à la base de données
			$this->MySQLDatetime = new ABDMySQL_Datetime();
			if ($this->isConnected() == true) $this->_logError(ERR_ABDMYSQL_ALREADY_CONNECTED, 'connect'); // Si une connexion est déjà établie, Erreur.
			$this->mysql_link = mysql_connect($hostname, $username, $password, false, MYSQL_CLIENT_COMPRESS); // Tentative de connexion au serveur.
			if (!$this->mysql_link) $this->_logError(ERR_ABDMYSQL_CANNOT_CONNECT, 'connect', 'Hostname: \'' . $hostname . '\', Username: \'' . $username . "'"); // Si la connexion à échouée, Erreur.
			if (trim($database) != '') $this->selectDatabase($database);  // Si la sélection d'une base de données a échouée, Erreur.
			$this->getMySQLVersion();
		}
		
		private function getMySQLVersion()
		{
			$this->mysql_version = substr(mysql_get_server_info(), 0, 1);
		}
		
		public function getMySQLLink()
		{
			return $this->mysql_link;
		}
		
		public function getRequestsCount()
		{
			return $this->requestsCount;
		}
		
		public function getLastInsertID()
		{
			return mysql_insert_id();
		}
		
		protected function isConnected()
		{ // Vérification de l'existance d'une connexion
			if (!$this->mysql_link) return false;
			else return true;
		}
		
		public function close()
		{
			if ($this->isConnected() == true)
			{
				foreach($this->results as $result) $this->freeResult($result);
				mysql_close($this->mysql_link); // Fermeture de la connexion
				$this->mysql_link = false;
				$this->requestsCount = 0; // Initialisation du nombre de requêtes
				$this->database_name = ''; // Supression du nom de la base de données
			}
		}
		
		public function makeSafe(&$value)
		{
			$value = mysql_real_escape_string($value, $this->mysql_link);
			return $value;
		}
		
		protected function xmlEncode($value)
		{
			return htmlspecialchars(utf8_encode($value));
		}
		
		# Bases de données #
		public function selectDatabase($name)
		{
			if (!mysql_select_db($name, $this->mysql_link))
			{
				$this->_logError(ERR_ABDMYSQL_CANNOT_SELECT_DATABASE, 'selectDatabase', "Param: '" . $name . "'"); // Si la sélection d'une base de données a échouée, Erreur.
			}
			else
			{
				$this->database = $name; // Mémorisation du nom de la base de données.
			}
		}
		
		public function databaseExists($name)
		{ // Vérification de l'existance d'une table
			if ($this->isConnected() == false) $this->_logError(ERR_ABDMYSQL_NOT_CONNECTED, 'databaseExists'); // Si aucune connexion n'est établie, Erreur.
			$this->makeSafe($name); // Protection contre l'SQL Injection.
			$databasesList = $this->getDatabasesList();
			if (!in_array($name, $databasesList)) return false; // Si aucune base de données de ce nom n'existe, renvoit la valeur 'false'.
			else return true; // Si une base de données de ce nom existe, renvoit de la valeur 'true'.
		}
		
		public function databasesExists()
		{
			$argsCount = func_num_args();
			if ($argsCount < 1) $this->logError(ERR_ABDMYSQL_DATA_MISSING, 'databasesExists');
			$argsList = func_get_args();
			$databasesList = $this->getDatabasesList();
			for ($i = 0; $i < $argsCount; $i++)
			{
				if (!in_array($argsList[$i], $databasesList)) return false;
			}
			return true;
		}
		
		public function getDatabasesList()
		{
			if ($this->isConnected() == false) $this->_logError(ERR_ABDMYSQL_NOT_CONNECTED, 'getDatabasesList'); // Si aucune connexion n'est établie, Erreur.
			$request = 'SHOW DATABASES'; // Construction de la requête.
			$result = mysql_query($request, $this->mysql_link); // Exécution d'une requête.
			$this->requestsCount++; // Incrémentation du nombre de requêtes effectuées.
			if (!$result) $this->_logError(ERR_ABDMYSQL_CANNOT_CARRY_OUT_THE_REQUEST, 'getDatabasesList'); // Si la requête n'a pas été effectuée correctement, Erreur.
			$liste = array();
			while ($db = mysql_fetch_array($result))
				array_push($liste, $db['Database']);
			$this->freeResult($result);
			return $liste;
		}
		
		public function deleteDatabase($name)
		{
			if ($this->isConnected() == false) $this->_logError(ERR_ABDMYSQL_NOT_CONNECTED, 'deleteDatabase'); // Si aucune connexion n'est établie, Erreur.
			$this->makeSafe($name); // Protection contre l'SQL Injection.
			$request = 'DROP DATABASE `' . $name . '`'; // Construction de la requête.
			$this->query_without_results($request);
		}
		
		# Tables #
		public function tableExists($name)
		{ // Vérification de l'existance d'une table
			if ($this->isConnected() == false) $this->_logError(ERR_ABDMYSQL_NOT_CONNECTED, 'tableExists'); // Si aucune connexion n'est établie, Erreur.
			$this->makeSafe($name); // Protection contre l'SQL Injection.
			$tablesList = $this->getTablesList();
			if (!in_array($name, $tablesList)) return false;
			else return true; // Si une table de ce nom existe, renvoit de la valeur 'true'.
		}
		
		public function tablesExists()
		{
			$argsCount = func_num_args();
			if ($argsCount < 1) $this->logError(ERR_ABDMYSQL_DATA_MISSING, 'tablesExists');
			$argsList = func_get_args();
			$tablesList = $this->getTablesList();
			for ($i = 0; $i < $argsCount; $i++)
			{
				if (!in_array($argsList[$i], $tablesList)) return false;
			}
			return true;
		}
		
		public function getTablesList($database='')
		{
			if ($this->isConnected() == false) $this->_logError(ERR_ABDMYSQL_NOT_CONNECTED, 'getTablesList'); // Si aucune connexion n'est établie, Erreur.
			if (trim($database) == '') $database = $this->database;
			$request = 'SHOW TABLES FROM ' . $database; // Construction de la requête.
			$result = mysql_query($request, $this->mysql_link); // Exécution d'une requête.
			$this->requestsCount++; // Incrémentation du nombre de requêtes effectuées.
			if (!$result) $this->_logError(ERR_ABDMYSQL_CANNOT_CARRY_OUT_THE_REQUEST, 'getTablesList', "Param: '" . $database . "'"); // Si la requête n'a pas été effectuée correctement, Erreur.
			$liste = array();
			while ($db = mysql_fetch_array($result))
				array_push($liste, $db['Tables_in_' . $database]);
			$this->freeResult($result);
			return $liste;
		}
		
		public function getTableStruct($name)
		{ // Renvoit la structure d'une table
			if ($this->isConnected() == false) $this->_logError(ERR_ABDMYSQL_NOT_CONNECTED, 'getTableStruct'); // Si aucune connexion n'est établie, Erreur.
			$this->makeSafe($name); // Protection contre l'SQL Injection.
			if (!$this->tableExists($name)) return false;
			$table = array();
			$table['config'] = array();
			$table['config']['FullText'] = array();
			$table['config']['PrimaryKey'] = array();
			$result_table_status = $this->select('SHOW TABLE STATUS');
			$table_status = mysql_fetch_array($result_table_status);
			$this->freeResult($result_table_status);
			$result_table_columns = $this->select('SHOW COLUMNS FROM `' . $name . '`');
			while($champs = mysql_fetch_array($result_table_columns))
			{
				// Type
				$table['columns'][$champs['Field']]['Type'] = strtoupper($champs['Type']);
				
				// Null
				if ($champs['Null'] == "NO") $table['columns'][$champs['Field']]['Null'] = false;
				else $table['columns'][$champs['Field']]['Null'] = true;
				
				// AutoIncrement
				if ($champs['Extra'] == "auto_increment") $table['columns'][$champs['Field']]['AutoIncrement'] = true;
				else $table['columns'][$champs['Field']]['AutoIncrement'] = false;
				
				// PrimaryKey
				if ($champs['Key'] == "PRI")
				{
					$table['columns'][$champs['Field']]['PrimaryKey'] = true;
					array_push($table['config']['PrimaryKey'], $champs['Field']);
				}
				else
				{
					$table['columns'][$champs['Field']]['PrimaryKey'] = false;
				}
			}
			$this->freeResult($result_table_columns);
			$result_index = $this->select('SHOW INDEX  FROM `' . $name . '`');
			if ($result_index)
			{
				while($champs = mysql_fetch_array($result_index))
				{
					if ($champs['Index_type']=="FULLTEXT")
					{
						$table['columns'][$champs['Column_name']]['FullText'] = true;
						array_push($table['config']['FullText'], $champs['Column_name']);
					}
					else
					{
						$table['columns'][$champs['Column_name']]['FullText'] = false;
					}
				}
			}
			$this->freeResult($result_index);
			$table['config']['Engine'] = $table_status['Engine'];
			if ($table_status['Auto_increment'] > 0) $table['config']['AutoIncrement'] = $table_status['Auto_increment'];
			return $table;
		}
		
		public function getTableData($name)
		{
			if ($this->isConnected() == false) $this->_logError(ERR_ABDMYSQL_NOT_CONNECTED, 'getTableData'); // Si aucune connexion n'est établie, Erreur.
			$this->makeSafe($name);
			$result = $this->select('SELECT * FROM `' . $name . '`');
			$tableau = $this->fetchAll($result);
			$this->freeResult($result);
			return $tableau;
		}
		
		public function getFullTable($name)
		{
			if ($this->isConnected() == false) $this->_logError(ERR_ABDMYSQL_NOT_CONNECTED, 'getTableData'); // Si aucune connexion n'est établie, Erreur.
			$this->makeSafe($name);
			$table = $this->getTableStruct($name);
			$table['content'] = $this->getTableData($name);
			return $table;
		}
		
		public function renameTable($oldName, $newName)
		{
			if ($this->isConnected() == false) $this->_logError(ERR_ABDMYSQL_NOT_CONNECTED, 'renameTable'); // Si aucune connexion n'est établie, Erreur.
			$this->makeSafe($oldName); // Protection contre l'SQL Injection.
			$this->makeSafe($newName); // Protection contre l'SQL Injection.
			$request = 'ALTER TABLE `' . $oldName . '` RENAME `' . $newName . '`'; // Construction de la requête.
			$this->query_without_results($request);
		}
		
		public function deleteTable($name)
		{
			if ($this->isConnected() == false) $this->_logError(ERR_ABDMYSQL_NOT_CONNECTED, 'deleteTable'); // Si aucune connexion n'est établie, Erreur.
			$this->makeSafe($name); // Protection contre l'SQL Injection.
			$request = 'DROP TABLE `' . $name . '`'; // Construction de la requête.
			$this->query_without_results($request);
		}
		
		# Vues #
		public function createView($name, $columns, $table)
		{
			if ($this->mysql_version < 5) $this->_logError(ERR_ABDMYSQL_REQUIERE_VERSION_5, 'createView'); // Si la version de MySQL est trop ancienne, Erreur.
			if ($this->isConnected() == false) $this->_logError(ERR_ABDMYSQL_NOT_CONNECTED, 'createView'); // Si aucune connexion n'est établie, Erreur.
			$this->makeSafe($name); // Protection contre l'SQL Injection.
			$this->makeSafe($table); // Protection contre l'SQL Injection.
			$request = 'CREATE VIEW `' . $name . '` AS SELECT ' . $columns . ' FROM `' . $table . '`'; // Construction de la requête.
			$this->query_without_results($request);
		}
		
		public function deleteView($name)
		{
			if ($this->mysql_version < 5) $this->_logError(ERR_ABDMYSQL_REQUIERE_VERSION_5, "deleteView"); // Si la version de MySQL est trop ancienne, Erreur.
			if ($this->isConnected() == false) $this->_logError(ERR_ABDMYSQL_NOT_CONNECTED, "deleteView"); // Si aucune connexion n'est établie, Erreur.
			$this->makeSafe($name); // Protection contre l'SQL Injection.
			$request = 'DROP VIEW `' . $name . '`'; // Construction de la requête.
			$this->query_without_results($request);
		}
		
		# Logs #
		public function activate_errorsLog($filepath, $includeDetails=false, $includeMySQLError=false)
		{
			if ($filepath == '') return ERR_ABDMYSQL_CANNOT_FOUND_FILE; // Si aucun fichier n'est spécifié, Erreur.
			if (!$this->makeLogFile($filepath)) false;
			$this->logErrors = true; // Activation de l'enregistrement des erreurs.
			$this->errorsLogPath = $filepath; // Mémorisation de l'adresse du fichier journal.
			$this->includeDetails = $includeDetails; // Définit si les détails doivent apparaitre dans le fichier journal.
			$this->includeMySQLError = $includeMySQLError; // Définit si le message d'erreur de mysql doit apparaitre dans le fichier journal.
			return true; // Activation réussie.
		}
		
		public function desactivate_errorsLog()
		{
			$this->logErrors = false; // Désactivation de l'enregistrement des erreurs.
			$this->errorsLogPath = ''; // Effacement de l'adresse du fichier journal de la mémoire.
			return true; // Désactivation réussie.
		}
		
		protected function makeLogFile($filepath)
		{
			$document_structure = '<?xml version="1.0" encoding="' . ABDMYSQL_XML_ENCODING . '" ?>'
						. "\n" . '<!-- ' . $this->app_name . ' version ' . $this->app_version . ' -->'
						. "\n\n" . '<ABDMySQL_Errors>' . "\n" . '</ABDMySQL_Errors>' . "\n";
			if (!is_writable($filepath))
			{
				if (file_exists($filepath)) $this->_logError(ERR_ABDMYSQL_CANNOT_WRITE_FILE, "makeFileLog"); // Si le fichier existe mais n'est pas accessible en écriture, Erreur.
				if (file_put_contents($filepath, $document_structure) < 1) return ERR_ABDMYSQL_CANNOT_WRITE_FILE; // Si le fichier n'existe pas et est impossible à créer, Erreur.
			}
			elseif (!filesize($filepath))
			{
				if (file_put_contents($filepath, $document_structure) < 1) return ERR_ABDMYSQL_CANNOT_WRITE_FILE; // Si le fichier n'existe pas et est impossible à créer, Erreur.
			}
		}
		
		protected function _logError($errorcode, $calledFunctionName, $details='')
		{
			if ($this->logErrors !== true || $this->errorsLogPath == '' || !file_exists($this->errorsLogPath) || !is_writable($this->errorsLogPath)) throw new Exception(ERRMSG_ABDMYSQL_UNKNOWN_ERROR, $errorcode); // Si l'enregistrement des erreurs n'est pas activé ou si le fichier journal n'existe pas, déclanchement de l'exception.
			switch ($errorcode)
			{
				case ERR_ABDMYSQL_CANNOT_CONNECT:
					$message = ERRMSG_ABDMYSQL_CANNOT_CONNECT;
					break;
				case ERR_ABDMYSQL_NOT_CONNECTED:
					$message = ERRMSG_ABDMYSQL_NOT_CONNECTED;
					break;
				case ERR_ABDMYSQL_ALREADY_CONNECTED:
					$message = ERRMSG_ABDMYSQL_ALREADY_CONNECTED;
					break;
				case ERR_ABDMYSQL_CANNOT_CARRY_OUT_THE_REQUEST:
					$message = ERRMSG_ABDMYSQL_CANNOT_CARRY_OUT_THE_REQUEST;
					break;
				case ERR_ABDMYSQL_CANNOT_OPEN_FILE:
					$message = ERRMSG_ABDMYSQL_CANNOT_OPEN_FILE;
					break;
				case ERR_ABDMYSQL_CANNOT_WRITE_FILE:
					$message = ERRMSG_ABDMYSQL_CANNOT_WRITE_FILE;
					break;
				case ERR_ABDMYSQL_CANNOT_SELECT_DATABASE:
					$message = ERRMSG_ABDMYSQL_CANNOT_SELECT_DATABASE;
					break;
				case ERR_ABDMYSQL_REQUIERE_VERSION_5:
					$message = ERRMSG_ABDMYSQL_REQUIERE_VERSION_5;
					break;
				case ERR_ABDMYSQL_INCOMPATIBLE_PARAMETERS:
					$message = ERRMSG_ABDMYSQL_INCOMPATIBLE_PARAMETERS;
					break;
				case ERR_ABDMYSQL_CANNOT_OPEN_GZFILE:
					$message = ERRMSG_ABDMYSQL_CANNOT_OPEN_GZFILE;
					break;
				case ERR_ABDMYSQL_CANNOT_WRITE_GZFILE:
					$message = ERRMSG_ABDMYSQL_CANNOT_WRITE_GZFILE;
					break;
				case ERR_ABDMYSQL_INVALID_DATA_FORMAT:
					$message = ERRMSG_ABDMYSQL_INVALID_DATA_FORMAT;
					break;
				case ERR_ABDMYSQL_DATA_MISSING:
					$message = ERRMSG_ABDMYSQL_DATA_MISSING;
					break;
				case ERR_ABDMYSQL_INVALID_DATA:
					$message = ERRMSG_ABDMYSQL_INVALID_DATA;
					break;
				default:
					$message = ERRMSG_ABDMYSQL_UNKNOWN_ERROR;
					break;
			}
			
			$this->makeLogFile($this->errorsLogPath);
			
			$dom = new DomDocument();
			$dom->load($this->errorsLogPath);
			
			$node_error = $dom->createElement("error");
			$node_error->setAttribute("date", $this->xmlEncode(gmdate('D M d H:i:s Y')));
			$node_error->setAttribute("remote_addr", $this->xmlEncode($_SERVER['REMOTE_ADDR']));
			$node_error->setAttribute("called_function", $this->xmlEncode($calledFunctionName));
			$node_error->setAttribute("error_code", $errorcode);
			
			//$message = mb_convert_encoding($message, ABDMYSQL_XML_ENCODING);
			$node_message = $dom->createElement("message", $this->xmlEncode(utf8_encode($message)));//htmlentities(trim($message), ENT_COMPAT, ABDMYSQL_XML_ENCODING));
			
			if ($this->includeDetails == true && trim($details) != '')
			{
				$node_details = $dom->createElement("details", $this->xmlEncode(trim($details)));
			}
			
			if ($this->includeMySQLError == true)
			{
				$node_mysql_error = $dom->createElement("mysql_error", $this->xmlEncode(mysql_error()));
			}
			
			$node_error->appendChild($node_message);
			$node_error->appendChild($node_details);
			$node_error->appendChild($node_mysql_error);
			
			$racine = $dom->getElementsByTagName("ABDMySQL_Errors")->item(0);
			
			$racine->appendChild($node_error);
			
			$dom->save($this->errorsLogPath);
			
			throw new Exception($message, $errorcode); // Enregistrement réussit, déclanchement de l'exception.
		}
				
		# Requêtes #
		public function select($request)
		{
			if ($this->isConnected() == false) $this->_logError(ERR_ABDMYSQL_NOT_CONNECTED, 'select'); // Si aucune connexion n'est établie, Erreur.
			$result = mysql_query($request, $this->mysql_link); // Exécution d'une requête.
			array_push($this->results, $result);
			$this->requestsCount++; // Incrémentation du nombre de requêtes effectuées.
			if (!$result) $this->_logError(ERR_ABDMYSQL_CANNOT_CARRY_OUT_THE_REQUEST, 'select', "Request :'" . $request . "'"); // Si la requête n'a pas été effectuée correctement, Erreur.
			return $result; // Renvoit du résultat de la requête.
		}
		
		public function insert($request)
		{ // Alias
			$this->query_without_results($request);
		}
		
		public function update($request)
		{ // Alias
			$this->query_without_results($request);
		}
		
		public function replace($table, $row, $substring, $replacewith, $condition='')
		{
			if ($this->isConnected() == false) $this->_logError(ERR_ABDMYSQL_NOT_CONNECTED, 'replace'); // Si aucune connexion n'est établie, Erreur.
			$this->makeSafe($table);
			$this->makeSafe($row);
			$this->makeSafe($substring);
			$this->makeSafe($replacewith);
			if ($condition == '') $condition = '1';
			$request = "UPDATE `" . $table . "` SET " . $row . " = REPLACE(" . $row . ", '" . $substring . "', '" . $replacewith . "') WHERE " . $condition;
			$this->query_without_results($request);
		}
		
		public function query_without_results($request)
		{
			if ($this->isConnected() == false) $this->_logError(ERR_ABDMYSQL_NOT_CONNECTED, 'query_whitout_results'); // Si aucune connexion n'est établie, Erreur.
			$result = mysql_unbuffered_query($request, $this->mysql_link); // Exécution d'une requête.
			$this->requestsCount++; // Incrémentation du nombre de requêtes effectuées.
			if (!$result) $this->_logError(ERR_ABDMYSQL_CANNOT_CARRY_OUT_THE_REQUEST, 'query_whitout_results', "Request :'" . $request . "'"); // Si la requête n'a pas été effectuée correctement, Erreur.
		}
		
		public function query($requests, $regexp_separator = '/;\n/m')
		{ // Pour les requêtes multiples. Attention : Renvoit simplement true/false
			if ($this->isConnected() == false) $this->_logError(ERR_ABDMYSQL_NOT_CONNECTED, 'query'); // Si aucune connexion n'est établie, Erreur.
			
			// Suppression des lignes commençants par le caractère '#' signalant un commentaire ;
			$lines = preg_replace('/^(\#(.*))$/m', '', $requests);
			
			// Séparation des requêtes ligne par ligne :
			$lines = preg_split($regexp_separator, $lines, -1, PREG_SPLIT_NO_EMPTY);
			
			// Pour chaque requête (ligne) :
			foreach ($lines as $nothing => $line)
			{
				$line = trim($line);
				if ($line == '') continue; // Si la ligne est vide, on continue la boucle.
				$result = mysql_unbuffered_query($line, $this->mysql_link); // Exécution d'une requête.
				if (!$result) $this->_logError(ERR_ABDMYSQL_CANNOT_CARRY_OUT_THE_REQUEST, 'query', "Line: '" . $line . "'"); // Si la requête n'a pas été effectuée correctement, Erreur.
				$this->freeResult($result);
				$this->requestsCount++; // Incrémentation du nombre de requêtes effectuées.
			}
		}
		
		public function delete($table, $condition="")
		{
			if ($this->isConnected() == false) $this->_logError(ERR_ABDMYSQL_NOT_CONNECTED, 'delete'); // Si aucune connexion n'est établie, Erreur.
			$this->makeSafe($table); // Protection contre l'SQL Injection.
			$request = 'DELETE FROM `' . $table . '`'; // Construction de la requête (1 sur 2).
			if ($condition != '') $request .= ' WHERE ' . $condition; // Construction de la requête (2 sur 2).
			$result = mysql_query($request, $this->mysql_link); // Exécution d'une requête.
			$this->requestsCount++; // Incrémentation du nombre de requêtes effectuées.
			if (!$result) $this->_logError(ERR_ABDMYSQL_CANNOT_CARRY_OUT_THE_REQUEST, 'delete', "Request :'" . $request . "'"); // Si la requête n'a pas été effectuée correctement, Erreur.
		}
		
		public function rowsCount($table, $condition='')
		{
			if ($this->isConnected() == false) $this->_logError(ERR_ABDMYSQL_NOT_CONNECTED, 'rowsCount'); // Si aucune connexion n'est établie, Erreur.
			$this->makeSafe($table); // Protection contre l'SQL Injection.
			$request = 'SELECT COUNT( * ) FROM `' . $table . '`'; // Construction de la requête (1 sur 2).
			if (trim($condition)!="") $request .= ' WHERE ' . $condition; // Construction de la requête (2 sur 2).
			$result = mysql_query($request, $this->mysql_link); // Exécution d'une requête.
			$this->requestsCount++; // Incrémentation du nombre de requêtes effectuées.
			if (!$result) $this->_logError(ERR_ABDMYSQL_CANNOT_CARRY_OUT_THE_REQUEST, 'rowsCount', "Request :'" . $request . "'"); // Si la requête n'a pas été effectuée correctement, Erreur.
			$resultat = mysql_fetch_row($result);
			$this->freeResult($result);
			return $resultat[0];
		}
		
		# Traitement des ressources #
		public function isMySQLResource($resource)
		{
			if (is_resource($resource) && (get_resource_type($resource) == 'mysql result')) return true;
			else return false;
		}
		
		public function fetchAll($result, $resultType = MYSQL_ASSOC)
		{
			if (!$this->isMySQLResource($result)) $this->logError(ERR_ABDMYSQL_INVALID_DATA_FORMAT, 'fetchAll');
			if ($resultType !== MYSQL_ASSOC && $resultType !== MYSQL_NUM && $resultType !== MYSQL_BOTH) $this->logError(ERR_ABDMYSQL_INVALID_DATA, 'fetchAll');
			$tableau = array();
			if ($this->resultsCount($result) < 1) return $tableau;
			mysql_data_seek($result, 0);
			while ($tuple = mysql_fetch_array($result, $resultType))
			{
				array_push($tableau, $tuple);
			}
			return $tableau;
		}
		
		public function freeResult($result)
		{
			if ($this->isMySQLResource($result)) mysql_free_result($result);
		}
		
		public function freeResults()
		{
			$argsCount = func_num_args();
			if ($argsCount < 1) $this->logError(ERR_ABDMYSQL_DATA_MISSING, 'freeResults');
			$argsList = func_get_args();
			for ($i = 0; $i < $argsCount; $i++)
			{
				if ($this->isMySQLResource($argsList[$i])) mysql_free_result($argsList[$i]);
			}
		}
		
		public function resultsCount($result)
		{
			if (!$result) $this->logError(ERR_ABDMYSQL_INVALID_DATA_FORMAT, 'resultsCount');
			return mysql_num_rows($result);
		}
		
		# Backups #
		public function saveCurrentDatabaseStruct_SQL($auto_increment = false, $output_file = '', $append = false, $compressed = false)
		{
			if ($this->isConnected() == false) $this->_logError(ERR_ABDMYSQL_NOT_CONNECTED, 'saveCurrentDatabaseStruct_SQL'); // Si aucune connexion n'est établie, Erreur.
			$resultat =   '# ' . "\n"
						. '# ' . $this->app_name . "\n"
						. '# Version ' . $this->app_version . "\n"
						. '# ' . "\n"
						. '# Exportation de la structure de la base de données sous forme de requêtes SQL' . "\n"
						. '# ' . "\n"
						. '# Fait le ' . gmdate('d/m/Y à H:i:s') . "\n"
						. '# ' . "\n"
						. '# Base de données : `' . $this->database . '`' . "\n"
						. '# ' . "\n\n";
			$tablesList = $this->getTablesList();
			foreach ($tablesList as $nothing => $table)
			{
				$table_struct = $this->getTableStruct($table);
				$resultat .= 'CREATE TABLE `' . $table . "` (\n";
				foreach ($table_struct['columns'] as $column_name => $column_params)
				{
					$resultat .= '`' . $column_name . '` ' . $column_params['Type'] . ' ';
					if ($column_params['Null'] == false) $resultat .= 'NOT ';
					$resultat .= 'NULL ';
					if ($column_params['AutoIncrement'] == true) $resultat .= 'AUTO_INCREMENT ';
					$resultat .= ",\n";
				}
				if (count($table_struct['config']['PrimaryKey']) > 0)
				{
					$resultat .= 'PRIMARY KEY ( ';
					$spacer = '';
					foreach ($table_struct['config']['PrimaryKey'] as $nothing => $column_name)
					{
						$resultat .= $spacer . '`' . $column_name . '`';
						$spacer = ', ';
					}
					$resultat .= " ) ,\n";
				}
				if (count($table_struct['config']['FullText']) > 0)
				{
					$resultat .= 'FULLTEXT KEY ( ';
					$spacer = '';
					foreach ($table_struct['config']['FullText'] as $nothing => $column_name)
					{
						$resultat .= $spacer . '`' . $column_name . '`';
						$spacer = ', ';
					}
					$resultat .= " )\n";
				}
				$resultat .= ') ENGINE=' . $table_struct['config']['Engine'];
				if ($auto_increment == true && isset($table_struct['config']['AutoIncrement'])) $resultat .= ' AUTO_INCREMENT=' . $table_struct['config']['AutoIncrement'];
				$resultat .= ";\n\n";
			}
			if ($output_file!='')
			{
				$this->saveData('saveCurrentDatabaseStruct_SQL', $output_file, $resultat, $append, $compressed);
			} else return $resultat;
		}
		
		public function saveCurrentDatabaseData_SQL($output_file='', $append=false, $compressed=false)
		{
			if ($this->isConnected() == false) $this->_logError(ERR_ABDMYSQL_NOT_CONNECTED, 'saveCurrentDatabaseData_SQL'); // Si aucune connexion n'est établie, Erreur.
			$resultat =   '# ' . "\n"
						. '# ' . $this->app_name . "\n"
						. '# Version ' . $this->app_version . "\n"
						. '# ' . "\n"
						. '# Exportation du contenu de la base de données sous forme de requêtes SQL' . "\n"
						. '# ' . "\n"
						. '# Fait le ' . gmdate('d/m/Y à H:i:s') . "\n"
						. '# ' . "\n"
						. '# Base de données : `' . $this->database . '`' . "\n"
						. '# ' . "\n\n";
			$tablesList = $this->getTablesList();
			foreach ($tablesList as $nothing => $table)
			{
				$fulltable = $this->getFullTable($table);
				if (count($fulltable['content']) > 0)
				{
					$spacer = '';
					$spacer_lines = '';
					$resultat .= 'INSERT INTO `' . $table . '` (';
					$columns = $this->getTableStruct($table);
					foreach ($columns['columns'] as $column_name => $nothing)
					{
						$resultat .= $spacer . '`' . $column_name . '`';
						$spacer = ', ';
					}
					$spacer = '';
					$resultat .= ") VALUES \n";
					
					foreach ($fulltable['content'] as $nothing => $line)
					{
						$resultat .= $spacer_lines . '(';
						$spacer = '';
						foreach ($line as $nothing => $column_value)
						{
							$resultat .= $spacer;
							if (is_numeric($column_value)) $resultat .= $column_value;
							else $resultat .= "'" . $this->makeSafe($column_value) . "'";
							$spacer = ', ';
						}
						$resultat .= ')';
						$spacer_lines = ",\n";
					}
					$resultat .= ";\n\n";
				}
			}
			if ($output_file!='')
			{
				$this->saveData('saveCurrentDatabaseData_SQL', $output_file, $resultat, $append, $compressed);
			} else return $resultat;
		}
				
		public function saveCurrentDatabaseData_XML($output_file='', $append=false, $compressed=false)
		{
			if ($this->isConnected() == false) $this->_logError(ERR_ABDMYSQL_NOT_CONNECTED, 'saveCurrentDatabaseData_XML'); // Si aucune connexion n'est établie, Erreur.
			$resultat =   '<!-- ' . "\n"
						. '- ' . $this->app_name . "\n"
						. '- Version ' . $this->app_version . "\n"
						. '- ' . "\n"
						. '- Exportation du contenu de la base de données au format XML' . "\n"
						. '- ' . "\n"
						. '- Fait le ' . gmdate('d/m/Y à H:i:s') . "\n"
						. '- ' . "\n"
						. '- Base de données : `' . $this->database . '`' . "\n"
						. '-->' . "\n\n";
			
			$resultat .= '<' . htmlspecialchars($this->database) . '>' . "\n";
			$tablesList = $this->getTablesList();
			foreach ($tablesList as $nothing => $table)
			{
				$tableData = $this->getTableData($table);
				$resultat .= '    <!-- ' . htmlspecialchars($table) . ' -->' . "\n";
				if (count($tableData) > 0)
				{
					foreach ($tableData as $nothing => $line)
					{
						$resultat .= '    <' . htmlspecialchars($table) . '>' . "\n";
						foreach ($line as $column_name => $column_value)
						{
							$resultat 	.= '        <' . htmlspecialchars($column_name) . '>'
										. htmlspecialchars($column_value)
										. '</' . htmlspecialchars($column_name) . '>' . "\n";
						}
						$resultat .= '    </' . htmlspecialchars($table) . '>' . "\n";
					}
					$resultat .= "\n";
				}
			}
			$resultat .= '</' . htmlspecialchars($this->database) . '>' . "\n";
			if ($output_file!='')
			{
				$this->saveData('saveCurrentDatabaseData_XML', $output_file, $resultat, $append, $compressed);
			} else return $resultat;
		}
		
		protected function saveData($calledFunctionName, $output_file, $content, $append=false, $compressed=false)
		{
			if ($append==true && $compressed==true) $this->_logError(ERR_ABDMYSQL_INCOMPATIBLE_PARAMETERS, $calledFunctionName . '->saveData', 'append=true AND compressed=true'); // Si deux paramètres sont incompatibles, Erreur.
			if ($compressed==false) 
			{
				if ($append==true) $open_param = 'a';
				else $open_param = 'w';
				if (!$handle = fopen($output_file, $open_param)) $this->_logError(ERR_ABDMYSQL_CANNOT_OPEN_FILE, $calledFunctionName . '->saveData', 'File Path: \'' . $output_file . "'"); // Si l'ouverture du fichier a échouée, Erreur.
				if (fwrite($handle, $content) === false)
				{
					fclose($handle);
					$this->_logError(ERR_ABDMYSQL_CANNOT_WRITE_FILE, $calledFunctionName . '->saveData', "File Path: '".$output_file . "'");
				}
				fclose($handle);
			}
			else
			{
				if (!$handle = gzopen($output_file, 'wb9')) $this->_logError(ERR_ABDMYSQL_CANNOT_OPEN_GZFILE, $calledFunctionName . '->saveData', "File Path: '".$output_file . "'"); // Si l'ouverture du fichier a échouée, Erreur.
				if (gzwrite($handle, $content) === false)
				{
					fclose($handle);
					$this->_logError(ERR_ABDMYSQL_CANNOT_WRITE_GZFILE, $calledFunctionName . '->saveData', "File Path: '".$output_file . "'");
				}
				gzclose($handle);
			}
		}
	}
}
?>

Conclusion :


Si vous utilisez cette application, merci de me contacter par courrier électronique à l'adresse citée plus haut.
Si vous avez des suggestions, n'hésitez surtout pas. C'est comme ça que nous pourrons, ensemble, faire évoluer cette application.

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

Messages postés
240
Date d'inscription
vendredi 14 juin 2002
Statut
Membre
Dernière intervention
17 mars 2009

Ah j'ai oublié de le dire dans le commentaire : j'ai ajouté un petit fichier d'exemple d'utilisation.
Messages postés
240
Date d'inscription
vendredi 14 juin 2002
Statut
Membre
Dernière intervention
17 mars 2009

Quelqu'un aurait des idées d'amélioration ? Je voudrais en faire une classe vraiment complète et qui puisse être utilisée par un maximum d'applications.
Messages postés
240
Date d'inscription
vendredi 14 juin 2002
Statut
Membre
Dernière intervention
17 mars 2009

Grande mise à jour : Possibilitié de faire un backup de la base de données !!! :D
Messages postés
240
Date d'inscription
vendredi 14 juin 2002
Statut
Membre
Dernière intervention
17 mars 2009

Pour deux raisons. La première est qu'il faut faire la différence entre les requêtes qui renvoient des résultats et les autres. La deuxième est que CMySQL::query est programmée pour exécuter plusieurs requêtes à la suite. Elle prend donc plus de temps à l'exécution. Quelques millisecondes, c'est ridicule, mais à grande échelle, ça se fait sentir...

:)
Messages postés
455
Date d'inscription
mardi 17 septembre 2002
Statut
Membre
Dernière intervention
22 juillet 2007

Pourquoi ne pas appeler $this->query à chaque fois que tu fais une requête, plutôt que de faire à chaque fois :
- mysql_query();
- $nbrequetes++;
- if (!$result) _errorlog();

Je me trompe peut-être, mais j'imagine que ça serait plus simple non ?
Afficher les 19 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.