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

Soyez le premier à donner votre avis sur cette source.

Vue 7 206 fois - Téléchargée 703 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

cs_wizad
Messages postés
356
Date d'inscription
samedi 30 octobre 2004
Statut
Membre
Dernière intervention
14 avril 2009
-
Une grande question me taraude... avec leur nouvelle loi il semble que pour diffuser tout contenu (gratuit ou payant) il faut préalablement le déposer (brevet)... on fait quoi maintenant?

Sinon un petit screen peut être sympa. Je zieute le code et le fonctionnement ce soir.
cs_Anthomicro
Messages postés
9433
Date d'inscription
mardi 9 octobre 2001
Statut
Membre
Dernière intervention
13 avril 2007
8 -
Salut :)

Je trouve ta classe pas mal, ça innove un peu des autres plus basiques basées généralement sur de la redéfinition de méthodes (mon ancienne classe n'y fait pas exception). Seul problème à mon avis : sa lourdeur.

Dommage qu'il n'y ait pas de surcharge de constructeur en PHP4, car perso je n'aime pas avoir à foutre les paramètres sur chaque page, en effet si tu dois faire ça, faut soit indiquer les paramètres en clair sur chaque page (ce qui est barbant niveau portabilité dès que tu changes d'hébergeur) soit passer par un fichier de conf que tu vas inclure sur chaque page, code supplémentaire et perte de perfs au final donc :-(

Sinon la gestion des erreurs n'est pas encore assez complète (genre tu pourrais logguer ça en fonction d'un attribut qui prendrait la valeur true ou false suivant que tu souhaites débugger ou pas par exemple).

Je mets 7/10 pour le moment ;)

a +
psykocrash
Messages postés
244
Date d'inscription
vendredi 14 juin 2002
Statut
Membre
Dernière intervention
17 mars 2009
-
Anthomicro, tu pourrais m'expliquer plus en détail en quoi ma classe est lourde ? et aussi qu'est ce que tu voudrais que je fasse d'une surcharge de constructeur ?
Pour ce qui est d'enregistrer les logs d'erreurs je vais l'ajouter, ça me semble intéressant :)
cs_wizad
Messages postés
356
Date d'inscription
samedi 30 octobre 2004
Statut
Membre
Dernière intervention
14 avril 2009
-
désolé pour la demande de screen étant mal réveillé ce atin j'ai même pas tilté sur le mot classe.

Sinon je ne voix pas l'intérêt de certains éléments (insert(request))... pour moi de bonnes idées mais inachevé.

Petite suggestion : la passage par un classe d'abstraction aurait été un plus (permettant par exemple d'avoir plusieur base supporté)
psykocrash
Messages postés
244
Date d'inscription
vendredi 14 juin 2002
Statut
Membre
Dernière intervention
17 mars 2009
-
Salut,

@Wizad : J'ai mis ces fonctions par soucis de clareté de code. A chaque fois qu'on attaque un gros projet, on se trouve obligé de stocker des requêtes préfaites, et on se retrouve avec des mysql_query($request, $link); sans savoir de quel type de requête il s'agit, et là c'est pas gagné pour celui qui veux débugger le code. Dans ma classe, on sait au moins de quel type de requête il est question, c'est au moins ça de gagné.
Sinon tu peux m'expliquer un peut plus ce "passage par une classe d'abstraction" stp ? Je sais pas comment ça marche, et si ça peux améliorer ma classe, alors je suis preneur :)

@Anthomicro : Pour les logs, c'est fait (mais pas encore testé). Comment tu voudrais qu'on gère les paramètres ?


Merci pour vos idées les gars :)

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.