<?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>CoolCoyote.net &#187; PHP &#8211; MySQL</title>
	<atom:link href="http://www.coolcoyote.net/category/php-mysql/feed" rel="self" type="application/rss+xml" />
	<link>http://www.coolcoyote.net</link>
	<description>Coding - Linux</description>
	<lastBuildDate>Sun, 07 Nov 2010 15:27:34 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>fr</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Installer Eclipse et PDT séparément sur Windows</title>
		<link>http://www.coolcoyote.net/php-mysql/installer-eclipse-et-pdt-separement-sur-windows</link>
		<comments>http://www.coolcoyote.net/php-mysql/installer-eclipse-et-pdt-separement-sur-windows#comments</comments>
		<pubDate>Sun, 07 Nov 2010 15:27:03 +0000</pubDate>
		<dc:creator>Denis S.</dc:creator>
				<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[PHP - MySQL]]></category>
		<category><![CDATA[pdt]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.coolcoyote.net/?p=368</guid>
		<description><![CDATA[Si vous ne voulez pas utiliser Eclipse uniquement pour faire du PHP, mieux vaut installer la version classique d&#8217;Eclipse, puis d&#8217;installer PDT (PHP Development Tool) séparément.
En ce qui me concerne j&#8217;ai commencé par télécharger la version &#171;&#160;Classic&#160;&#187; d&#8217;Eclipse que l&#8217;on peut trouver sur cette page. A l&#8217;heure où j&#8217;écris ces lignes il s&#8217;agit de Eclipse [...]]]></description>
			<content:encoded><![CDATA[<p>Si vous ne voulez pas utiliser Eclipse uniquement pour faire du PHP, mieux vaut installer la version classique d&#8217;Eclipse, puis d&#8217;installer PDT (PHP Development Tool) séparément.</p>
<p>En ce qui me concerne j&#8217;ai commencé par télécharger la version &laquo;&nbsp;Classic&nbsp;&raquo; d&#8217;Eclipse que l&#8217;on peut trouver sur <a href="http://www.eclipse.org/downloads/" target="_blank">cette page</a>. A l&#8217;heure où j&#8217;écris ces lignes il s&#8217;agit de <strong>Eclipse Classic 3.6.1</strong>. Téléchargez le zip en fonction de votre système (32 ou 64 bits). Dézippez ensuite votre fichier dans le répertoire <strong>Program Files</strong>. Vous obtenez un répertoire <strong>eclipse</strong>. Entre-y et faites un raccourcit de <strong>eclipse.exe</strong> vers le bureau par exemple.</p>
<p><span id="more-368"></span></p>
<p>Lancez Eclipse. On vous demande de choisir votre <strong>Workspace</strong>. De ce que j&#8217;ai lu, il est préférable pour des raisons de performances de choisir un espace de travail à la racine de votre <strong>C:</strong>. J&#8217;ai donc choisis <strong>C:\workspace</strong>, et j&#8217;ai coché la case pour l&#8217;utiliser par défaut.</p>
<p>Une fois dans Eclipse, aller dans le menu <strong>Help / Install New Software</strong>. Dans l&#8217;espace <strong>Work with</strong>, cliquer sur <strong>Add&#8230;</strong></p>
<p><a href="http://www.coolcoyote.net/wp-content/uploads/2010/11/Eclipse001.jpg"><img class="aligncenter size-full wp-image-373" title="Eclipse001" src="http://www.coolcoyote.net/wp-content/uploads/2010/11/Eclipse001.jpg" alt="" width="737" height="269" /></a></p>
<p>Dans la nouvelle fenêtre tapez <strong>Eclipse </strong>dans le champ name, et l&#8217;url <strong>http://download.eclipse.org/releases/helios/</strong> dans le champ <strong>Location </strong>et validez.</p>
<p><a href="http://www.coolcoyote.net/wp-content/uploads/2010/11/Eclipse002.jpg"><img class="aligncenter size-full wp-image-374" title="Eclipse002" src="http://www.coolcoyote.net/wp-content/uploads/2010/11/Eclipse002.jpg" alt="" width="489" height="188" /></a></p>
<p>Après quelques instants, la liste des logiciels téléchargeables apparaît. Dans <strong>Programming Languages</strong>, choisir <strong>PDT</strong> et cliquez sur <strong>Next</strong>, puis <strong>Next </strong>à nouveau.</p>
<p><a href="http://www.coolcoyote.net/wp-content/uploads/2010/11/Eclipse003.jpg"><img class="aligncenter size-full wp-image-376" title="Eclipse003" src="http://www.coolcoyote.net/wp-content/uploads/2010/11/Eclipse003.jpg" alt="" width="520" height="239" /></a></p>
<p>Acceptez les conditions et enfin <strong>Finish</strong>. Le chargement de <strong>PDT </strong>commence. Ça peut prendre plusieurs minutes. A la fin de l&#8217;installation, redémarrez Eclipse.</p>
<p>source de l&#8217;article: <a href="http://wiki.eclipse.org/PDT/Installation#Eclipse_3.6_.2F_Helios_.2F_PDT_2.2" target="_blank">http://wiki.eclipse.org/PDT/Installation#Eclipse_3.6_.2F_Helios_.2F_PDT_2.2</a></p>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow: hidden;">
<div class="icon"><img src="http://www.eclipse.org/downloads/images/classic2.jpg" alt="" width="32" /></div>
<p><span class="title"><a href="http://www.eclipse.org/downloads/packages/eclipse-classic-361/heliossr1">Eclipse Classic 3.6.1</a></span></p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.coolcoyote.net/php-mysql/installer-eclipse-et-pdt-separement-sur-windows/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Portée des fonctions</title>
		<link>http://www.coolcoyote.net/php-mysql/portee-des-fonctions</link>
		<comments>http://www.coolcoyote.net/php-mysql/portee-des-fonctions#comments</comments>
		<pubDate>Thu, 17 Jun 2010 15:19:36 +0000</pubDate>
		<dc:creator>Denis S.</dc:creator>
				<category><![CDATA[PHP - MySQL]]></category>
		<category><![CDATA[classes]]></category>
		<category><![CDATA[fonctions]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[portée]]></category>

		<guid isPermaLink="false">http://www.coolcoyote.net/?p=232</guid>
		<description><![CDATA[La dernière fois, je me posais la question de savoir comment Symfony faisait pour proposer dans ses vues des fonctions telles que __() (les helpers) puisque je pensais que la seule solution de rendre une fonction utilisateur locale à une méthode de classe était de la déclarer directement dans la méthode et que je n&#8217;ai [...]]]></description>
			<content:encoded><![CDATA[<p>La dernière fois, je me posais la question de savoir comment <strong>Symfony </strong>faisait pour proposer dans ses vues des fonctions telles que <strong>__()</strong> (les helpers) puisque je pensais que la seule solution de rendre une fonction utilisateur locale à une méthode de classe était de la déclarer directement dans la méthode et que je n&#8217;ai trouvé aucun moyen de transmettre cette fonction à cette méthode (comme cela se passe pour les variables). Et pour cause, on n&#8217;en n&#8217;a pas besoin!</p>
<p><span id="more-232"></span></p>
<p>Un petit retour aux basics de PHP m&#8217;a confirmé que la création d&#8217;une fonction dans une méthode de classe la rendait globale à tout le programme, même dans la méthodes d&#8217;une autre classe. Du coup <strong>Symfony </strong>déclare &laquo;&nbsp;bêtement&nbsp;&raquo; (je met entre guillemets car Symfony oblige, ce n&#8217;est pas si simple <img src='http://www.coolcoyote.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ) ces fonctions dans la méthode d&#8217;une autre classe.</p>
<p>Exemple:</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="cc_syntax"><pre class="php"><span class="kw2">&lt;?php</span>
<span class="kw2">class</span> MaClasse
<span class="br0">&#123;</span>
    <span class="kw2">public</span> <span class="kw2">function</span> registerFunction<span class="br0">&#40;</span><span class="br0">&#41;</span>
    <span class="br0">&#123;</span>
        <span class="kw2">function</span> ma_fonction<span class="br0">&#40;</span><span class="br0">&#41;</span>
        <span class="br0">&#123;</span>
            <span class="co1">// Traitement</span>
        <span class="br0">&#125;</span>
    <span class="br0">&#125;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="co1">// A ce moment, on ne peut pas appeler ma_fonction() car sa déclaration ne s'est pas faite</span>
&nbsp;
<span class="re0">$instance</span> <span class="sy0">=</span> <span class="kw2">new</span> MaClasse<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$instance</span><span class="sy0">-&gt;</span><span class="me1">registerFunction</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="co1">// Maintenant on peut l'appeler</span>
ma_fonction<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="sy1">?&gt;</span></pre></td></tr></table></div>

<p>Comme dit précédemment, on pourra donc également appeler <strong>ma_fonction()</strong> à l&#8217;intérieur d&#8217;une méthode d&#8217;une autre classe ou n&#8217;importe où dans le programme.</p>
<p>Attention cependant : <strong>PHP </strong>n&#8217;accepte pas la redéfinition des fonctions déjà déclarées, ce qui veut dire que si on s&#8217;amuse à appeler une deuxième fois la méthode <strong>registerFunction()</strong>, on aura un beau message d&#8217;erreur.</p>
<p>Comme quoi, relire les bases de temps en temps ça fait pas de mal <img src='http://www.coolcoyote.net/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.coolcoyote.net/php-mysql/portee-des-fonctions/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Les composants de Doctrine &#8211; Le composant Table</title>
		<link>http://www.coolcoyote.net/php-mysql/les-composants-de-doctrine-le-composant-table</link>
		<comments>http://www.coolcoyote.net/php-mysql/les-composants-de-doctrine-le-composant-table#comments</comments>
		<pubDate>Mon, 14 Jun 2010 17:57:33 +0000</pubDate>
		<dc:creator>Denis S.</dc:creator>
				<category><![CDATA[Doctrine]]></category>
		<category><![CDATA[PHP - MySQL]]></category>
		<category><![CDATA[composant]]></category>
		<category><![CDATA[finders]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.coolcoyote.net/?p=267</guid>
		<description><![CDATA[Maintenant que nous avons initialisé Doctrine (vois l&#8217;article sur l&#8217;introduction à Doctrine), nous allons pouvoir commencer à l&#8217;utiliser.
Comme nous l&#8217;avons dit, avec Doctrine tout est objet. Nous aurons donc accès à des classes qui vont nous permettre de travailler les données. On appelle ça des composants. Doctrine fournit plusieurs composants. En voici trois essentiels :

Le [...]]]></description>
			<content:encoded><![CDATA[<p>Maintenant que nous avons initialisé Doctrine (vois l&#8217;article sur <a href="http://www.coolcoyote.net/php-mysql/introduction-a-doctrine">l&#8217;introduction à Doctrine</a>), nous allons pouvoir commencer à l&#8217;utiliser.</p>
<p>Comme nous l&#8217;avons dit, avec Doctrine tout est objet. Nous aurons donc accès à des classes qui vont nous permettre de travailler les données. On appelle ça des <strong>composants</strong>. Doctrine fournit plusieurs composants. En voici trois essentiels :</p>
<ul>
<li>Le composant <strong>Record </strong>qui représente un enregistrement d&#8217;une table</li>
<li>Le composant <strong>Collection </strong>qui représente un ensemble de Record</li>
<li>Le composant <strong>Table </strong>qui représente notre table et nous permettra d&#8217;accéder aux composants Collection et Record</li>
</ul>
<p>Dans cet article nous allons étudier le composant Table.  Il permet comme son nom l&#8217;indique d&#8217;accéder à une table de notre base de données et d&#8217;interagir avec elle. Pour cela il nous faut une instance de la classe représentant notre table :</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
2
3
</pre></td><td class="cc_syntax"><pre class="php"><span class="kw2">&lt;?php</span>
<span class="kw1">require_once</span><span class="br0">&#40;</span><span class="st_h">'bootstrap.php'</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$table</span> <span class="sy0">=</span> Doctrine_Core<span class="sy0">::</span><span class="me2">getTable</span><span class="br0">&#40;</span><span class="st_h">'Produits'</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></td></tr></table></div>

<p><span id="more-267"></span></p>
<p>Vous remarquerez le nom particulier de notre table. En effet, dans notre base de données notre table s&#8217;appelle <strong>produits </strong>et dans Doctrine on l&#8217;appellera <strong>Produits</strong>. Chaque classe commence donc par une majuscule. En fait, chaque mot qui compose le nom de la table commence par une majuscule. Ainsi si on a une table <strong>nouveaux_produits</strong> on l&#8217;appellera <strong>NouveauxProduits </strong>dans Doctrine.</p>
<p>Cet objet va nous permettre d&#8217;accéder à une fonctionnalité très intéressante des Table : les <strong>finders</strong>.</p>
<p>Les finders sont des méthodes qui nous permettent de faire des recherches dans notre table et qui retournent soit un <strong>Record</strong>, soit une <strong>Collection</strong>. Voici un exemple :</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
</pre></td><td class="cc_syntax"><pre class="php"><span class="re0">$record</span> <span class="sy0">=</span> <span class="re0">$table</span><span class="sy0">-&gt;</span><span class="me1">find</span><span class="br0">&#40;</span><span class="nu0">4</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></td></tr></table></div>

<p>La méthode <strong>find()</strong> permet d&#8217;effectuer une recherche sur la clé primaire de notre table. Dans notre cas la clé primaire de la table <strong>produits </strong>est <strong>produits_id</strong>. L&#8217;équivalent SQL de ce que nous venons de faire est :</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
</pre></td><td class="cc_syntax"><pre class="mysql"><span class="kw1">SELECT</span> produits_id<span class="sy2">,</span> produits_name<span class="sy2">,</span> produits_prix <span class="kw1">FROM</span> produits <span class="kw1">WHERE</span> produits_id <span class="sy1">=</span> <span class="nu0">4</span></pre></td></tr></table></div>

<p>En fait <strong>find()</strong> fait plus que cela, il permet de sélectionner non seulement l&#8217;enregistrement mais aussi de rendre accessible les enregistrements des autres tables qui sont en relation avec cet enregistrement. Pour comprendre cela, nous allons étudier en détail le comportement de Doctrine. J&#8217;ai également récupéré les logs MySQL afin de voir comment Doctrine travaillait. Soit la base de données suivante :</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
</pre></td><td class="cc_syntax"><pre class="mysql"><span class="kw1">SET</span> @OLD_UNIQUE_CHECKS<span class="sy1">=</span>@@UNIQUE_CHECKS<span class="sy2">,</span> UNIQUE_CHECKS<span class="sy1">=</span><span class="nu0">0</span><span class="sy2">;</span>
<span class="kw1">SET</span> @OLD_FOREIGN_KEY_CHECKS<span class="sy1">=</span>@@FOREIGN_KEY_CHECKS<span class="sy2">,</span> FOREIGN_KEY_CHECKS<span class="sy1">=</span><span class="nu0">0</span><span class="sy2">;</span>
<span class="kw1">SET</span> @OLD_SQL_MODE<span class="sy1">=</span>@@SQL_MODE<span class="sy2">,</span> SQL_MODE<span class="sy1">=</span><span class="st0">'TRADITIONAL'</span><span class="sy2">;</span>
&nbsp;
<span class="co1">-- -----------------------------------------------------</span>
<span class="co1">-- Table `groupes`</span>
<span class="co1">-- -----------------------------------------------------</span>
<span class="kw1">CREATE</span>  <span class="kw1">TABLE</span> <span class="kw1">IF <span class="kw10">NOT</span> EXISTS</span> <span class="st0">`groupes`</span> <span class="br0">&#40;</span>
  <span class="st0">`groupes<span class="es1">_</span>id`</span> <span class="kw4">INT</span> <span class="kw10">NOT</span> <span class="kw3">NULL</span> <span class="kw6">AUTO_INCREMENT</span> <span class="sy2">,</span>
  <span class="st0">`groupes<span class="es1">_</span>name`</span> <span class="kw4">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">45</span><span class="br0">&#41;</span> <span class="kw10">NOT</span> <span class="kw3">NULL</span> <span class="sy2">,</span>
  <span class="kw1">PRIMARY KEY</span> <span class="br0">&#40;</span><span class="st0">`groupes<span class="es1">_</span>id`</span><span class="br0">&#41;</span> <span class="br0">&#41;</span>
<span class="kw1">ENGINE</span> <span class="sy1">=</span> <span class="kw1">InnoDB</span>
<span class="kw2">DEFAULT</span> CHARACTER <span class="kw1">SET</span> <span class="sy1">=</span> utf8
<span class="kw10">COLLATE</span> <span class="sy1">=</span> utf8_general_ci<span class="sy2">;</span>
&nbsp;
<span class="co1">-- -----------------------------------------------------</span>
<span class="co1">-- Table `user`</span>
<span class="co1">-- -----------------------------------------------------</span>
<span class="kw1">CREATE</span>  <span class="kw1">TABLE</span> <span class="kw1">IF <span class="kw10">NOT</span> EXISTS</span> <span class="st0">`user`</span> <span class="br0">&#40;</span>
  <span class="st0">`user<span class="es1">_</span>id`</span> <span class="kw4">INT</span> <span class="kw10">NOT</span> <span class="kw3">NULL</span> <span class="kw6">AUTO_INCREMENT</span> <span class="sy2">,</span>
  <span class="st0">`groupes<span class="es1">_</span>id`</span> <span class="kw4">INT</span> <span class="kw10">NOT</span> <span class="kw3">NULL</span> <span class="sy2">,</span>
  <span class="st0">`user<span class="es1">_</span>pseudo`</span> <span class="kw4">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">100</span><span class="br0">&#41;</span> <span class="kw3">NULL</span> <span class="sy2">,</span>
  <span class="kw1">PRIMARY KEY</span> <span class="br0">&#40;</span><span class="st0">`user<span class="es1">_</span>id`</span><span class="br0">&#41;</span> <span class="sy2">,</span>
  <span class="kw1">CONSTRAINT</span> <span class="st0">`user<span class="es1">_</span>groupes<span class="es1">_</span>id`</span>
    <span class="kw1">FOREIGN KEY</span> <span class="br0">&#40;</span><span class="st0">`groupes<span class="es1">_</span>id`</span> <span class="br0">&#41;</span>
    <span class="kw1">REFERENCES</span> <span class="st0">`groupes`</span> <span class="br0">&#40;</span><span class="st0">`groupes<span class="es1">_</span>id`</span> <span class="br0">&#41;</span>
    <span class="kw1">ON</span> <span class="kw1">DELETE</span> <span class="kw1">CASCADE</span>
    <span class="kw1">ON</span> <span class="kw1">UPDATE</span> <span class="kw1">NO</span> <span class="kw1">ACTION</span><span class="br0">&#41;</span>
<span class="kw1">ENGINE</span> <span class="sy1">=</span> <span class="kw1">InnoDB</span>
<span class="kw2">DEFAULT</span> CHARACTER <span class="kw1">SET</span> <span class="sy1">=</span> utf8
<span class="kw10">COLLATE</span> <span class="sy1">=</span> utf8_general_ci<span class="sy2">;</span>
&nbsp;
<span class="kw1">CREATE</span> <span class="kw1">INDEX</span> <span class="st0">`user<span class="es1">_</span>groupes<span class="es1">_</span>id`</span> <span class="kw1">ON</span> <span class="st0">`user`</span> <span class="br0">&#40;</span><span class="st0">`groupes<span class="es1">_</span>id`</span> <span class="kw1">ASC</span><span class="br0">&#41;</span> <span class="sy2">;</span>
&nbsp;
<span class="co1">-- -----------------------------------------------------</span>
<span class="co1">-- Table `phone`</span>
<span class="co1">-- -----------------------------------------------------</span>
<span class="kw1">CREATE</span>  <span class="kw1">TABLE</span> <span class="kw1">IF <span class="kw10">NOT</span> EXISTS</span> <span class="st0">`phone`</span> <span class="br0">&#40;</span>
  <span class="st0">`phone<span class="es1">_</span>id`</span> <span class="kw4">INT</span> <span class="kw10">NOT</span> <span class="kw3">NULL</span> <span class="kw6">AUTO_INCREMENT</span> <span class="sy2">,</span>
  <span class="st0">`user<span class="es1">_</span>id`</span> <span class="kw4">INT</span> <span class="kw10">NOT</span> <span class="kw3">NULL</span> <span class="sy2">,</span>
  <span class="st0">`phone<span class="es1">_</span>number`</span> <span class="kw4">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">20</span><span class="br0">&#41;</span> <span class="kw10">NOT</span> <span class="kw3">NULL</span> <span class="sy2">,</span>
  <span class="kw1">PRIMARY KEY</span> <span class="br0">&#40;</span><span class="st0">`phone<span class="es1">_</span>id`</span><span class="br0">&#41;</span> <span class="sy2">,</span>
  <span class="kw1">CONSTRAINT</span> <span class="st0">`phone<span class="es1">_</span>user<span class="es1">_</span>id`</span>
    <span class="kw1">FOREIGN KEY</span> <span class="br0">&#40;</span><span class="st0">`user<span class="es1">_</span>id`</span> <span class="br0">&#41;</span>
    <span class="kw1">REFERENCES</span> <span class="st0">`user`</span> <span class="br0">&#40;</span><span class="st0">`user<span class="es1">_</span>id`</span> <span class="br0">&#41;</span>
    <span class="kw1">ON</span> <span class="kw1">DELETE</span> <span class="kw1">CASCADE</span>
    <span class="kw1">ON</span> <span class="kw1">UPDATE</span> <span class="kw1">NO</span> <span class="kw1">ACTION</span><span class="br0">&#41;</span>
<span class="kw1">ENGINE</span> <span class="sy1">=</span> <span class="kw1">InnoDB</span>
<span class="kw2">DEFAULT</span> CHARACTER <span class="kw1">SET</span> <span class="sy1">=</span> utf8
<span class="kw10">COLLATE</span> <span class="sy1">=</span> utf8_general_ci<span class="sy2">;</span>
&nbsp;
<span class="kw1">CREATE</span> <span class="kw1">INDEX</span> <span class="st0">`phone<span class="es1">_</span>user<span class="es1">_</span>id`</span> <span class="kw1">ON</span> <span class="st0">`phone`</span> <span class="br0">&#40;</span><span class="st0">`user<span class="es1">_</span>id`</span> <span class="kw1">ASC</span><span class="br0">&#41;</span> <span class="sy2">;</span>
&nbsp;
<span class="kw1">SET</span> SQL_MODE<span class="sy1">=</span>@OLD_SQL_MODE<span class="sy2">;</span>
<span class="kw1">SET</span> FOREIGN_KEY_CHECKS<span class="sy1">=</span>@OLD_FOREIGN_KEY_CHECKS<span class="sy2">;</span>
<span class="kw1">SET</span> UNIQUE_CHECKS<span class="sy1">=</span>@OLD_UNIQUE_CHECKS<span class="sy2">;</span></pre></td></tr></table></div>

<p>Voici une représentation schématique de cette base :</p>
<div id="attachment_268" class="wp-caption alignnone" style="width: 417px"><img class="size-full wp-image-268" title="exemple_user" src="http://www.coolcoyote.net/wp-content/uploads/2010/01/exemple_user.png" alt="Schéma base de données" width="407" height="231" /><p class="wp-caption-text">Schéma base de données</p></div>
<p>Comme on peut le voir, on a une table d&#8217;utilisateur. Chaque utilisateur ne peut appartenir qu&#8217;à un seul groupe (many-to-one), mais peut posséder plusieurs numéros de téléphone (one-to-many). Si je fais :</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
</pre></td><td class="cc_syntax"><pre class="php"><span class="re0">$user</span> <span class="sy0">=</span> Doctrine_Core<span class="sy0">::</span><span class="me2">getTable</span><span class="br0">&#40;</span><span class="st_h">'User'</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">find</span><span class="br0">&#40;</span><span class="nu0">1</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></td></tr></table></div>

<p>MySQL va faire la requête suivante :</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
</pre></td><td class="cc_syntax"><pre class="mysql"><span class="kw1">SELECT</span> u.user_id <span class="kw1">AS</span> u__user_id<span class="sy2">,</span> u.groupes_id <span class="kw1">AS</span> u__groupes_id<span class="sy2">,</span> u.user_pseudo <span class="kw1">AS</span> u__user_pseudo <span class="kw1">FROM</span> <span class="kw23">user</span> u <span class="kw1">WHERE</span> <span class="br0">&#40;</span>u.user_id <span class="sy1">=</span> <span class="st0">'1'</span><span class="br0">&#41;</span> <span class="kw1">LIMIT</span> <span class="nu0">1</span></pre></td></tr></table></div>

<p>Je vais ainsi avoir accès aux champs de l&#8217;enregistrement récupéré grâce aux propriétés suivantes:</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
2
3
</pre></td><td class="cc_syntax"><pre class="php"><span class="kw1">echo</span> <span class="re0">$user</span><span class="sy0">-&gt;</span><span class="me1">user_id</span>  <span class="sy0">.</span>  <span class="st_h">'&lt;br /&gt;'</span><span class="sy0">;</span>
<span class="kw1">echo</span> <span class="re0">$user</span><span class="sy0">-&gt;</span><span class="me1">groupes_id</span>  <span class="sy0">.</span>  <span class="st_h">'&lt;br /&gt;'</span><span class="sy0">;</span>
<span class="kw1">echo</span> <span class="re0">$user</span><span class="sy0">-&gt;</span><span class="me1">user_pseudo</span>  <span class="sy0">.</span>  <span class="st_h">'&lt;br /&gt;'</span><span class="sy0">;</span></pre></td></tr></table></div>

<p>On va également avoir la possibilité d&#8217;accéder aux champs de la table <strong>groupes </strong>dont dépend notre enregistrement :</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
</pre></td><td class="cc_syntax"><pre class="php"><span class="kw1">echo</span> <span class="re0">$user</span><span class="sy0">-&gt;</span><span class="me1">Groupes</span><span class="sy0">-&gt;</span><span class="me1">groupes_name</span> <span class="sy0">.</span> <span class="st_h">'&lt;br /&gt;'</span><span class="sy0">;</span></pre></td></tr></table></div>

<p><strong>$user-&gt;Groupes</strong> représente un objet <strong>Record </strong>de la table <strong>Groupes</strong>. C&#8217;est un Record car selon le type de relation définit , un utilisateur ne peut appartenir qu&#8217;à un seul et unique groupe.</p>
<p>Sauf que dans la requête effectuée par Doctrine, on ne va pas chercher les informations de la table <strong>groupes</strong>. En fait la requête sera effectuée uniquement au moment où je demande d&#8217;accéder à la propriété <strong>$user-&gt;Groupes-&gt;groupes_name</strong>. Ainsi, à ce moment et uniquement lors du premier appel, Doctrine va effectuer la requête suivante :</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
</pre></td><td class="cc_syntax"><pre class="mysql"><span class="kw1">SELECT</span> g.groupes_id <span class="kw1">AS</span> g__groupes_id<span class="sy2">,</span> g.groupes_name <span class="kw1">AS</span> g__groupes_name <span class="kw1">FROM</span> groupes g <span class="kw1">WHERE</span> <span class="br0">&#40;</span>g.groupes_id <span class="sy1">=</span> <span class="st0">'1'</span><span class="br0">&#41;</span></pre></td></tr></table></div>

<p>Doctrine va ensuite mettre ce résultat en cache. C&#8217;est à dire que si on demande à nouveau à accéder à une propriété de l&#8217;objet <strong>$user-&gt;Groupes</strong>, Doctrine ne va pas refaire la requête.</p>
<p>Tout comme nous avons un objet <strong>$user-&gt;Groupes</strong>, nous avons un objet <strong>$user-&gt;Phone</strong>. Sauf qu&#8217;il y a une différence : ici un utilisateur peut posséder plusieurs numéros de téléphone. Ainsi l&#8217;objet <strong>$user-&gt;Phone</strong> ne sera pas une instance de <strong>Record</strong>, mais une instance de <strong>Collection</strong>. Nous verrons plus loin les collections en détail, mais rapidement voici comment nous accèderons aux éléments de notre collection:</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
2
</pre></td><td class="cc_syntax"><pre class="php"><span class="kw1">echo</span> <span class="re0">$user</span><span class="sy0">-&gt;</span><span class="me1">Phone</span><span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><span class="sy0">-&gt;</span><span class="me1">phone_number</span><span class="sy0">;</span>
<span class="kw1">echo</span> <span class="re0">$user</span><span class="sy0">-&gt;</span><span class="me1">Phone</span><span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span><span class="sy0">-&gt;</span><span class="me1">phone_number</span><span class="sy0">;</span></pre></td></tr></table></div>

<p>Au moment de l&#8217;appel à l&#8217;objet <strong>$user-&gt;Phone</strong>, Doctrine va effectuer la requête suivante :</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
</pre></td><td class="cc_syntax"><pre class="mysql"><span class="kw1">SELECT</span> p.phone_id <span class="kw1">AS</span> p__phone_id<span class="sy2">,</span> p.user_id <span class="kw1">AS</span> p__user_id<span class="sy2">,</span> p.phone_number <span class="kw1">AS</span> p__phone_number <span class="kw1">FROM</span> phone p <span class="kw1">WHERE</span> <span class="br0">&#40;</span>p.user_id <span class="kw2">IN</span> <span class="br0">&#40;</span><span class="st0">'1'</span><span class="br0">&#41;</span><span class="br0">&#41;</span></pre></td></tr></table></div>

<p>et récupérer l&#8217;ensemble des résultats.</p>
<p><strong>find()</strong> est donc bien pratique pour récupérer l&#8217;enregistrement d&#8217;une table, mais c&#8217;est moins glorieux lorsque l&#8217;on doit accéder aux relations de cet enregistrement. Même si Doctrine fait attention de ne pas effectuer de requêtes superflues, il fait en deux requêtes ce que l&#8217;on aurait pu faire en une seule avec une jointure.</p>
<p>Dans les finders, nous avons vu comment récupérer un enregistrement. Il est également possible de récupérer tous les enregistrements :</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
</pre></td><td class="cc_syntax"><pre class="php"><span class="re0">$users</span> <span class="sy0">=</span> Doctrine_Record<span class="sy0">::</span><span class="me2">getTable</span><span class="br0">&#40;</span><span class="st_h">'User'</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">findAll</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></td></tr></table></div>

<p><strong>findAll()</strong> retourne donc une Collection qui contient tous les enregistrements de la table <strong>user</strong>. On peut itérer dans cette collection afin d&#8217;extraire les informations :</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
2
3
</pre></td><td class="cc_syntax"><pre class="php"><span class="kw1">foreach</span> <span class="br0">&#40;</span><span class="re0">$users</span> <span class="kw1">as</span> <span class="re0">$user</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw1">echo</span> <span class="re0">$user</span><span class="sy0">-&gt;</span><span class="me1">user_pseudo</span> <span class="sy0">.</span> <span class="st_h">'&lt;br /&gt;'</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></td></tr></table></div>

<p>La requête SQL de Doctrine qui va aller chercher les résultats est la suivante :</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
</pre></td><td class="cc_syntax"><pre class="mysql"><span class="kw1">SELECT</span> u.user_id <span class="kw1">AS</span> u__user_id<span class="sy2">,</span> u.groupes_id <span class="kw1">AS</span> u__groupes_id<span class="sy2">,</span> u.user_pseudo <span class="kw1">AS</span> u__user_pseudo <span class="kw1">FROM</span> <span class="kw23">user</span> u</pre></td></tr></table></div>

<p>On peut également afficher le nom du groupe de chaque utilisateur :</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
2
3
</pre></td><td class="cc_syntax"><pre class="php"><span class="kw1">foreach</span> <span class="br0">&#40;</span><span class="re0">$users</span> <span class="kw1">as</span> <span class="re0">$user</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw1">echo</span> <span class="re0">$user</span><span class="sy0">-&gt;</span><span class="me1">Groupes</span><span class="sy0">-&gt;</span><span class="me1">groupes_name</span> <span class="sy0">.</span> <span class="st_h">'&lt;br /&gt;'</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></td></tr></table></div>

<p>Là c&#8217;est encore pire au niveau de l&#8217;optimisation. En effet, nous avons vu plus haut que Doctrine n&#8217;effectuait les requêtes des tables en relation que lorsque l&#8217;on y accède. Insérons les données suivantes dans nos tables :</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="cc_syntax"><pre class="mysql"><span class="kw2">INSERT</span> <span class="kw1">INTO</span> <span class="st0">`groupes`</span> <span class="br0">&#40;</span><span class="st0">`groupes<span class="es1">_</span>id`</span><span class="sy2">,</span> <span class="st0">`groupes<span class="es1">_</span>name`</span><span class="br0">&#41;</span> <span class="kw1">VALUES</span>
<span class="br0">&#40;</span><span class="nu0">1</span><span class="sy2">,</span> <span class="st0">'groupe 1'</span><span class="br0">&#41;</span><span class="sy2">,</span>
<span class="br0">&#40;</span><span class="nu0">2</span><span class="sy2">,</span> <span class="st0">'groupe 2'</span><span class="br0">&#41;</span><span class="sy2">;</span>
&nbsp;
<span class="kw2">INSERT</span> <span class="kw1">INTO</span> <span class="st0">`user`</span> <span class="br0">&#40;</span><span class="st0">`user<span class="es1">_</span>id`</span><span class="sy2">,</span> <span class="st0">`groupes<span class="es1">_</span>id`</span><span class="sy2">,</span> <span class="st0">`user<span class="es1">_</span>pseudo`</span><span class="br0">&#41;</span> <span class="kw1">VALUES</span>
<span class="br0">&#40;</span><span class="nu0">1</span><span class="sy2">,</span> <span class="nu0">1</span><span class="sy2">,</span> <span class="st0">'User 1'</span><span class="br0">&#41;</span><span class="sy2">,</span>
<span class="br0">&#40;</span><span class="nu0">2</span><span class="sy2">,</span> <span class="nu0">2</span><span class="sy2">,</span> <span class="st0">'User 2'</span><span class="br0">&#41;</span><span class="sy2">,</span>
<span class="br0">&#40;</span><span class="nu0">3</span><span class="sy2">,</span> <span class="nu0">1</span><span class="sy2">,</span> <span class="st0">'User 3'</span><span class="br0">&#41;</span><span class="sy2">;</span></pre></td></tr></table></div>

<p>Si nous analysons les requêtes effectuées par Doctrine lors de la boucle qui accède à la table groupe voici ce que l&#8217;on voit :</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
2
3
</pre></td><td class="cc_syntax"><pre class="mysql"><span class="kw1">SELECT</span> g.groupes_id <span class="kw1">AS</span> g__groupes_id<span class="sy2">,</span> g.groupes_name <span class="kw1">AS</span> g__groupes_name <span class="kw1">FROM</span> groupes g <span class="kw1">WHERE</span> <span class="br0">&#40;</span>g.groupes_id <span class="sy1">=</span> <span class="st0">'1'</span><span class="br0">&#41;</span>
<span class="kw1">SELECT</span> g.groupes_id <span class="kw1">AS</span> g__groupes_id<span class="sy2">,</span> g.groupes_name <span class="kw1">AS</span> g__groupes_name <span class="kw1">FROM</span> groupes g <span class="kw1">WHERE</span> <span class="br0">&#40;</span>g.groupes_id <span class="sy1">=</span> <span class="st0">'2'</span><span class="br0">&#41;</span>
<span class="kw1">SELECT</span> g.groupes_id <span class="kw1">AS</span> g__groupes_id<span class="sy2">,</span> g.groupes_name <span class="kw1">AS</span> g__groupes_name <span class="kw1">FROM</span> groupes g <span class="kw1">WHERE</span> <span class="br0">&#40;</span>g.groupes_id <span class="sy1">=</span> <span class="st0">'1'</span><span class="br0">&#41;</span></pre></td></tr></table></div>

<p>Là ce n&#8217;est plus du tout optimisé puisque l&#8217;on constate que Doctrine va effectuer une requête pour chacun des enregistrements de la Collection <strong>$users</strong>, même si certaines sont communes. Si ce n&#8217;est pas grave dans notre cas, imaginez sur une table de 10 000 entrées&#8230; N&#8217;importe qui vous dirait que dans ce cas il faut effectuer une requête sur la table <strong>user </strong>avec une jointure sur la table <strong>groupes </strong>pour récupérer les champs du groupe. Cela nous pourrons le faire en DQL. En attendant sachez donc que si <strong>findAll()</strong> est parfaitement adapté pour récupérer les enregistrements d&#8217;une table, il ne l&#8217;est plus du tout lorsqu&#8217;il s&#8217;agit d&#8217;accéder aux relations de cette table.</p>
<p>Les finders ont d&#8217;autre possibilités assez intéressantes. Par exemple, il est possible d&#8217;avoir des finders personnalisés selon notre table. On les appelle les <strong>Magic Finders</strong>. Imaginons que nous voulions récupérer toutes les entrées de <strong>user </strong>dont le <strong>groupes_id</strong> est 1 :</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
</pre></td><td class="cc_syntax"><pre class="php"><span class="re0">$users</span> <span class="sy0">=</span> Doctrine_Core<span class="sy0">::</span><span class="me2">getTable</span><span class="br0">&#40;</span><span class="st_h">'User'</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">findByGroupes_id</span><span class="br0">&#40;</span><span class="nu0">1</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></td></tr></table></div>

<p>Cette ligne exécute la requête suivante :</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
</pre></td><td class="cc_syntax"><pre class="mysql"><span class="kw1">SELECT</span> u.user_id <span class="kw1">AS</span> u__user_id<span class="sy2">,</span> u.groupes_id <span class="kw1">AS</span> u__groupes_id<span class="sy2">,</span> u.user_pseudo <span class="kw1">AS</span> u__user_pseudo <span class="kw1">FROM</span> <span class="kw23">user</span> u <span class="kw1">WHERE</span> <span class="br0">&#40;</span>u.groupes_id <span class="sy1">=</span> <span class="st0">'1'</span><span class="br0">&#41;</span></pre></td></tr></table></div>

<p>Et renverra une instance de <strong>Doctrine_Collection</strong>. Ce qui est vraiment top, c&#8217;est que ce finder, qui dépend complètement des champs présents dans la table n&#8217;a pas besoin d&#8217;être codé par le développeur, Doctrine le propose automatiquement, voilà pourquoi on les appelle les <strong>Magic Finders</strong>.</p>
<p>Il est également possible de ne retourner qu&#8217;un seul enregistrement au lieu d&#8217;une Collection :</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
</pre></td><td class="cc_syntax"><pre class="php"><span class="re0">$users</span> <span class="sy0">=</span> Doctrine_Core<span class="sy0">::</span><span class="me2">getTable</span><span class="br0">&#40;</span><span class="st_h">'User'</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">findOneByGroupes_id</span><span class="br0">&#40;</span><span class="nu0">1</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></td></tr></table></div>

<p>Encore une fois il s&#8217;agit d&#8217;un finder personnalisé qui va effectuer la requête suivante :</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
</pre></td><td class="cc_syntax"><pre class="mysql"><span class="kw1">SELECT</span> u.user_id <span class="kw1">AS</span> u__user_id<span class="sy2">,</span> u.groupes_id <span class="kw1">AS</span> u__groupes_id<span class="sy2">,</span> u.user_pseudo <span class="kw1">AS</span> u__user_pseudo <span class="kw1">FROM</span> <span class="kw23">user</span> u <span class="kw1">WHERE</span> <span class="br0">&#40;</span>u.groupes_id <span class="sy1">=</span> <span class="st0">'1'</span><span class="br0">&#41;</span> <span class="kw1">LIMIT</span> <span class="nu0">1</span></pre></td></tr></table></div>

<p>Les finders personnalisés peuvent aller encore plus loin. Regardez le finder suivant :</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
</pre></td><td class="cc_syntax"><pre class="php"><span class="re0">$users</span> <span class="sy0">=</span> Doctrine_Core<span class="sy0">::</span><span class="me2">getTable</span><span class="br0">&#40;</span><span class="st_h">'User'</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">findOneByGroupes_idAndUser_pseudo</span><span class="br0">&#40;</span><span class="nu0">1</span><span class="sy0">,</span> <span class="st_h">'User 1'</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></td></tr></table></div>

<p>La requête SQL produite est la suivante :</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
</pre></td><td class="cc_syntax"><pre class="mysql"><span class="kw1">SELECT</span> u.user_id <span class="kw1">AS</span> u__user_id<span class="sy2">,</span> u.groupes_id <span class="kw1">AS</span> u__groupes_id<span class="sy2">,</span> u.user_pseudo <span class="kw1">AS</span> u__user_pseudo <span class="kw1">FROM</span> <span class="kw23">user</span> u <span class="kw1">WHERE</span> <span class="br0">&#40;</span>u.groupes_id <span class="sy1">=</span> <span class="st0">'1'</span> <span class="kw10">AND</span> u.user_pseudo <span class="sy1">=</span> <span class="st0">'User 1'</span><span class="br0">&#41;</span> <span class="kw1">LIMIT</span> <span class="nu0">1</span></pre></td></tr></table></div>

<p>On peut donc utiliser les mots-clés <strong>And </strong>et <strong>Or </strong>dans les Magic Finders afin de composer notre recherche</p>
<p>Voici donc un petit récap sur les finders :</p>
<ul>
<li><strong>findAll()</strong> renvoie une Collection qui contient tous les enregistrements de la table</li>
<li><strong>find()</strong> renvoi un Record. La recherche se fera sur la clé primaire de la table</li>
<li><strong>findBy</strong> + le nom du champ commençant par une majuscule : Renvoie une Collection. La recherche se fait sur le champ indiqué après <strong>By</strong></li>
<li><strong>findOneBy </strong>+  le nom du champ commençant par une majuscule : Renvoie un Record. La recherche se fait sur le champ indiqué après <strong>By</strong></li>
<li>On peut utiliser les mots-clés <strong>And </strong>et <strong>Or </strong>dans les Magic Finders afin de composer une recherche sur plusieurs champs</li>
</ul>
<p>Ces finders sont très pratiques mais retenez qu&#8217;<span style="color: #ff0000;"><strong>il ne faut jamais les utiliser si vous avez besoin d&#8217;accéder aux relations des enregistrements à cause de leur manque d&#8217;optimisation</strong></span>. Pour cela nous nous tournerons vers le DQL.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coolcoyote.net/php-mysql/les-composants-de-doctrine-le-composant-table/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installation de APC sous Debian</title>
		<link>http://www.coolcoyote.net/php-mysql/installation-de-apc-sous-debian</link>
		<comments>http://www.coolcoyote.net/php-mysql/installation-de-apc-sous-debian#comments</comments>
		<pubDate>Mon, 07 Jun 2010 13:50:16 +0000</pubDate>
		<dc:creator>Denis S.</dc:creator>
				<category><![CDATA[Linux Debian]]></category>
		<category><![CDATA[PHP - MySQL]]></category>
		<category><![CDATA[apc]]></category>
		<category><![CDATA[debian]]></category>
		<category><![CDATA[opcode]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.coolcoyote.net/?p=252</guid>
		<description><![CDATA[APC est un cache d&#8217;OPCodes pour PHP. Il permet de mettre en cache au niveau serveur le code de PHP précompilé afin de ne pas refaire ce traitement.
Vous trouverez plus d&#8217;informations dans l&#8217;article de Julien Pauli sur developpez.com.
Ici il s&#8217;agit de voir comment l&#8217;installer sous Debian. Très facile finalement, il existe un paquet pour ça:
&#62; [...]]]></description>
			<content:encoded><![CDATA[<p>APC est un cache d&#8217;OPCodes pour PHP. Il permet de mettre en cache au niveau serveur le code de PHP précompilé afin de ne pas refaire ce traitement.</p>
<p>Vous trouverez plus d&#8217;informations dans <a href="http://julien-pauli.developpez.com/tutoriels/php/apc/" target="_blank">l&#8217;article</a> de <a href="http://julien-pauli.developpez.com/" target="_blank">Julien Pauli</a> sur developpez.com.</p>
<p>Ici il s&#8217;agit de voir comment l&#8217;installer sous Debian. Très facile finalement, il existe un paquet pour ça:</p>
<pre class="code">&gt; apt-get install php-apc</pre>
<p>Il faudra bien sûr redémarrer Apache.</p>
<p>Le fichier permettant le monitoring du cache est situé dans <strong>/usr/share/doc/php-apc</strong> et s&#8217;appelle <strong>apc.php.gz</strong>. Il faudra donc le décompresser:</p>
<pre class="code">&gt; gzip -d apc-php.gz</pre>
<p>Il vous suffit de déplacer ce fichier où bon vous semble.</p>
<p>A noter que le fichier de config d&#8217;APC se situe dans:</p>
<pre class="code">/etc/php5/conf.d/apc.ini</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.coolcoyote.net/php-mysql/installation-de-apc-sous-debian/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introduction à Doctrine</title>
		<link>http://www.coolcoyote.net/php-mysql/introduction-a-doctrine</link>
		<comments>http://www.coolcoyote.net/php-mysql/introduction-a-doctrine#comments</comments>
		<pubDate>Tue, 12 Jan 2010 13:09:05 +0000</pubDate>
		<dc:creator>Denis S.</dc:creator>
				<category><![CDATA[Doctrine]]></category>
		<category><![CDATA[PHP - MySQL]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.coolcoyote.net/?p=254</guid>
		<description><![CDATA[Cette année je suis passé à Doctrine. Les raisons étaient diverses:

Il était temps pour moi de laisser tomber la vieille extension mysql de PHP et de passer à de l&#8217;objet.
Trouver un système qui s&#8217;intègre facilement dans un modèle MVC
Pouvoir faire de l&#8217;abstraction de base de données
Idéalement un système qui va me faire gagner du temps [...]]]></description>
			<content:encoded><![CDATA[<p>Cette année je suis passé à Doctrine. Les raisons étaient diverses:</p>
<ul>
<li>Il était temps pour moi de laisser tomber la vieille extension <strong>mysql</strong> de <strong>PHP</strong> et de passer à de l&#8217;objet.</li>
<li>Trouver un système qui s&#8217;intègre facilement dans un modèle <strong>MVC</strong></li>
<li>Pouvoir faire de l&#8217;abstraction de base de données</li>
<li>Idéalement un système qui va me faire gagner du temps dans mes développements.</li>
</ul>
<p>Après avoir regardé plusieurs solutions, je me suis donc tourné vers <a href="http://doctrine-project.org" target="_blank">Doctrine</a>:</p>
<ul>
<li>Il s&#8217;interface avec <strong>PDO</strong>, donc abstraction de base de données</li>
<li>Les performances semblent au rendez-vous</li>
<li>Il génère automatiquement le modèle du <strong>MVC</strong></li>
<li>Support des fonctionnalités récentes de MySQL</li>
<li>Utilisé par défaut dans<strong> Symfony</strong></li>
<li>Tout est objet</li>
</ul>
<p>Bref je me suis dis que c&#8217;était le top. Et c&#8217;est vrai que quand on le maîtrise c&#8217;est vraiment sympa. Sauf que la transition s&#8217;est quand même un peu faite dans la douleur. La doc est présente mais dans certains cas j&#8217;ai quand même perdu pas mal de temps à chercher des solutions à mes problèmes. Je me suis donc dit qu&#8217;il était peut-être possible d&#8217;apporter quelques compléments d&#8217;information.</p>
<p><span id="more-254"></span></p>
<h3>Comprendre la philosophie Doctrine</h3>
<p>Doctrine est un <a href="http://fr.wikipedia.org/wiki/Mapping_objet-relationnel" target="_blank">ORM</a> (Object Relational Mapper), c&#8217;est à dire qu&#8217;il va s&#8217;interfacer avec notre base de données afin de nous permettre d&#8217;y accéder comme s&#8217;il s&#8217;agissait d&#8217;un objet.  Ainsi il sera possible d&#8217;accéder aux données d&#8217;une table comme s&#8217;il s&#8217;agissait de propriétés d&#8217;une classe, mais en plus cette classe va nous proposer des méthodes permettant de mettre en œuvre des fonctionnalité comme l&#8217;enregistrement, la suppression, la mise à jour etc.</p>
<p>Prenons un exemple simple :  soit la table mysql suivante:</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
2
3
4
5
</pre></td><td class="cc_syntax"><pre class="mysql"><span class="kw1">CREATE</span> <span class="kw1">TABLE</span> produits <span class="br0">&#40;</span>
  produits_id <span class="kw4">int</span><span class="br0">&#40;</span><span class="nu0">11</span><span class="br0">&#41;</span> <span class="kw10">NOT</span> <span class="kw3">NULL</span> <span class="kw6">auto_increment</span><span class="sy2">,</span>
  produits_name <span class="kw4">varchar</span><span class="br0">&#40;</span><span class="nu0">255</span><span class="br0">&#41;</span> <span class="kw10">NOT</span> <span class="kw3">NULL</span>
  <span class="kw1">PRIMARY KEY</span>  <span class="br0">&#40;</span>produits_id<span class="br0">&#41;</span>
<span class="br0">&#41;</span> <span class="kw1">ENGINE</span><span class="sy1">=</span><span class="kw1">InnoDB</span>  <span class="kw2">DEFAULT</span> <span class="kw7">CHARSET</span><span class="sy1">=</span>utf8<span class="sy2">;</span></pre></td></tr></table></div>

<p>Imaginons que nous voulions insérer un nouvel enregistrement, nous pourrons le réaliser comme ceci :</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
2
3
</pre></td><td class="cc_syntax"><pre class="php"><span class="re0">$produit</span> <span class="sy0">=</span> <span class="kw2">new</span> Produits<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$produit</span><span class="sy0">-&gt;</span><span class="me1">produits_name</span> <span class="sy0">=</span> <span class="st_h">'Casserole'</span><span class="sy0">;</span>
<span class="re0">$produit</span><span class="sy0">-&gt;</span><span class="me1">save</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></td></tr></table></div>

<p>C&#8217;est tout ! Et en bon ORM qu&#8217;il est, Doctrine propose une interface objet pour de nombreux éléments comme la connexion à la base, les tables, les enregistrements des tables, etc. ce que nous verrons plus tard.</p>
<p>Doctrine peut également réaliser des requêtes similaires à ce que l&#8217;on connaît sous MySQL mais avec son propre langage: le <a href="http://www.doctrine-project.org/documentation/manual/1_2/en/dql-doctrine-query-language" target="_blank">DQL</a> (Doctrine Query Langage). Sincèrement, on s&#8217;y fait très vite, voici un exemple de sélection du produit ayant l&#8217;ID 4 :</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
2
3
4
</pre></td><td class="cc_syntax"><pre class="php"><span class="re0">$produit</span> <span class="sy0">=</span> Doctrine_Query<span class="sy0">::</span><span class="me2">create</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
    <span class="sy0">-&gt;</span><span class="me1">from</span><span class="br0">&#40;</span><span class="st_h">'Produits a'</span><span class="br0">&#41;</span>
    <span class="sy0">-&gt;</span><span class="me1">where</span><span class="br0">&#40;</span><span class="st_h">'a.produits_id = ?'</span><span class="sy0">,</span> <span class="nu0">4</span><span class="br0">&#41;</span>
    <span class="sy0">-&gt;</span><span class="me1">fetchOne</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></td></tr></table></div>

<p>La documentation officielle sur le <a href="http://www.doctrine-project.org/documentation/manual/1_2/en/dql-doctrine-query-language" target="_blank">DQL</a> est plutôt bien faite et le &laquo;&nbsp;langage&nbsp;&raquo; est très explicite. Il n&#8217;y aura donc aucune difficulté particulière. Cependant nous en parlerons quand même dans un prochain article.</p>
<h3>La génération du modèle et le fichier YAML</h3>
<p>Pour arriver à tout cela, Doctrine va devoir utiliser des classes qui représenteront nos tables. Ces classes, on ne va pas les créer car Doctrine s&#8217;en charge pour nous. Il va donc se charger de générer des fichiers PHP qui seront notre modèle de données. Il y a plusieurs façons de réaliser cela :</p>
<ul>
<li>On peut créer notre modèle sur Doctrine qui va ensuite se charger de créer les tables sur MySQL</li>
<li>On peut créer nos tables MySQL et Doctrine en déduira son modèle.</li>
</ul>
<p>En ce qui me concerne, je modélise ma base de données avec <strong>MySQL Workbench</strong>, donc je pars toujours d&#8217;une base de données existante pour générer mon modèle Doctrine (je vais considérer que vous ferez pareil). Quelle que soit la solution choisie, il y a un passage qui semble indispensable : le fichier <strong>YAML</strong>. Il s&#8217;agit d&#8217;un fichier  de configuration qui va contenir le schéma de notre base de données et sur lequel Doctrine va se baser.</p>
<p>La génération du modèle va donc se dérouler ainsi:</p>
<p>Base de données MySQL existante -&gt; Génération du fichier YAML -&gt; Génération du modèle</p>
<p>Il existe une solution qui permet de générer le modèle directement à partir de la base de données, mais je ne l&#8217;ai pas trouvée intéressante car elle manque de fonctionnalités. En effet, nous verrons plus tard que Doctrine propose des fonctionnalités très intéressantes mais qui nécessitent d&#8217;être paramétrées dans le fichier YAML et que la conversion directe MySQL -&gt; Modèle va ignorer.</p>
<p>Si vous ne connaissez pas <strong>YAML</strong>, il s&#8217;agit d&#8217;un langage de sérialisation de données comparable à <a href="http://fr.wikipedia.org/wiki/Json" target="_blank">JSON</a>. Vous pourrez trouver plus de renseignements sur <a href="http://fr.wikipedia.org/wiki/YAML" target="_blank">Wikipédia</a> et sur <a href="http://www.yaml.org/" target="_blank">le site officiel</a>. Bien que je le trouve un peu plus complexe que JSON, YAML reste facilement compréhensible. Il ne sera donc pas compliqué de retravailler le modèle pour Doctrine.</p>
<h3>Téléchargement et installation de Doctrine</h3>
<p>Les informations qui suivent sont valables pour Doctrine 1.2.1. Il est possible de télécharger le sandbox à cette adresse: <a href="http://www.doctrine-project.org/download" target="_blank">http://www.doctrine-project.org/download</a></p>
<p>On va créer un répertoire <strong>doctrine_test</strong>. Dans ce répertoire, nous allons créer le répertoire <strong>lib/vendor/doctrine</strong> dans lequel nous allons copier la librairie.</p>
<p>Nous devrions donc avoir dans le répertoire <strong>doctrine_test/lib/vendor/dotrine</strong> les éléments suivants:</p>
<ul>
<li>Un répertoire <strong>Doctrine</strong></li>
<li>Un répertoire <strong>vendor</strong></li>
<li>Un fichier <strong>Doctrine.php</strong></li>
</ul>
<h3>Le bootstrap</h3>
<p>Ce que l&#8217;on va appeler bootstrap, c&#8217;est un fichier PHP qui va contenir le code de connexion à la base de données et que l&#8217;on va inclure dans chacun de nos fichiers afin d&#8217;activer l&#8217;autoload, d&#8217;établir la connexion à la base et de définir plusieurs paramètres. Dans le répertoire doctrine_test, nous allons créer un fichier bootstrap.php dont voici le contenu :</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
</pre></td><td class="cc_syntax"><pre class="php"><span class="kw2">&lt;?php</span>
&nbsp;
<span class="co1">// bootstrap.php</span>
&nbsp;
<span class="co4">/**
 * Bootstrap Doctrine.php, register autoloader specify
 * configuration attributes and load models.
 */</span>
&nbsp;
<span class="kw1">require_once</span><span class="br0">&#40;</span><span class="st_h">'lib/vendor/doctrine/Doctrine.php'</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="kw3">spl_autoload_register</span><span class="br0">&#40;</span><span class="kw3">array</span><span class="br0">&#40;</span><span class="st_h">'Doctrine'</span><span class="sy0">,</span> <span class="st_h">'autoload'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="kw3">spl_autoload_register</span><span class="br0">&#40;</span><span class="kw3">array</span><span class="br0">&#40;</span><span class="st_h">'Doctrine'</span><span class="sy0">,</span> <span class="st_h">'modelsAutoload'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span> 
&nbsp;
<span class="re0">$manager</span> <span class="sy0">=</span> Doctrine_Manager<span class="sy0">::</span><span class="me2">getInstance</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="re0">$conn</span> <span class="sy0">=</span> Doctrine_Manager<span class="sy0">::</span><span class="me2">connection</span><span class="br0">&#40;</span><span class="st_h">'mysql://user:password@host/dbname'</span><span class="sy0">,</span><span class="st_h">'doctrine'</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="re0">$manager</span><span class="sy0">-&gt;</span><span class="me1">setAttribute</span><span class="br0">&#40;</span>Doctrine_Core<span class="sy0">::</span><span class="me2">ATTR_VALIDATE</span><span class="sy0">,</span> Doctrine_Core<span class="sy0">::</span><span class="me2">VALIDATE_ALL</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$manager</span><span class="sy0">-&gt;</span><span class="me1">setAttribute</span><span class="br0">&#40;</span>Doctrine_Core<span class="sy0">::</span><span class="me2">ATTR_AUTO_ACCESSOR_OVERRIDE</span><span class="sy0">,</span> <span class="kw4">true</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$manager</span><span class="sy0">-&gt;</span><span class="me1">setAttribute</span><span class="br0">&#40;</span>Doctrine_Core<span class="sy0">::</span><span class="me2">ATTR_AUTOLOAD_TABLE_CLASSES</span><span class="sy0">,</span> <span class="kw4">true</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$manager</span><span class="sy0">-&gt;</span><span class="me1">setAttribute</span><span class="br0">&#40;</span>Doctrine_Core<span class="sy0">::</span><span class="me2">ATTR_MODEL_LOADING</span><span class="sy0">,</span> Doctrine_Core<span class="sy0">::</span><span class="me2">MODEL_LOADING_CONSERVATIVE</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
Doctrine_Core<span class="sy0">::</span><span class="me2">loadModels</span><span class="br0">&#40;</span><span class="st_h">'models'</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></td></tr></table></div>

<p>Une note très importante si vous avez déjà utilisé Doctrine : vous remarquerez un deuxième autoload qui n&#8217;est pas indiqué dans la documentation. En effet cet autoload est nécessaire et n&#8217;est pas documenté et j&#8217;ai galéré un bon moment avant de trouver la solution sur leur forum.</p>
<p>L&#8217;explication de ce fichier est relativement simple :</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
</pre></td><td class="cc_syntax"><pre class="php"><span class="kw1">require_once</span><span class="br0">&#40;</span><span class="st_h">'lib/vendor/doctrine/Doctrine.php'</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></td></tr></table></div>

<p>On inclue la librairie Doctrine</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
2
</pre></td><td class="cc_syntax"><pre class="php"><span class="kw3">spl_autoload_register</span><span class="br0">&#40;</span><span class="kw3">array</span><span class="br0">&#40;</span><span class="st_h">'Doctrine'</span><span class="sy0">,</span> <span class="st_h">'autoload'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="kw3">spl_autoload_register</span><span class="br0">&#40;</span><span class="kw3">array</span><span class="br0">&#40;</span><span class="st_h">'Doctrine'</span><span class="sy0">,</span> <span class="st_h">'modelsAutoload'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></td></tr></table></div>

<p>On déclare les autoloads</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
</pre></td><td class="cc_syntax"><pre class="php"><span class="re0">$manager</span> <span class="sy0">=</span> Doctrine_Manager<span class="sy0">::</span><span class="me2">getInstance</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></td></tr></table></div>

<p>On récupère une instance <strong>Doctrine_Manager</strong> (singleton) qui va nous permettre de définir certaines options</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
</pre></td><td class="cc_syntax"><pre class="php"><span class="re0">$conn</span> <span class="sy0">=</span> Doctrine_Manager<span class="sy0">::</span><span class="me2">connection</span><span class="br0">&#40;</span><span class="st_h">'mysql://user:password@host/dbname'</span><span class="sy0">,</span><span class="st_h">'doctrine'</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></td></tr></table></div>

<p>On se connecte à la base de données avec une syntaxe de type <strong>DSN</strong> compatible avec <strong>PDO</strong></p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
2
3
4
</pre></td><td class="cc_syntax"><pre class="php"><span class="re0">$manager</span><span class="sy0">-&gt;</span><span class="me1">setAttribute</span><span class="br0">&#40;</span>Doctrine_Core<span class="sy0">::</span><span class="me2">ATTR_VALIDATE</span><span class="sy0">,</span> Doctrine_Core<span class="sy0">::</span><span class="me2">VALIDATE_ALL</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$manager</span><span class="sy0">-&gt;</span><span class="me1">setAttribute</span><span class="br0">&#40;</span>Doctrine_Core<span class="sy0">::</span><span class="me2">ATTR_AUTO_ACCESSOR_OVERRIDE</span><span class="sy0">,</span> <span class="kw4">true</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$manager</span><span class="sy0">-&gt;</span><span class="me1">setAttribute</span><span class="br0">&#40;</span>Doctrine_Core<span class="sy0">::</span><span class="me2">ATTR_AUTOLOAD_TABLE_CLASSES</span><span class="sy0">,</span> <span class="kw4">true</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$manager</span><span class="sy0">-&gt;</span><span class="me1">setAttribute</span><span class="br0">&#40;</span>Doctrine_Core<span class="sy0">::</span><span class="me2">ATTR_MODEL_LOADING</span><span class="sy0">,</span> Doctrine_Core<span class="sy0">::</span><span class="me2">MODEL_LOADING_CONSERVATIVE</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></td></tr></table></div>

<p>Ici on définit les options de Doctrine au niveau global (on peut définir des options sur 3 niveaux: au niveau global, au niveau d&#8217;une connexion en particulier, au niveau d&#8217;une table en particulier). Voici la signification de ces options:</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
</pre></td><td class="cc_syntax"><pre class="php"><span class="re0">$manager</span><span class="sy0">-&gt;</span><span class="me1">setAttribute</span><span class="br0">&#40;</span>Doctrine_Core<span class="sy0">::</span><span class="me2">ATTR_VALIDATE</span><span class="sy0">,</span> Doctrine_Core<span class="sy0">::</span><span class="me2">VALIDATE_ALL</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></td></tr></table></div>

<p>Doctrine possède un validateur de données intégré. Si jamais vous essayez par exemple d&#8217;insérer une chaîne de caractère dans une champ de type entier, Doctrine va générer une erreur avant même de tenter de l&#8217;insérer en base. C&#8217;est assez utile et ici on déclare vouloir l&#8217;utiliser.</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
</pre></td><td class="cc_syntax"><pre class="php"><span class="re0">$manager</span><span class="sy0">-&gt;</span><span class="me1">setAttribute</span><span class="br0">&#40;</span>Doctrine_Core<span class="sy0">::</span><span class="me2">ATTR_AUTO_ACCESSOR_OVERRIDE</span><span class="sy0">,</span> <span class="kw4">true</span><span class="br0">&#41;</span></pre></td></tr></table></div>

<p>l&#8217;<strong>AUTO_ACCESSOR_OVERRIDE</strong> va nous permettre de personnaliser l&#8217;assignation de données. J&#8217;essaierai de faire un article complet sur la personnalisation des classes car j&#8217;ai trouvé la documentation assez légère sur les possibilités offertes du coup je pense moi-même ne pas exploiter cette fonctionnalité à fond.</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
</pre></td><td class="cc_syntax"><pre class="php"><span class="re0">$manager</span><span class="sy0">-&gt;</span><span class="me1">setAttribute</span><span class="br0">&#40;</span>Doctrine_Core<span class="sy0">::</span><span class="me2">ATTR_AUTOLOAD_TABLE_CLASSES</span><span class="sy0">,</span> <span class="kw4">true</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></td></tr></table></div>

<p>Doctrine permet de personnaliser également les classes de table en permettant de créer des méthodes propres à une table. Ce paramètre permet de charger le fichier contenant nos méthodes personnalisées.</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
</pre></td><td class="cc_syntax"><pre class="php"><span class="re0">$manager</span><span class="sy0">-&gt;</span><span class="me1">setAttribute</span><span class="br0">&#40;</span>Doctrine_Core<span class="sy0">::</span><span class="me2">ATTR_MODEL_LOADING</span><span class="sy0">,</span> Doctrine_Core<span class="sy0">::</span><span class="me2">MODEL_LOADING_CONSERVATIVE</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></td></tr></table></div>

<p>Ce paramètre permet d&#8217;utiliser l&#8217;autoload pour le chargement des classes du modèle.</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
</pre></td><td class="cc_syntax"><pre class="php">Doctrine_Core<span class="sy0">::</span><span class="me2">loadModels</span><span class="br0">&#40;</span><span class="st_h">'models'</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></td></tr></table></div>

<p>Enfin on déclare quel répertoire contient nos fichiers de modèle. Vous en déduirez donc qu&#8217;il va falloir créer un dossier <strong>models</strong> <img src='http://www.coolcoyote.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h3>Base de données de test et génération du modèle</h3>
<p>Nous allons commencer avec une base de données simple dont voici le schema :</p>
<p>Voici le code SQL de création des tables (à copier / coller dans phpMyAdmin) :</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
</pre></td><td class="cc_syntax"><pre class="mysql"><span class="kw1">SET</span> @OLD_UNIQUE_CHECKS<span class="sy1">=</span>@@UNIQUE_CHECKS<span class="sy2">,</span> UNIQUE_CHECKS<span class="sy1">=</span><span class="nu0">0</span><span class="sy2">;</span>
<span class="kw1">SET</span> @OLD_FOREIGN_KEY_CHECKS<span class="sy1">=</span>@@FOREIGN_KEY_CHECKS<span class="sy2">,</span> FOREIGN_KEY_CHECKS<span class="sy1">=</span><span class="nu0">0</span><span class="sy2">;</span>
<span class="kw1">SET</span> @OLD_SQL_MODE<span class="sy1">=</span>@@SQL_MODE<span class="sy2">,</span> SQL_MODE<span class="sy1">=</span><span class="st0">'TRADITIONAL'</span><span class="sy2">;</span>
&nbsp;
<span class="co1">-- -----------------------------------------------------</span>
<span class="co1">-- Table `produits`</span>
<span class="co1">-- -----------------------------------------------------</span>
<span class="kw1">CREATE</span>  <span class="kw1">TABLE</span> <span class="kw1">IF <span class="kw10">NOT</span> EXISTS</span> <span class="st0">`produits`</span> <span class="br0">&#40;</span>
  <span class="st0">`produits<span class="es1">_</span>id`</span> <span class="kw4">INT</span> <span class="kw10">NOT</span> <span class="kw3">NULL</span> <span class="kw6">AUTO_INCREMENT</span> <span class="sy2">,</span>
  <span class="st0">`produits<span class="es1">_</span>name`</span> <span class="kw4">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">100</span><span class="br0">&#41;</span> <span class="kw10">NOT</span> <span class="kw3">NULL</span> <span class="sy2">,</span>
  <span class="st0">`produits<span class="es1">_</span>prix`</span> <span class="kw4">FLOAT</span> <span class="kw10">NOT</span> <span class="kw3">NULL</span> <span class="kw2">DEFAULT</span> <span class="nu0">0</span> <span class="sy2">,</span>
  <span class="kw1">PRIMARY KEY</span> <span class="br0">&#40;</span><span class="st0">`produits<span class="es1">_</span>id`</span><span class="br0">&#41;</span> <span class="br0">&#41;</span>
<span class="kw1">ENGINE</span> <span class="sy1">=</span> <span class="kw1">InnoDB</span>
<span class="kw2">DEFAULT</span> CHARACTER <span class="kw1">SET</span> <span class="sy1">=</span> utf8<span class="sy2">;</span>
&nbsp;
<span class="co1">-- -----------------------------------------------------</span>
<span class="co1">-- Table `tailles`</span>
<span class="co1">-- -----------------------------------------------------</span>
<span class="kw1">CREATE</span>  <span class="kw1">TABLE</span> <span class="kw1">IF <span class="kw10">NOT</span> EXISTS</span> <span class="st0">`tailles`</span> <span class="br0">&#40;</span>
  <span class="st0">`tailles<span class="es1">_</span>id`</span> <span class="kw4">INT</span> <span class="kw10">NOT</span> <span class="kw3">NULL</span> <span class="kw6">AUTO_INCREMENT</span> <span class="sy2">,</span>
  <span class="st0">`tailles<span class="es1">_</span>name`</span> <span class="kw4">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">45</span><span class="br0">&#41;</span> <span class="kw3">NULL</span> <span class="sy2">,</span>
  <span class="kw1">PRIMARY KEY</span> <span class="br0">&#40;</span><span class="st0">`tailles<span class="es1">_</span>id`</span><span class="br0">&#41;</span> <span class="br0">&#41;</span>
<span class="kw1">ENGINE</span> <span class="sy1">=</span> <span class="kw1">InnoDB</span>
<span class="kw2">DEFAULT</span> CHARACTER <span class="kw1">SET</span> <span class="sy1">=</span> utf8<span class="sy2">;</span>
&nbsp;
<span class="co1">-- -----------------------------------------------------</span>
<span class="co1">-- Table `couleurs`</span>
<span class="co1">-- -----------------------------------------------------</span>
<span class="kw1">CREATE</span>  <span class="kw1">TABLE</span> <span class="kw1">IF <span class="kw10">NOT</span> EXISTS</span> <span class="st0">`couleurs`</span> <span class="br0">&#40;</span>
  <span class="st0">`couleurs<span class="es1">_</span>id`</span> <span class="kw4">INT</span> <span class="kw10">NOT</span> <span class="kw3">NULL</span> <span class="kw6">AUTO_INCREMENT</span> <span class="sy2">,</span>
  <span class="st0">`couleurs<span class="es1">_</span>name`</span> <span class="kw4">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">45</span><span class="br0">&#41;</span> <span class="kw10">NOT</span> <span class="kw3">NULL</span> <span class="sy2">,</span>
  <span class="kw1">PRIMARY KEY</span> <span class="br0">&#40;</span><span class="st0">`couleurs<span class="es1">_</span>id`</span><span class="br0">&#41;</span> <span class="br0">&#41;</span>
<span class="kw1">ENGINE</span> <span class="sy1">=</span> <span class="kw1">InnoDB</span>
<span class="kw2">DEFAULT</span> CHARACTER <span class="kw1">SET</span> <span class="sy1">=</span> utf8<span class="sy2">;</span>
&nbsp;
<span class="co1">-- -----------------------------------------------------</span>
<span class="co1">-- Table `produits_having_tailles`</span>
<span class="co1">-- -----------------------------------------------------</span>
<span class="kw1">CREATE</span>  <span class="kw1">TABLE</span> <span class="kw1">IF <span class="kw10">NOT</span> EXISTS</span> <span class="st0">`produits<span class="es1">_</span>having<span class="es1">_</span>tailles`</span> <span class="br0">&#40;</span>
  <span class="st0">`produits<span class="es1">_</span>id`</span> <span class="kw4">INT</span> <span class="kw10">NOT</span> <span class="kw3">NULL</span> <span class="sy2">,</span>
  <span class="st0">`tailles<span class="es1">_</span>id`</span> <span class="kw4">INT</span> <span class="kw10">NOT</span> <span class="kw3">NULL</span> <span class="sy2">,</span>
  <span class="kw1">PRIMARY KEY</span> <span class="br0">&#40;</span><span class="st0">`produits<span class="es1">_</span>id`</span><span class="sy2">,</span> <span class="st0">`tailles<span class="es1">_</span>id`</span><span class="br0">&#41;</span> <span class="sy2">,</span>
  <span class="kw1">INDEX</span> <span class="st0">`pht<span class="es1">_</span>produits<span class="es1">_</span>id`</span> <span class="br0">&#40;</span><span class="st0">`produits<span class="es1">_</span>id`</span> <span class="kw1">ASC</span><span class="br0">&#41;</span> <span class="sy2">,</span>
  <span class="kw1">INDEX</span> <span class="st0">`pht<span class="es1">_</span>tailles<span class="es1">_</span>id`</span> <span class="br0">&#40;</span><span class="st0">`tailles<span class="es1">_</span>id`</span> <span class="kw1">ASC</span><span class="br0">&#41;</span> <span class="sy2">,</span>
  <span class="kw1">CONSTRAINT</span> <span class="st0">`pht<span class="es1">_</span>produits<span class="es1">_</span>id`</span>
    <span class="kw1">FOREIGN KEY</span> <span class="br0">&#40;</span><span class="st0">`produits<span class="es1">_</span>id`</span> <span class="br0">&#41;</span>
    <span class="kw1">REFERENCES</span> <span class="st0">`produits`</span> <span class="br0">&#40;</span><span class="st0">`produits<span class="es1">_</span>id`</span> <span class="br0">&#41;</span>
    <span class="kw1">ON</span> <span class="kw1">DELETE</span> <span class="kw1">CASCADE</span>
    <span class="kw1">ON</span> <span class="kw1">UPDATE</span> <span class="kw1">NO</span> <span class="kw1">ACTION</span><span class="sy2">,</span>
  <span class="kw1">CONSTRAINT</span> <span class="st0">`pht<span class="es1">_</span>tailles<span class="es1">_</span>id`</span>
    <span class="kw1">FOREIGN KEY</span> <span class="br0">&#40;</span><span class="st0">`tailles<span class="es1">_</span>id`</span> <span class="br0">&#41;</span>
    <span class="kw1">REFERENCES</span> <span class="st0">`tailles`</span> <span class="br0">&#40;</span><span class="st0">`tailles<span class="es1">_</span>id`</span> <span class="br0">&#41;</span>
    <span class="kw1">ON</span> <span class="kw1">DELETE</span> <span class="kw1">CASCADE</span>
    <span class="kw1">ON</span> <span class="kw1">UPDATE</span> <span class="kw1">NO</span> <span class="kw1">ACTION</span><span class="br0">&#41;</span>
<span class="kw1">ENGINE</span> <span class="sy1">=</span> <span class="kw1">InnoDB</span>
<span class="kw2">DEFAULT</span> CHARACTER <span class="kw1">SET</span> <span class="sy1">=</span> utf8<span class="sy2">;</span>
&nbsp;
<span class="co1">-- -----------------------------------------------------</span>
<span class="co1">-- Table `produits_having_couleurs`</span>
<span class="co1">-- -----------------------------------------------------</span>
<span class="kw1">CREATE</span>  <span class="kw1">TABLE</span> <span class="kw1">IF <span class="kw10">NOT</span> EXISTS</span> <span class="st0">`produits<span class="es1">_</span>having<span class="es1">_</span>couleurs`</span> <span class="br0">&#40;</span>
  <span class="st0">`produits<span class="es1">_</span>id`</span> <span class="kw4">INT</span> <span class="kw10">NOT</span> <span class="kw3">NULL</span> <span class="sy2">,</span>
  <span class="st0">`couleurs<span class="es1">_</span>id`</span> <span class="kw4">INT</span> <span class="kw10">NOT</span> <span class="kw3">NULL</span> <span class="sy2">,</span>
  <span class="kw1">PRIMARY KEY</span> <span class="br0">&#40;</span><span class="st0">`produits<span class="es1">_</span>id`</span><span class="sy2">,</span> <span class="st0">`couleurs<span class="es1">_</span>id`</span><span class="br0">&#41;</span> <span class="sy2">,</span>
  <span class="kw1">INDEX</span> <span class="st0">`phc<span class="es1">_</span>produits<span class="es1">_</span>id`</span> <span class="br0">&#40;</span><span class="st0">`produits<span class="es1">_</span>id`</span> <span class="kw1">ASC</span><span class="br0">&#41;</span> <span class="sy2">,</span>
  <span class="kw1">INDEX</span> <span class="st0">`phc<span class="es1">_</span>couleurs<span class="es1">_</span>id`</span> <span class="br0">&#40;</span><span class="st0">`couleurs<span class="es1">_</span>id`</span> <span class="kw1">ASC</span><span class="br0">&#41;</span> <span class="sy2">,</span>
  <span class="kw1">CONSTRAINT</span> <span class="st0">`phc<span class="es1">_</span>produits<span class="es1">_</span>id`</span>
    <span class="kw1">FOREIGN KEY</span> <span class="br0">&#40;</span><span class="st0">`produits<span class="es1">_</span>id`</span> <span class="br0">&#41;</span>
    <span class="kw1">REFERENCES</span> <span class="st0">`produits`</span> <span class="br0">&#40;</span><span class="st0">`produits<span class="es1">_</span>id`</span> <span class="br0">&#41;</span>
    <span class="kw1">ON</span> <span class="kw1">DELETE</span> <span class="kw1">CASCADE</span>
    <span class="kw1">ON</span> <span class="kw1">UPDATE</span> <span class="kw1">NO</span> <span class="kw1">ACTION</span><span class="sy2">,</span>
  <span class="kw1">CONSTRAINT</span> <span class="st0">`phc<span class="es1">_</span>couleurs<span class="es1">_</span>id`</span>
    <span class="kw1">FOREIGN KEY</span> <span class="br0">&#40;</span><span class="st0">`couleurs<span class="es1">_</span>id`</span> <span class="br0">&#41;</span>
    <span class="kw1">REFERENCES</span> <span class="st0">`couleurs`</span> <span class="br0">&#40;</span><span class="st0">`couleurs<span class="es1">_</span>id`</span> <span class="br0">&#41;</span>
    <span class="kw1">ON</span> <span class="kw1">DELETE</span> <span class="kw1">CASCADE</span>
    <span class="kw1">ON</span> <span class="kw1">UPDATE</span> <span class="kw1">NO</span> <span class="kw1">ACTION</span><span class="br0">&#41;</span>
<span class="kw1">ENGINE</span> <span class="sy1">=</span> <span class="kw1">InnoDB</span>
<span class="kw2">DEFAULT</span> CHARACTER <span class="kw1">SET</span> <span class="sy1">=</span> utf8<span class="sy2">;</span>
&nbsp;
<span class="kw1">SET</span> SQL_MODE<span class="sy1">=</span>@OLD_SQL_MODE<span class="sy2">;</span>
<span class="kw1">SET</span> FOREIGN_KEY_CHECKS<span class="sy1">=</span>@OLD_FOREIGN_KEY_CHECKS<span class="sy2">;</span>
<span class="kw1">SET</span> UNIQUE_CHECKS<span class="sy1">=</span>@OLD_UNIQUE_CHECKS<span class="sy2">;</span></pre></td></tr></table></div>

<p>Votre base de données étant créée, on va commencer par générer notre fichier YAML. Pensez à bien paramétrer le DSN dans le fichier bootstrap.php pour vous connecter à la base. Dans le répertoire <strong>doctrine_test</strong>, créez un répertoire <strong>yaml</strong> et un répertoire <strong>models</strong> accessibles en écriture pour Apache. On va ensuite créer un fichier <strong>generate_yaml.php</strong> contenant le code suivant :</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
2
3
</pre></td><td class="cc_syntax"><pre class="php"><span class="kw2">&lt;?php</span>
<span class="kw1">require_once</span><span class="br0">&#40;</span><span class="st_h">'bootstrap.php'</span><span class="br0">&#41;</span><span class="sy0">;</span>
Doctrine<span class="sy0">::</span><span class="me2">generateYamlFromDb</span><span class="br0">&#40;</span><span class="st_h">'yaml'</span><span class="sy0">,</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="st_h">'doctrine'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></td></tr></table></div>

<p>Si vous exécutez ce fichier, vous trouverez dans le répertoire <strong>yaml</strong> un fichier <strong>schema.yml</strong>. Vous pouvez éditer ce fichier pour voir à quoi ressemble notre modèle. Nous allons ensuite générer les fichiers de classe à proprement parler. Créez le fichier <strong>generate_model.php</strong> et insérez le code :</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
2
3
</pre></td><td class="cc_syntax"><pre class="php"><span class="kw2">&lt;?php</span>
<span class="kw1">require_once</span><span class="br0">&#40;</span><span class="st_h">'bootstrap.php'</span><span class="br0">&#41;</span><span class="sy0">;</span>
Doctrine<span class="sy0">::</span><span class="me2">generateModelsFromYaml</span><span class="br0">&#40;</span><span class="st_h">'yaml'</span><span class="sy0">,</span> <span class="st_h">'models'</span><span class="sy0">,</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="st_h">'generateTableClasses'</span> <span class="sy0">=&gt;</span> <span class="kw4">true</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></td></tr></table></div>

<p>Si vous l&#8217;exécutez , c&#8217;est maintenant dans le répertoire models que seront générés les fichiers. On y trouvera un répertoire <strong>generated </strong>dans lequel on trouvera les classes définissant nos tables, ainsi qu&#8217;une série de fichiers qui nous permettra par la suite de personnaliser nos classes.</p>
<p>Nous sommes maintenant fin prêts à utiliser Doctrine. Dans un prochain article nous verrons comment commencer à exploiter notre base de données.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coolcoyote.net/php-mysql/introduction-a-doctrine/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Dépendances et exceptions</title>
		<link>http://www.coolcoyote.net/php-mysql/dependances-et-exceptions</link>
		<comments>http://www.coolcoyote.net/php-mysql/dependances-et-exceptions#comments</comments>
		<pubDate>Sat, 09 Jan 2010 11:14:47 +0000</pubDate>
		<dc:creator>Denis S.</dc:creator>
				<category><![CDATA[PHP - MySQL]]></category>
		<category><![CDATA[classes]]></category>
		<category><![CDATA[dépendance]]></category>
		<category><![CDATA[exceptions]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.coolcoyote.net/?p=218</guid>
		<description><![CDATA[A l&#8217;heure où j&#8217;entends beaucoup parler d&#8217;objet, de framework, de dépendance faible, d&#8217;injection de dépendance etc. je me suis posé une question. Admettons que dans mon petit framework sans prétention j&#8217;ai envie que mes modules soient complètement indépendants, c&#8217;est-à-dire que je puisse les prendre un à un et les utiliser avec un projet complètement différent, [...]]]></description>
			<content:encoded><![CDATA[<p>A l&#8217;heure où j&#8217;entends beaucoup parler d&#8217;<strong>objet</strong>, de <strong>framework</strong>, de <strong>dépendance faible</strong>, <strong>d&#8217;injection de dépendance</strong> etc. je me suis posé une question. Admettons que dans mon petit framework sans prétention j&#8217;ai envie que mes modules soient complètement indépendants, c&#8217;est-à-dire que je puisse les prendre un à un et les utiliser avec un projet complètement différent, hors framework. <strong>Zend Framework</strong> fait cela. Cependant je me suis demandé comment gérer des exceptions personnalisées dans ce cas ?</p>
<p>En effet, dans mon framework, j&#8217;ai créé une classe d&#8217;exception qui hérite de <em>Exception </em>et qui rajoute des fonctionnalités comme par exemple une méthode permettant d&#8217;afficher le message d&#8217;erreur bien formaté en HTML avec un fond rouge et presque un gyrophare sur le dessus. Oui mais voilà, quand dans un de mes modules j&#8217;ai besoin d&#8217;utiliser une exception et que j&#8217;ai à afficher le message en utilisant une méthode personnalisée de mon exception, cela casse complètement l&#8217;indépendance de mon module. Je ne peux plus le sortir de son contexte car il dépend désormais de la classe d&#8217;exception de mon framework ce qui est contraire à ce que je veux.</p>
<p><span id="more-218"></span></p>
<p>J&#8217;ai vu que Zend Framework crée une classe d&#8217;exception spécifique pour son module héritée de la classe d&#8217;exception du framework, ce qui lui rend à peu près son indépendance puisqu&#8217;en changeant simplement la classe parent, on peut hériter directement de la classe <em>Exception</em>.</p>
<p>Par exemple pour le module de cache, on trouve cette classe d&#8217;exception:<br />
<code lang="php" escaped="true">&lt;?php<br />
class Zend_Cache_Exception extends Zend_Exception {}<br />
?&gt;</code><br />
En changeant la classe parent on rend le module indépendant:<br />
<code lang="php" escaped="true">&lt;?php<br />
class Zend_Cache_Exception extends Exception {}<br />
?&gt;</code><br />
Oui mais voilà, dans ce cas<em> Zend_Exception</em> qui hérite directement de <em>Exception </em>n&#8217;apporte rien de nouveau. Aucune nouvelle méthode, aucune fonctionnalité. Or dans mon cas, si j&#8217;utilise cette façon de procéder les méthodes personnalisées de ma classes d&#8217;exception ne seront plus disponibles lorsque je changerai la classe parent par <em>Exception</em>. Une seule conclusion m&#8217;est venue à l&#8217;esprit: je ne doit pas utiliser les fonctionnalités spéciales de ma classe d&#8217;exception dans mes modules. Dommage, car j&#8217;ai besoin d&#8217;afficher mes messages d&#8217;erreurs comme je le veux&#8230;</p>
<p>Et puis je me suis demandé si c&#8217;était vraiment le rôle de mon module de stopper l&#8217;exécution du programme pour afficher le message d&#8217;erreur. Non finalement. Si je prends pour exemple l&#8217;extension <strong>mysqli </strong>de PHP, elle ne bloque pas l&#8217;exécution du programme si la connexion à la base ne se fait pas. Elle se contente de fournir des méthodes pour récupérer les erreurs. C&#8217;est dans cette direction que je vais aller.</p>
<p>Tout d&#8217;abord, voici une structure de classe pour mon module avec un exemple d&#8217;exception :<br />
<code lang="php" escaped="true">&lt;?php<br />
class MonModule<br />
{<br />
    private $_error = NULL;</p>
<p>    public function __construct()<br />
    {<br />
        try {<br />
            if (!condition) {<br />
                throw new Exception('Message d\'erreur');<br />
            }</p>
<p>            // Suite du code exécuté<br />
        } catch (Exception $e) {<br />
            $this-&gt;_error = $e-&gt;getMessage();<br />
        }<br />
    }</p>
<p>    public function getError()<br />
    {<br />
        return $this-&gt;_error;<br />
    }<br />
}<br />
?&gt;</code><br />
Dans ce code on voir donc que mon module n&#8217;affiche pas le message d&#8217;erreur. Il se contente de le passer à un membre. Dans mon contrôleur, je vais pouvoir faire entrer ma classe d&#8217;exception personnalisée en action:<br />
<code lang="php" escaped="true">&lt;?php<br />
try {<br />
    $instance = new MonModule();</p>
<p>    if ($instance-&gt;getError()) {<br />
        throw new MyException($instance-&gt;getError());<br />
    }<br />
} catch (MyException $e) {<br />
    $e-&gt;methodePerso();<br />
}<br />
?&gt;</code><br />
Ici on travaille directement sur l&#8217;instanciation de la classe <strong>MonModule()</strong>, du coup la valeur retournée par le constructeur est forcément une instance, mais lors de l&#8217;utilisation de cette technique sur les méthodes de la classe, on peut améliorer la chose en retournant <em>false </em>:<br />
<code lang="php" escaped="true">&lt;?php<br />
class MonModule<br />
{<br />
    private $_error = NULL;</p>
<p>    public function maMethode()<br />
    {<br />
        try {<br />
            if (!condition) {<br />
                throw new Exception('Message d\'erreur');<br />
            }</p>
<p>            // Suite du code exécuté<br />
            return $this;<br />
        } catch (Exception $e) {<br />
            $this-&gt;_error = $e-&gt;getMessage();<br />
            return false;<br />
        }<br />
    }</p>
<p>    public function getError()<br />
    {<br />
        return $this-&gt;_error;<br />
    }<br />
}<br />
?&gt;</code><br />
Et dans le contrôleur :<br />
<code lang="php" escaped="true">&lt;?php<br />
try {<br />
    $instance = new MonModule();</p>
<p>    if (!$instance-&gt;maMethode()) {<br />
        throw new MyException($instance-&gt;getError());<br />
    }<br />
} catch (MyException $e) {<br />
    $e-&gt;methodePerso();<br />
}<br />
?&gt;</code><br />
Je ne sais pas si c&#8217;est la méthode idéale, mais au moins je suis sûr de conserver l&#8217;indépendance de mes classes et de mes exceptions.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coolcoyote.net/php-mysql/dependances-et-exceptions/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installation PHP5/Apache2.2/MySQL5 sous Windows</title>
		<link>http://www.coolcoyote.net/php-mysql/installation-php5apache22mysql5-sous-windows</link>
		<comments>http://www.coolcoyote.net/php-mysql/installation-php5apache22mysql5-sous-windows#comments</comments>
		<pubDate>Sat, 16 Aug 2008 13:38:54 +0000</pubDate>
		<dc:creator>Denis S.</dc:creator>
				<category><![CDATA[PHP - MySQL]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[installation]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://192.168.0.1/wordpress/?p=42</guid>
		<description><![CDATA[Cette installation est effectuée sous Windows XP Pro SP2, mais devrait fonctionner sous Vista sans problème. Elle est destinée à une installation en tant que plateforme de développement, pas à une installation de production.
Installation de PHP
Télécharger la dernière version de PHP sur php.net (la dernière version est la 5.2.6 au moment de cet article). Prenez [...]]]></description>
			<content:encoded><![CDATA[<p>Cette installation est effectuée sous Windows XP Pro SP2, mais devrait fonctionner sous Vista sans problème. Elle est destinée à une installation en tant que plateforme de développement, pas à une installation de production.</p>
<h3>Installation de PHP</h3>
<p>Télécharger la dernière version de PHP sur <a href="http://www.php.net" target="_blank">php.net</a> (la dernière version est la 5.2.6 au moment de cet article). Prenez la version <strong>zip package</strong>.</p>
<p>A la racine de votre disque dur <strong>c:</strong> créeez un répertoire <strong>php </strong>et dézippez-y l&#8217;archive PHP.</p>
<p><span id="more-42"></span></p>
<p>Le répertoire <strong>c:\php</strong> contient un certain nombre de fichier <strong>dll </strong>que nous allons maintenant copier dans le répertoire <strong>c:\windows\system32\</strong>. En voici la liste:</p>
<ul>
<li>fdftk.dll</li>
<li>gds32.dll</li>
<li>libeay32.dll</li>
<li>libmcrypt.dll</li>
<li>libmhash.dll</li>
<li>libmysql.dll</li>
<li>msql.dll</li>
<li>ntwdblib.dll</li>
<li>php5ts.dll</li>
<li>ssleay32.dll</li>
</ul>
<p>Puis copiez le fichier <strong>c:\php\php.ini-dist</strong> dans le répertoire <strong>c:\windows</strong>. Renommez le fichier <strong>c:\windows\php.ini-dist</strong> en <strong>c:\windows\php.ini</strong>.</p>
<p>Editez ensuite ce fichier avec votre bloc note.</p>
<p>Remplacez les lignes:</p>
<pre class="code">; Windows: "\path1;\path2"
;include_path = ".;c:\php\includes"</pre>
<p>par:</p>
<pre class="code">; Windows: "\path1;\path2"
include_path = ".;c:\php\includes"</pre>
<p>puis les lignes:</p>
<pre class="code">; Directory in which the loadable extensions (modules) reside.
extension_dir = "./"</pre>
<p>par:</p>
<pre class="code">; Directory in which the loadable extensions (modules) reside.
extension_dir = "c:\php\ext"</pre>
<p>Plus loin il y a les extensions dynamiques. Il faut activer celles que l&#8217;on veut utiliser en décommentant la ligne (supprimer le &#8216;;&#8217; devant la ligne). Nous allons activerles extensions suivantes:</p>
<pre class="code">extension=php_gd2.dll
extension=php_mbstring.dll
extension=php_mcrypt.dll
extension=php_mysql.dll
extension=php_mysqli.dll
extension=php_sockets.dll
extension=php_sqlite.dll
extension=php_xsl.dll
extension=php_zip.dll</pre>
<p>Ce sera ensuite à ajuster selon vos besoins</p>
<p>Enfin plus loin on a un bloc:</p>
<pre class="code">[mail function]
; For Win32 only.
SMTP = localhost
smtp_port = 25</pre>
<p>remplacez la ligne:</p>
<pre class="code">SMTP = localhost</pre>
<p>par le smtp de votre FAI. Pour orange par exemple:</p>
<pre class="code">SMTP = smtp.orange.fr</pre>
<p>Cela vous permettra d&#8217;envoyer des emails avec PHP</p>
<p>Sauvegardez votre fichier php.ini.</p>
<p>PHP est prêt, nous allons maintenant installer MySQL</p>
<h3>Installation de MySQL</h3>
<p>Rendez-vous sur la page <a href="http://dev.mysql.com/downloads/mysql/5.0.html#win32" target="_blank">http://dev.mysql.com/downloads/mysql/5.0.html#win32</a> pour télécharger la dernière version stable de MySQL. Prenez la version &laquo;&nbsp;Windows ZIP/Setup.EXE (x86)&nbsp;&raquo;</p>
<p>Décompressez l&#8217;archive et lancez l&#8217;exécutable. Personnellement je choisis la version &laquo;&nbsp;Custom&nbsp;&raquo; à installer. Ainsi à l&#8217;écran suivant je peux choisir le répertoire d&#8217;installation: <strong>c:\mysql</strong>. Je laisse les autres options telles quelles (tout est installé sauf les <strong>Developer Components</strong>).</p>
<p>A la fin de l&#8217;installation, vérifiez que la case &laquo;&nbsp;<strong>Configure the MySQL server now</strong>&nbsp;&raquo; est cochée et cliquez sur &laquo;&nbsp;<strong>Finish</strong>&laquo;&nbsp;.</p>
<p>Choisissez l&#8217;option &laquo;&nbsp;<strong>Reconfigure instance</strong>&nbsp;&raquo; puis &laquo;&nbsp;<strong>Detailed configuration</strong>&laquo;&nbsp;. Nous allons maintenant devoir configurer plusieurs options.</p>
<p>Selon votre machine, vous pouvez choisir soit &laquo;&nbsp;<strong>Developer Machine</strong>&laquo;&nbsp;, soit &laquo;&nbsp;<strong>Server Machine</strong>&laquo;&nbsp;. Si votre Windows vous sert à tout faire, choisissez &laquo;&nbsp;<strong>Developer Machine</strong>&nbsp;&raquo; ce qui limitera la mémoire utilisée par le service.</p>
<p>A l&#8217;écran suivant, choisissez &laquo;&nbsp;<strong>Multifunctionnal Database</strong>&laquo;&nbsp;.</p>
<p>Plus loin sélectionnez &laquo;&nbsp;<strong>Decision Support(DSS)/OLAP</strong>&laquo;&nbsp;.</p>
<p>Sur l&#8217;écran suivant laissez cochées les cases &laquo;&nbsp;<strong>Enable TCP/IP Networking</strong>&nbsp;&raquo; et &laquo;&nbsp;<strong>Enable Strict Mode</strong>&laquo;&nbsp;.</p>
<p>On nous demande ensuite de choisir le type de support de caractères que l&#8217;on veut. Choisissez &laquo;&nbsp;<strong>Best support For Multilingualism</strong>&laquo;&nbsp;.</p>
<p>Cochez ensuite la case &laquo;&nbsp;<strong>Include Bin directory in Windows PATH</strong>&laquo;&nbsp;.</p>
<p>On nous propose ensuite de configurer le compte root. Dans &laquo;&nbsp;<strong>Current root password</strong>&nbsp;&raquo; laissez vide. Puis dans les deux autres cases, choisissez votre mot de passe root. En dessous on nous propose d&#8217;accepter les connexions root à partir d&#8217;autres machines. Si vous n&#8217;accédez pas à votre serveur MySQL à partir d&#8217;une autre machine, ce qui sera probablement le cas, ne cochez pas cette case.</p>
<p>En dessous encore on nous propose de créer un compte anonyme. Personnellement je ne le fais pas, je préfère gérer ensuite avec phpMyAdmin. Il suffit ensuite de cliquer sur le bouton &laquo;&nbsp;<strong>Execute</strong>&nbsp;&raquo; de l&#8217;écran suivant.</p>
<h3>Installation d&#8217;Apache</h3>
<p>Téléchargez la dernière version 2.2.x d&#8217;Apache à cette adresse: <a href="http://httpd.apache.org/download.cgi " target="_blank">http://httpd.apache.org/download.cgi </a>(prenez la version Windows MSI sans le mod_ssl)</p>
<p>Lancez l&#8217;installation. On vous demandera d&#8217;entrer certaines informations:</p>
<ul>
<li>Network Domain: laissez <strong>example.org</strong></li>
<li>Server Name: mettez &laquo;&nbsp;<strong>localhost</strong>&laquo;&nbsp;</li>
<li>Administrator&#8217;s Email Address: laissez <strong>admin@example.org</strong></li>
<li>Sélectionnez également &laquo;&nbsp;<strong>for All Users, on Port 80&#8230;</strong>&laquo;&nbsp;</li>
</ul>
<p>Choisissez ensuite l&#8217;installation &laquo;&nbsp;<strong>Custom</strong>&nbsp;&raquo;</p>
<p>Vous pourrez alors choisir le répertoire d&#8217;installation du serveur. Mettez le répertoire <strong>c:\apache</strong></p>
<p>rendez-vous ensuite dans le répertoire <strong>c:\apache\conf</strong> et éditez le fichier <strong>httpd.conf</strong> avec votre bloc notes.</p>
<p>Après la ligne</p>
<pre class="code">#LoadModule vhost_alias_module modules/mod_vhost_alias.so</pre>
<p>Rajoutez la ligne suivante:</p>
<pre class="code">LoadModule php5_module "c:/php/php5apache2_2.dll"</pre>
<p>Modifiez la ligne</p>
<pre class="code">DocumentRoot "C:/Apache/htdocs"</pre>
<p>afin d&#8217;y mettre votre répertoire contenant tous vos sites web. Par exemple:</p>
<pre class="code">DocumentRoot "C:/sitesweb"</pre>
<p>Sachant que ce répertoire sera la racine de vos sites (si ce répertoire n&#8217;existe pas encore, créez le maintenant).</p>
<p>Remplacez ensuite la ligne:</p>
<pre class="code">&lt;Directory "C:/Apache/htdocs"&gt;</pre>
<p>En y mettant  à nouveau votre répertoire racine</p>
<pre class="code">&lt;Directory "C:/sitesweb"&gt;</pre>
<p>Modifiez la ligne:</p>
<pre class="code">DirectoryIndex index.html</pre>
<p>par</p>
<pre class="code">DirectoryIndex index.html index.php</pre>
<p>Sous la ligne:</p>
<pre class="code">AddType application/x-gzip .gz .tgz</pre>
<p>Rajoutez la ligne</p>
<pre class="code">AddType application/x-httpd-php .php</pre>
<p>Sauvegardez votre fichier de configuration. Dans la systray de Windows vous avez l&#8217;icône d&#8217;Apache. Double cliquez dessus et faites &laquo;&nbsp;<strong>Restart</strong>&laquo;&nbsp;. Si tout a été fait correctement, il ne devrait pas y avoir de problème.</p>
<p>Pour tester, on peut se rendre dans le répertoire <strong>c:\sitesweb</strong> (ou votre répertoire racine) et créez le fichier <strong>index.php</strong> avec le bloc-notes et placez-y le code suivant:</p>

<div class="cc_syntax-container"><table><tr><td class="line-numbers"><pre>1
2
3
</pre></td><td class="cc_syntax"><pre class="php"><span class="kw2">&lt;?php</span>
<span class="kw3">phpinfo</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="sy1">?&gt;</span></pre></td></tr></table></div>

<p>Sauvegardez. Ouvrez maintenant votre navigateur internet et dans la barre d&#8217;adresse tapez <strong>http://localhost</strong></p>
<p>Si tout se passe bien vous devriez avoir une page de présentation PHP</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coolcoyote.net/php-mysql/installation-php5apache22mysql5-sous-windows/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Documentation PHP en ligne</title>
		<link>http://www.coolcoyote.net/php-mysql/documentation-php-en-ligne</link>
		<comments>http://www.coolcoyote.net/php-mysql/documentation-php-en-ligne#comments</comments>
		<pubDate>Mon, 04 Aug 2008 10:58:17 +0000</pubDate>
		<dc:creator>Denis S.</dc:creator>
				<category><![CDATA[PHP - MySQL]]></category>
		<category><![CDATA[documentation]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://192.168.0.1/wordpress/?p=29</guid>
		<description><![CDATA[J&#8217;attendais vraiment ça avant de mettre le blog en ligne. Après plusieurs semaines de bataille avec le nouveau système de compilation de la documentation PHP, j&#8217;ai quand même réussis à la compiler pour en faire à peu près ce que j&#8217;en voulais.
Autant dire que ça n&#8217;a pas été simple et que je m&#8217;amuserai pas à [...]]]></description>
			<content:encoded><![CDATA[<p>J&#8217;attendais vraiment ça avant de mettre le blog en ligne. Après plusieurs semaines de bataille avec le nouveau système de compilation de la documentation PHP, j&#8217;ai quand même réussis à la compiler pour en faire à peu près ce que j&#8217;en voulais.</p>
<p>Autant dire que ça n&#8217;a pas été simple et que je m&#8217;amuserai pas à refaire ça tous les jours. Quoi qu&#8217;il en soit je pourrai désormais la recompiler régulièrement sachant qu&#8217;à chaque mise à jour il y a plein de bugs qu&#8217;il faut corriger avant de pouvoir recompiler.</p>
<p>Allez, <a href="http://www.coolcoyote.net/phpweb/">direction la doc</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.coolcoyote.net/php-mysql/documentation-php-en-ligne/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

