Pour avoir une programmation plus clair et efficace il est recommandé d’utiliser la programmation orienté objets. L’avantage est d’éviter le dédoublement de code, mais surtout de ce facilité la vie lorsqu’un changement drastique survient à notre code. Comme dans le cas d’une base de données.

La base de donnée est la pièce maitresse d’un gros site web. La plus souvent utilisé avec le PHP est MySQL, mais il existe d’autre type de base de donnée comme par exemple PostGre SQL ou bien SQL Lite. Le choix d’une BD est habituellement effectué avant même le début de développement. Mais il arrive que l’on doit changer le type de BD rapidement en plein milieu du projet, d’où l’importance de centraliser les actions à la BD dans une classe. Voici donc la classe de BD que j’utilise pour mes sites web avec quelques explications. Le code de base est tiré du livre Advanced PHP Programming.

Pour ceux qui ne sont pas à l’aise avec la POO, je vous réfère pour le moment sur un tutoriel du SiteDuZero

On commence tout d’abord a créer les variables de notre classe.


class DB_Mysql{
 protected $user; //utilisateur de la bd
 protected $pass; //mot de passe de la bd
 protected $dbhost; //adresse de la bd, souvent localhost
 protected $dbname; //nom de la db
 protected $dbh; //Connection handle
 protected $cpt_query=0; //compteur de requête
}

Un petit peu d’explication sur le code. Ces variables seront accessibles par le mot clé $this dans toutes les fonctions. Le mot clé protected signifie que la variable sera accessible par toutes les classes en liens avec la classe DB_Mysql de l’intérieur seulement.

Ensuite nous devons utiliser une petit classe qui contiendra notre informations de BD.


class DB_Mysql_Home extends DB_Mysql {
 protected $user   = 'root';
 protected $pass   = '';
 protected $dbname = 'mabd';
 protected $dbhost = 'localhost';

public function __construct() { }

}

La classe DB_Mysql étant une extension de la classe DB_Mysql_Home se retrouve automatiquement avec les informations entrée dans les variable profitant ainsi que la relation parent-enfant de la classe.

Nous créons ensuite la fonction pour la connexion à la bd.


private function connect()
	{
		$this->dbh = @mysql_connect($this->dbhost,$this->user,$this->pass);
		//si la connexion a échoué
		if(!is_resource($this->dbh)) {
			exit('Impossible de se connecter');
		}
		//si la sélection de table a échoucé
		$ret = mysql_select_db($this->dbname,$this->dbh);
		if(!$ret) {
			exit('Impossible de sélectionner la table sql');
		}
	}

Fonction relativement simple. Ce n’est que des fonctions de Mysql très simpliste. La prochain fonction est la plus importante de la classe, soit celle pour éxécuter des requêtes.


public function execute($query)
	{
		if(!$this->dbh) {
			$this->connect();
		}
		$ret = mysql_query($query, $this->dbh);
		$this->cpt_query++;
		if(!$ret) {
			exit('Erreur de requête : '.mysql_error());
		}
		else if(!is_resource($ret)) {
			return TRUE;
		} else {
			$stmt = new DB_MysqlStatement($this->dbh, $query);
			$stmt->result = $ret;
			return $stmt;
		}
	}

Quelques explications. Tout d’abord on vérifie si la connexion existe, si ce n’est pas le cas, nous la créons. Cela évite de créer la connexion si aucune requête ne sera exécuter dans la page. Ensuite nous effectuons la requête grâce à la fonction mysql_query qui nous retourne une ressource si tout c’est bien passé. Si notre variable n’est pas valide nous quittons le programme, sinon la variable doit être une ressource.

Si tout est exécuter sans problème, on peut donc instancier notre deuxième classe qui elle gère les ressource SQL. Pourquoi une deuxième classe, parce qu’elle nous permettra de continuer à travailler en objet. Donc nous envoyons à DB_MysqlStatement le handle de la connexion ainsi que la ressource de la requête et nous retournons ensuite l’objet de la classe.

Ne reste plus ensuite qu’appeler les fonctions nécessaire pour extraire les données de l’objet SQL. Voici le code de le dernière classe.


class DB_MysqlStatement{
	public $result;
	public $query;
	public $dbh;
	public $binds;

	public function __construct($dbh, $query)
	{
		$this->query = $query;
		$this->dbh = $dbh;
		if(!is_resource($dbh)) {
			exit("N'est pas une connexion valide");
		}
	}

	public function fetch_row()
	{
		return mysql_fetch_row($this->result);
	}

	public function fetch_assoc()
	{
		if(!$this->result) {
			exit("La requête n'a pas été exécuté");
		}
		return mysql_fetch_assoc($this->result);
	}

	public function data_seek($pointeur){
		return mysql_data_seek($this->result,$pointeur);
	}

	public function fetch_fetchall_assoc()
	{
		$retval = array();
		while($row = $this->fetch_assoc()) {
			$retval[] = $row;
		}
		return $retval;
	}

	public function num_rows(){
		return mysql_num_rows($this->result);
	}

	public function fetch_array(){
		return mysql_fetch_array($this->result);
	}

	public function fetch_object(){
		return mysql_fetch_object($this->result);
	}

}

Tout d’abord, le constructeur déclenché lors de l’instanciation de la classe lors de l’exécution de la requête. La fonction est relativement simple alors qu’il n’y a qu’une simple validation pour s’assurer que la connexion est valide.
Ensuite on retrouve les fonctions de base d’un driver de base de donnée comme Mysql. Il y a les fonctions pour recevoir les informations de la requête comme fetch_row, fetch_assoc ou bien fetch_array. Ensuite des fonctions utile comme data_seek qui permet de déplacer le pointeur dans un objet de requête ou bien num_rows qui compte le nombre de résultats dans votre requête.

Les différences entre les fonctions de mysql ou autre système de base de données sont minimes mais tellement importante à connaitre. La plupart des programmeurs php lros de leur début utilisent la fonction mysql_fetch_array sans vraiment connaître sont impacte. Les deux autres fonctions semblables sont mysql_fetch_assoc, mysql_fetch_object et mysql_fetch_row. La première fonction (mysql_fetch_array) retourne un tableau avec des clés numérique et associatives, tandis que la fonction mysql_fetch_assoc retourne des clés associatives seulement alors que mysql_fetch_row fait l’inverse. Autrement dit, quand vous utilisez mysql_fetch_array, vous utilise des tableaux deux fois plus gros, qui vous duplique chaque donnée. Voici un exemple de ce que donne un tableau retourner par mysql_fetch_array:

Array
(
[id] => 1
[0] => 1
[nom] => Pierre-Luc
[1] => Pierre-Luc
)

En voici un autre retourner par mysql_fetch_assoc

Array
(
[id] => 1
[nom] => Pierre-Luc
)

Pour conclure sur le code de la classe, elle laisse place a encore beaucoup d’amélioration. On pourrait ajouté une fonction qui prépare chaque variable avant de l’inclure dans la requête. Cela permettrait d’analyser les variables pour éviter les injections SQL. Si vous avez des questions, n’hésitez pas!

Partagez cette article: Ces icônes sont des liens vers des sites de partage de signet sociaux où les lecteurs peuvent partager et découvrir de nouveaux liens.
  • Digg
  • Facebook
  • del.icio.us
  • Google
  • Live
  • Pownce
  • Wikio FR
  • Mixx
  • Sphinn
  • StumbleUpon

Ajouter mon fil RSS à votre agrégateur de contenu préféré.