<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Blogue de Pierre-Luc Babin &#187; database</title>
	<atom:link href="http://www.plbabin.com/category/database/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.plbabin.com</link>
	<description>PHP et bien plus encore...</description>
	<lastBuildDate>Mon, 01 Dec 2008 22:48:13 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Une classe Database</title>
		<link>http://www.plbabin.com/2008/05/une-classe-database/</link>
		<comments>http://www.plbabin.com/2008/05/une-classe-database/#comments</comments>
		<pubDate>Fri, 02 May 2008 19:39:46 +0000</pubDate>
		<dc:creator>Pierre-Luc Babin</dc:creator>
				<category><![CDATA[Codes utiles]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[classe]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://phpblog.plbabin.com/?p=71</guid>
		<description><![CDATA[Pour avoir une programmation plus clair et efficace il est recommandé d&#8217;utiliser la programmation orienté objets. L&#8217;avantage est d&#8217;éviter le dédoublement de code, mais surtout de ce facilité la vie lorsqu&#8217;un changement drastique survient à notre code. Comme dans le cas d&#8217;une base de données.
La base de donnée est la pièce maitresse d&#8217;un gros site [...]]]></description>
			<content:encoded><![CDATA[<p>Pour avoir une programmation plus clair et efficace il est recommandé d&#8217;utiliser la programmation orienté objets. L&#8217;avantage est d&#8217;éviter le dédoublement de code, mais surtout de ce facilité la vie lorsqu&#8217;un changement drastique survient à notre code. Comme dans le cas d&#8217;une base de données.</p>
<p>La base de donnée est la pièce maitresse d&#8217;un gros site web. La plus souvent utilisé avec le PHP est MySQL, mais il existe d&#8217;autre type de base de donnée comme par exemple PostGre SQL ou bien SQL Lite. Le choix d&#8217;une BD est habituellement effectué avant même le début de développement. Mais il arrive que l&#8217;on doit changer le type de BD rapidement en plein milieu du projet, d&#8217;où l&#8217;importance de centraliser les actions à la BD dans une classe. Voici donc la classe de BD que j&#8217;utilise pour mes sites web avec quelques explications. Le code de base est tiré du livre Advanced PHP Programming.</p>
<blockquote><p>Pour ceux qui ne sont pas à l&#8217;aise avec la POO, je vous réfère pour le moment sur <a title="Site Du Zéro - La programmation orienté objet en php" href="http://www.siteduzero.com/tuto-3-1678-0-la-programmation-orientee-objet-en-php.html">un tutoriel du SiteDuZero</a></p></blockquote>
<p>On commence tout d&#8217;abord a créer les variables de notre classe.</p>
<pre><code class="php">
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
}
</code></pre>
<p>Un petit peu d&#8217;explication sur le code. Ces variables seront accessibles par le mot clé <strong>$this</strong> dans toutes les fonctions. Le mot clé <em>protected</em> signifie que la variable sera accessible par toutes les classes en liens avec la classe  DB_Mysql de l&#8217;intérieur seulement.</p>
<p>Ensuite nous devons utiliser une petit classe qui contiendra notre informations de BD.</p>
<pre><code class="php">
class DB_Mysql_Home extends DB_Mysql {
 protected $user   = 'root';
 protected $pass   = '';
 protected $dbname = 'mabd';
 protected $dbhost = 'localhost';

public function __construct() { }
</code>
}</pre>
<p>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.</p>
<p>Nous créons ensuite la fonction pour la connexion à la bd.</p>
<pre><code class="php">
private function connect()
	{
		$this-&gt;dbh = @mysql_connect($this-&gt;dbhost,$this-&gt;user,$this-&gt;pass);
		//si la connexion a échoué
		if(!is_resource($this-&gt;dbh)) {
			exit('Impossible de se connecter');
		}
		//si la sélection de table a échoucé
		$ret = mysql_select_db($this-&gt;dbname,$this-&gt;dbh);
		if(!$ret) {
			exit('Impossible de sélectionner la table sql');
		}
	}
</code></pre>
<p>Fonction relativement simple. Ce n&#8217;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.</p>
<pre><code class="php">
public function execute($query)
	{
		if(!$this-&gt;dbh) {
			$this-&gt;connect();
		}
		$ret = mysql_query($query, $this-&gt;dbh);
		$this-&gt;cpt_query++;
		if(!$ret) {
			exit('Erreur de requête : '.mysql_error());
		}
		else if(!is_resource($ret)) {
			return TRUE;
		} else {
			$stmt = new DB_MysqlStatement($this-&gt;dbh, $query);
			$stmt-&gt;result = $ret;
			return $stmt;
		}
	}
</code></pre>
<p>Quelques explications. Tout d&#8217;abord on vérifie si la connexion existe, si ce n&#8217;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 <em>mysql_query</em> qui nous retourne une ressource si tout c&#8217;est bien passé. Si notre variable n&#8217;est pas valide nous quittons le programme, sinon la variable doit être une ressource.</p>
<p>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&#8217;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&#8217;objet de la classe.</p>
<p>Ne reste plus ensuite qu&#8217;appeler les fonctions nécessaire pour extraire les données de l&#8217;objet SQL. Voici le code de le dernière classe.</p>
<pre><code class="php">
class DB_MysqlStatement{
	public $result;
	public $query;
	public $dbh;
	public $binds;

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

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

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

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

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

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

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

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

}
</code></pre>
<p>Tout d&#8217;abord, le constructeur déclenché lors de l&#8217;instanciation de la classe lors de l&#8217;exécution de la requête. La fonction est relativement simple alors qu&#8217;il n&#8217;y a qu&#8217;une simple validation pour s&#8217;assurer que la connexion est valide.<br />
Ensuite on retrouve les fonctions de base d&#8217;un driver de base de donnée comme Mysql. Il y a les fonctions pour recevoir les informations de la requête comme <em>fetch_row</em>, <em>fetch_assoc</em> ou bien <em>fetch_array</em>. Ensuite des fonctions utile comme <em>data_seek</em> qui permet de déplacer le pointeur dans un objet de requête ou bien <em>num_rows</em> qui compte le nombre de résultats dans votre requête.</p>
<blockquote class="explications"><p>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 <em>mysql_fetch_array</em> sans vraiment connaître sont impacte. Les deux autres fonctions semblables sont <em>mysql_fetch_assoc</em>, <em>mysql_fetch_object</em> et <em>mysql_fetch_row</em>. La première fonction (<em>mysql_fetch_array</em>) retourne un tableau avec des clés numérique et associatives, tandis que la fonction <em>mysql_fetch_assoc</em> retourne des clés associatives seulement alors que <em>mysql_fetch_row</em> fait l&#8217;inverse. Autrement dit, quand vous utilisez <em>mysql_fetch_array</em>, 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 <em>mysql_fetch_array</em>:</p>
<pre>Array
(
[id] =&gt; 1
[0] =&gt; 1
[nom] =&gt; Pierre-Luc
[1] =&gt; Pierre-Luc
)</pre>
<p>En voici un autre retourner par <em>mysql_fetch_assoc</em></p>
<pre>Array
(
[id] =&gt; 1
[nom] =&gt; Pierre-Luc
)</pre>
</blockquote>
<p>Pour conclure sur le code de la classe, elle laisse place a encore beaucoup d&#8217;amélioration. On pourrait ajouté une fonction qui prépare chaque variable avant de l&#8217;inclure dans la requête. Cela permettrait d&#8217;analyser les variables pour éviter les injections SQL. Si vous avez des questions, n&#8217;hésitez pas!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.plbabin.com/2008/05/une-classe-database/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
