<?xml version="1.0" encoding="iso-8859-1" standalone="no"?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "/usr/local/share/xml/docbook/4.2/docbookx.dtd">
<article class="techreport" lang="fr">

<!--  ================================= Entetes info ============================= -->
  <articleinfo>
    <date>Mars- Avril 2007</date>
    <author>
      <firstname>Ivan</firstname>
      <surname>Kurzweg</surname>  
      <email>ik-r@wanadoo.fr</email>
    </author>

    <title>Programmation en PHP</title>

    <copyright>
      
      <year>2007</year>
      <holder>Ivan KURZWEG, <emphasis>ik-r@wanadoo.fr</emphasis></holder>
    </copyright>

    <legalnotice>
      <para>Permission to use, copy, modify, and distribute this documentation for any purpose with or without fee is here by granted, provided that the above copyright notice and this permission notice appear in all copies.
</para>        
    </legalnotice>

    <keywordset>
      <keyword>Html, css, cours, initiation logiciel libre, </keyword>
    </keywordset>

  </articleinfo>
  
  <abstract> 
    <para>Ce document présente une introduction à la programmation PHP appliqué au développement Internet. Il ne se veut bien sûr pas exhaustif, et de nombreuses documentations peuvent être trouvées en complément sur Internet. Dans tous les cas, le site de référence sera <ulink url="http://www.php.net">www.php.net</ulink> qui fournira l'ensemble de la documentation officielle.</para>
  </abstract>








<!--  ================================= Chapitre 1 ============================= -->
  <sect1>
    <title>Programmation Php -  Notions de bases</title>
    <sect2>
      <title>Présentation de Php</title> 
    <para><acronym>Php</acronym> pour <foreignphrase>PHP:Hypertext Preprocessor</foreignphrase> est un langage de programmation de script, spécialement conçu pour permettre la création de pages Web dynamiques. Ce n'est pas le seul langage de programmation que l'on utilise sur le net (Ruby, Python, Perl, ..) mais c'est le plus répandu : plus de 13 millions de domaines l'utilisaient en 2004. 
</para>
      <para>IL dispose en effet de plusieurs avantages : </para>
<para><itemizedlist>
	  <listitem>
	  <para>Rapidité</para></listitem>
	  <listitem>
	    <para>Gratuité</para></listitem>
	  <listitem>
	    <para>Facile à utiliser</para></listitem>
	  <listitem>
	    <para>Multi OS</para></listitem>
	  <listitem>
	    <para>Sources de documentations multiples</para></listitem>
	  <listitem>
	    <para>Support des bases de données</para></listitem>
</itemizedlist></para>
      <para>Dans le cas de la programmation de pages Web dynamiques, le code PHP est inclus dans le code HTML. L'interpréteur PHP est appelé par le serveur Web, lors d'une demande d'une page <filename>.php</filename>. Le contenu du code PHP est ainsi remplacé par les <emphasis>sorties</emphasis> du programme. </para>
<figure>
        <title>Accès à une page Php</title>

        <mediaobject>
          <imageobject>
            <imagedata fileref="images/php1.jpg" />
          </imageobject>
        </mediaobject>
      </figure>
<orderedlist>
 <listitem>
	    <para>Le client envoi une requête (URL) au serveur WEB http://www.domaine.com/page1.php par exemple.
</para>
	  </listitem>
	  <listitem>
	    <para>Le serveur HTTP récupère le fichier sur le disqeu</para>
	  </listitem>
 <listitem>
	    <para>Grâce à l'extension. (.PHP) du fichier, il le transmet au parser PHP pour être éxécuté.</para>
	  </listitem>
 <listitem>
	    <para>Le résultat (sauf erreur) est retourné au client , sous forme de page HTML</para>
	  </listitem></orderedlist><example>
  <title>Un premier programme </title>
	  <programlisting width="60">
La ligne de code suivante 	  
<![CDATA[<?]]><co id="begin_hello" /><![CDATA[echo "<p>Hello World</p>"; ?>]]> <co id="end_hello" />

donnera l'interprétation suivante dans la page HTML
<![CDATA[<p>Hello World</p>]]>

Qui donnera dans la navigateur  

<![CDATA[
Hello World ]]>

 </programlisting>
<calloutlist>

   <callout arearefs="begin_hello">
      <para>
      Caractères spéciaux pour débuter l'inclusion de code PHP
      </para>
   </callout>
   <callout arearefs="end_hello">
      <para>
      Caractères spéciaux pour terminer l'inclusion de code PHP
      </para>
   </callout>
</calloutlist>

</example>
</sect2>
    <sect2>
      <title>Instructions</title>
      <para>
Lors de l'interprétation d'une page PHP, le serveur Web <foreignphrase>parse</foreignphrase> les lignes de la page. Chaque fois qu'il rencontre les caractères <command><![CDATA[<?]]></command>,  il demande alors à l'interpréteur Php d'exécuter le <emphasis>bloc d'instructions</emphasis>. Les <emphasis>instructions</emphasis> sont excéutées séquentiellement, du haut de la page vers le bas, jusque'au caractère <command><![CDATA[?>]]></command>. Chaque instruction est terminée par un <command>;</command>. Ainsi, les espaces et les tabulations, et même les retours à la ligne n'ont pas d'influence sur le code. 
</para> 
 <para>Les commentaires sont ajoutés aux codes en utilisant les caractères <command>//</command> ou <command>#</command> (ce qui indique à Php que tous les caractères qui suivent sur la ligne ne doivent pas être interprétés) ou en encadrant le texte par  <command>/ *</command> et <command>* /</command>.
</para>
<para>
Ainsi le premier exemple peut également s'écrire :
<example>
  <title>Des commentaires et des espaces .. </title>
 <programlisting>
<![CDATA[
<?
// Affichage texte
echo "<p>
	  Hello World </p>"; 
#sorties code Php
?>
]]>

 </programlisting>
</example>
</para>
<para>
Certaines instructions peuvent contenir des <emphasis>expressions</emphasis>. Les instructions sont exécutés, les expressions sont évaluées. </para>
<para>
Les instructions peuvent être regroupées dans des blocs, délimités par { }. Un bloc garanti que toutes les instructions sont exécutées de manière séquentielles de la première à la dernière.</para>
<example>
  <title>Les blocs d'instructions</title>
	  <screen  width="60">
<![CDATA[
if (le cyclone revient)]]><co id="cond" />
<![CDATA[{]]><co id="begin" />
 <![CDATA[  rentrer les animaux;
   faire des réserves;]]>
<![CDATA[}]]><co id="end" />

 </screen>
<calloutlist>
   <callout arearefs="cond">
      <para>
      Si la condition est respectée ...
      </para>
   </callout>

   <callout arearefs="begin">
      <para>
      Début du bloc
      </para>
   </callout>
   <callout arearefs="end">
      <para>
      Fin du bloc
      </para>
   </callout>
</calloutlist>

</example>

    </sect2>


    <sect2>
      <title>Variables</title>
   <para>
Une variable est un espace mémoire utilisé pour stocker une information. Elle est définie par un nom. On peut affecter une valeur à une variable, et utiliser cette valeur plus tard dans le programme. Un exemple d'utilisation des variables peut être de stocker les données entrées par un utilisateur. 
    </para>
      <para>
Si les noms des variables sont au choix du programmeur, il est important de noter quelques règles de nommages :
<itemizedlist>
	  <listitem>
	    <para>les noms de variables commencent par un $</para></listitem>
	  <listitem>
	    <para>les noms de variables sont de longueur quelconque</para></listitem>
	  <listitem>
	    <para>les noms de variables peuvent contenir des chiffres, des lettres et le signe underscore</para></listitem>
	  <listitem>
	    <para>les noms des variables sont sensibles à la casse.</para></listitem></itemizedlist></para>

      <para>Contrairement à beaucoup d'autres langages, la déclaration des variables n'est pas une obligation en Php. Lorsqu'elle est omise, cette déclaration est implicite au moment de la première affectation. <emphasis>L'affectation</emphasis> est l'instruction qui permet de stocker une valeur dans une variable, elle est définie par le signe <command>=</command>.</para>
<para>C'est donc la première affectation qui détermine le type de la variable. Le type d'une variable représente le type de données qu'elle va pouvoir contenir : numérique, caractère, tableau, ...</para>
<example><title>Affectations et variables</title>
<programlisting>
<![CDATA[
<p>Hello World!
<? $age = 33; 
   $nom = "Ivan"; ?>
<br />Hello <? echo $nom; ?>
<br />Tu as <? echo $age; ?> ans
</p>
]]>
</programlisting>
</example> 
<example><title>Variables et inclusion de code HTML</title>
<programlisting>
<![CDATA[
<p>Un exemple d'inclusion de code Php avec des variables 
pour stocker par exemple une URL
<? $base_url = "http://www.kurzweg.info"; ?>
<br />La racine de ce site se trouve 
<a href="<? echo $base_url?>"alt="racine">ici</a> 
</p>
]]>
</programlisting>
</example> 
      <note><para>Il est possible de supprimer une variable (et pas seulement sa valeur) en utilsant la fonction <command>unset($var)</command>.</para></note>
</sect2>
<sect2><title>Opérateurs</title>
<para>Nous avons vu comment déclarer des variables et leur affecter des valeurs. Voyons maintenant comment manipuler ces valeurs :</para>
<sect3><title>Opérateurs arithmétiques</title>
<para>
              <table>
                  <title>Opérateurs arithmétiques</title>

                  <tgroup cols="2">
       <colspec colwidth="*" colnum="1" colname="op"/>
        <colspec colwidth="3*"   colnum="2" colname="desc"/>
                    <thead>
                      <row>
                        <entry><emphasis role="bold" >Opérateur</emphasis></entry>
                        <entry><emphasis role="bold">Description</emphasis></entry>
                      </row>
		    </thead>
		    <tbody>
                      <row>
                        <entry>+</entry>
                        <entry>Addition</entry>
                      </row>
                      <row>
                        <entry>-</entry>
                        <entry>Soustraction</entry>
                      </row>
                      <row>
                        <entry>*</entry>
                        <entry>Multiplication</entry>
                      </row>
                      <row>
                        <entry>/</entry>
                        <entry>Division</entry>
                      </row>
                      <row>
                        <entry>%</entry>
                        <entry>Modulo (reste de la division entière)</entry>
                      </row>
                    </tbody>
                  </tgroup>
                </table>
</para>
</sect3>
<sect3><title>Opérateurs de comparaison</title>
<para>Les opérateurs de comparaison permettent d'obtenir une valeur booléenne VRAI ou FAUX selon le résultat de l'expression : 
              <table pgwide="0" >
                  <title>Opérateurs de comparaison</title>

                  <tgroup cols="2">
       <colspec colwidth="*" colnum="1" colname="op"/>
        <colspec colwidth="3*"   colnum="2" colname="desc"/>
                    <thead>
                      <row>
                        <entry><emphasis role="bold" >Opérateur</emphasis></entry>
                        <entry><emphasis role="bold">Description</emphasis></entry>
                      </row>
		    </thead>
		    <tbody>
                      <row>
                        <entry>==</entry>
                        <entry>Egalité</entry>
                      </row>
                      <row>
                        <entry>&gt;</entry>
                        <entry>Strictement supérieur</entry>
                      </row>
                      <row>
                        <entry>&gt;=</entry>
                        <entry>Supérieur ou égal</entry>
                      </row>
                      <row>
                        <entry>&lt;</entry>
                        <entry>Strictement inférieur</entry>
                      </row>
                      <row>
                        <entry>&lt;=</entry>
                        <entry>Inérieur ou égale</entry>
                      </row>
                      <row>
                        <entry>!=</entry>
                        <entry>Non égalité</entry>
                      </row>                      <row>
                        <entry>&lt;&gt;</entry>
                        <entry>Non égalité</entry>
                      </row>
                    </tbody>
                  </tgroup>
                </table>
</para>
</sect3>
<sect3><title>Opérateurs logiques</title>
<para>Les opérateurs logiques permettent par exemple de combiner les résultats de comparaisons. Il renvoient la valeur booléenne VRAI ou FAUX.
              <table>
                  <title>Opérateurs logiques</title>

                  <tgroup cols="2">
       <colspec colwidth="*" colnum="1" colname="op"/>
        <colspec colwidth="3*"   colnum="2" colname="desc"/>
                    <thead>
                      <row>
                        <entry><emphasis role="bold" >Opérateur</emphasis></entry>
                        <entry><emphasis role="bold">Vrai quand ...</emphasis></entry>
                      </row>
		    </thead>
		    <tbody>
                      <row>
                        <entry>OR</entry>
                        <entry>une des deux opérandes est VRAI</entry>
                      </row>
                      <row>
                        <entry>AND</entry>
                        <entry>les deux opérandes sont VRAI</entry>
                      </row>
                      <row>
                        <entry>XOR</entry>
                        <entry>Uniquement lorsqu'un opérande est VRAI, pas les deux</entry>
                      </row>
                    </tbody>
                  </tgroup>
                </table>
</para>
</sect3>
</sect2>


<sect2>
      <title>Tableaux</title>
      <para>
Les tableaux sont des structures de données permettant de stocker plusieurs valeurs dans une même variable. Très utilisés en PHP, on dispose de tableaux à une ou plusieurs dimensions.</para>
<sect3>
	<title>Tableau à une dimension</title>
	<para>Un tableau à une dimension permet donc de stocker plusieurs valeurs<emphasis> de même type</emphasis> dans une même variable. L'accès à chaque cellule du tableau se fait en utilisant un indice : une entier commençant à 0 ou une chaîne de caractère identifiant la cellule.</para>
<para>
<informalexample>
<programlisting><![CDATA[
Exemple : 
$prof[0] = "Assoune";
$prof[1] = "Obré";
$prof[2] = "Lausin";
$prenoms_enseignant['Assoune'] = "Maximin";
$prenoms_enseignant['Obré'] = "Philippe";
$prenoms_enseignant['Lausin'] = "Benoit";
]]></programlisting></informalexample>
</para>
	<para>Il est possible de déclarer et d'affecter des valeurs à un tableau en utilisant le constructeur<command> array()</command>. </para>
<para>
<informalexample>
<programlisting><![CDATA[
Exemple : 
$prof = array("Assoune", "Obré", "Lausin");
$prenoms_enseignant = array('Assoune' => "Maximin",
     'Obré' => "Philippe",
     'Lausin' => "Benoit");
]]></programlisting></informalexample>
</para>
</sect3>
<sect3>
	<title>Tableau à plusieurs dimension</title>
	<para>Les tableaux à plusieurs dimensions permettent de stocker plusieurs valeurs dans chaque cellule du tableau. Il faut néanmoins respecter l'ordre et le type de chaque valeur.</para>
<para>
<informalexample>
<programlisting><![CDATA[
Exemple : 
$prof[0][0] = "Assoune";
$prof[1][0] = "Obré";
$prof[2][0] = "Lausin";
$prof[0][1] = "Maximin";
$prof[1][1] = "Philippe";
$prof[2][1] = "Benoit";
]]></programlisting></informalexample>
</para>
</sect3>
<!--  
    <sect3>
	<title>Fonctions sur les tableaux</title>
	<para>Il existe un certain nombre de fonctions prédéfinies en Php, dont voici une liste non exhaustive :</para>
<table>
                  <title>Fonctions concernant les tableaux</title>

                  <tgroup cols="3">
        <colspec colnum="1" colname="fonc" colwidth="*"/>
        <colspec colnum="2" colname="desc" colwidth="2*"/>
        <colspec colnum="3" colname="ex" colwidth="3*"/>
                    <thead>
                      <row>
                        <entry><emphasis role="bold">Fonctions</emphasis></entry>
                        <entry><emphasis role="bold">Commentaires</emphasis></entry>
                        <entry><emphasis role="bold">Exemple</emphasis></entry>
                      </row>
		    </thead>
		    <tbody>
                    <row>
		<entry><command><computeroutput><![CDATA[count($var) ]]></computeroutput></command></entry>
                        <entry>compte le nombre d'éléments affectés</entry>
		<entry><computeroutput><programlisting>
<![CDATA[$dept = array ("974","972");
$nb = count($dept); 
 ]]></programlisting></computeroutput></entry>
                      </row> 
                                <row>
		        <entry><command><![CDATA[sort($var) ]]></command></entry>
                        <entry>trie les éléments selon un ordre numérique ou alphabétique et réaffecte les indices du tableau
</entry>
		        <entry><programlisting><![CDATA[$dept=array ("des","dpa","dbe");
sort($dept);
while (list($indice, $val)
=each($dept) )
{ echo ("$indice - $val");
    // "0 - dbe" puis "1 - des"
    // puis "2 - dpa"
}
 ]]></programlisting></entry>
                      </row>                      <row>
		        <entry><command><![CDATA[asort($var) ]]></command></entry>
                        <entry>trie les éléments mais ne réaffecte pas les indices
</entry>
		        <entry><programlisting><![CDATA[$dept=array ("des","dpa","dbe");
asort($dept);
    // "2 - dbe" puis "0 - des"
    // puis "1 - dpa"
 ]]>
</programlisting></entry>
                      </row>
	            </tbody>
	          </tgroup>
</table> 
</sect3>
-->
    </sect2>  

    <sect2>
      <title>Exercices d'applications</title>
      <sect3><title>Analyse de code</title>
   <para>Interprétez et corrigez si nécessaires les extraits de code suivants : 

<orderedlist>
	  <listitem>
<programlisting><![CDATA[$string = 'c'est surement un probleme de guillemets';
echo $string]]></programlisting></listitem>
	  <listitem><programlisting><![CDATA[$age = 12;
$result1 = "$age";
$result2 = "$age';
echo $result1;
echo "<br />";
echo $result2;]]></programlisting></listitem>
	  <listitem><programlisting><![CDATA[$nb = 10;
$ch1 = "Il y a '$nb' personnes connectées";
$ch2 = `Il y a "$nb" personnes connectées. ';
echo $ch1,"<br />\n";
echo $ch2;]]></programlisting></listitem>
	  <listitem><programlisting><![CDATA[$string1 = `Hello';
$string2 = `World!';
$stringall = $string1.$string2;
echo $stringall;]]></programlisting></listitem>


	  <listitem><programlisting><![CDATA[$nix = "BSD";
echo "Free$nix, Open$nix, PC$nix sont tous des Unix libres ...";]]></programlisting></listitem>

	  <listitem><programlisting><![CDATA[$number = 2;
$string = "Hello";
$combined = $number + $string;
$combined2 = $number.$string;
echo $combined;
echo <br />;
echo $combined2;]]></programlisting></listitem>
	  <listitem>
<programlisting><![CDATA[
$cpt=4;
$cpt+=2;
$cpt-=3;
$cpt*=2;
$cpt/=3;
echo $cpt;]]></programlisting></listitem></orderedlist>

 </para></sect3>
      <sect3><title>Instructions simples</title>
<para>Ecrivez le code permettant d'inverser le contenu de deux variables $x et $y. (au départ, $x contient 2 et $y contient 4, et c'est l'inverse en fn de programme). Le programme devra afficher le contenu des variables avant et après le traitement.</para>
      <para>Ecrivez une page PHP qui fournit le code HTML affichant sur la même page : 
<orderedlist>
	  <listitem>
	    <para>La surface et la circonférence d'un cercle de 2cm de rayon (PI et le rayon devront être stockés dans des variables)</para>
	  </listitem>
	  <listitem>
	    <para>Le résultat de l'évaluation de l'expression <command>((VRAI et FAUX) OU VRAI) ET FAUX</command></para>
	  </listitem> 
	  <listitem>
	    <para>Le résultat de l'évaluation de l'expression <command>((VRAI et FAUX) OU (VRAI ET FAUX))</command></para>
	  </listitem> 
	  <listitem>
	    <para>La phrase <computeroutput>la date actuelle est :date et il est : heure</computeroutput></para>
	  </listitem> 
	  <listitem>
	    <para>Le nom de la machine</para>
	  </listitem>
	  <listitem>
	    <para>Un lien vers les différentes informations sur les modules et les versions de PHP disponibles sur votre machine.</para>
	  </listitem>
	</orderedlist>

</para></sect3>
      <sect3><title>Fiche stagiaire</title>
<para>Reprenez la fiche stagiaire créée dans le cours HTML, et stockez toutes les valeurs (nom, prénom, etc ..) dans la première case d'un tableau (à plusieurs dimensions). Affichez ensuite la page en utilisant ce tableau.</para></sect3>
    </sect2>
  </sect1>






<!--  ================================= Chapitre 2 ============================= -->
<sect1>
    <title>Structures de contrôles</title>

    <sect2>
      <title>Conditionnelles</title>
      <sect3><title><command>if</command></title>
      <para>





Les structures conditionnelles permettent de n'exécuter un bloc d'instructions que si une condition est réalisée. Le synopsys de la conditionnelle est le suivant : 
<informalexample>
<programlisting><computeroutput>
if ( condition1 ...<co id="id1" /> )
{
  <replaceable> Bloc d'instructions 1..</replaceable><co id="id2" />
}
elseif ( condition2 ... ) <co id="id3" />
   {
      <replaceable>Bloc d'instructions 2..</replaceable><co id="id4" />
   }
   else<co id="id5" />
   {
   <replaceable>Bloc d'instructions 3..</replaceable>
   }
<co id="id6" />
</computeroutput></programlisting>
<calloutlist>
   <callout arearefs="id1">
      <para>
      Une <emphasis>expression</emphasis> dont l'évaluation donne VRAI ou FAUX
      </para>
   </callout>
   <callout arearefs="id2">
      <para>
      Si la condition 1 est vrai alors tout le bloc 2 est exécuté et  le programme va en 6
      </para>
   </callout>
   <callout arearefs="id3">
      <para>
      Si la condition 1 est FAUX alors  la valeur de la condition 3 est testée
      </para>
   </callout>
   <callout arearefs="id4">
      <para>
      Si la condition 2 est VRAI alors  le bloc 4  est exécuté et  le programme va en 6
      </para>
   </callout>
   <callout arearefs="id5">
      <para>
      Si la condition 2 est FAUSSE alors le bloc 5  est exécuté et  le programme va en 6
      </para>
   </callout>   <callout arearefs="id6">
      <para>
      Fin de la conditionnelle
      </para>
   </callout>
</calloutlist></informalexample>
     </para>
<para>Voici un exemple d'enchaînement de conditionnelles : 
<example>
<title>Emboitements de condition</title>
<programlisting>
<![CDATA[
if ($country == "Germany" )
{
   $version = "German";
   $message = " Sie sehen unseren Katalog auf Deutsch";
}
elseif ($country == "France" )
  {
     $version = "French";
     $message = " Vous verrez notre catalogue en francais";
   }
   elseif ($country == "Italy" )
      {
         $version = "Italian";
         $message = " Vedrete il nostro catalogo in Italiano";
      }
      else
      {
         $version = "English";
         $message = "You will see our catalog in English";
      }
echo "$message<br>";

]]>
</programlisting>
</example></para>
</sect3>
      <sect3><title>Le <command>Switch</command></title>
	<para>Nous avons vu dans l'exemple précédent la nécessité de renoter plusieurs fois le même test d'égalité. Dans le cas de multiples tests de la valeur d'une variable, l'écriture peut devenir vite fastidieuse. C'est là qu'intervient le <command>switch</command> : 
<informalexample>
<programlisting>switch ( $variable )
{
  case value :
     bloc d'instructions
     break;
  case value :
     bloc d'instructions
     break;
  ...
  default:
     bloc d'instructions
     break;
}
</programlisting></informalexample>
Il faut bien noter ici que l'on ne peut tester que la valeur d'une seule variable !</para>
<para>Un exemple d'utilisation du switch : 

<example>
<title>Emboitements de condition</title>
<programlisting>
<![CDATA[

switch ( $dept )
{
  case 974 :
     $dept_nom = "Réunion";
     break;
  case 972 : 
     $dept_nom = "Guyane";
  default:
     $dept_nom = "France métropolitaine";
     break;
}

]]>
</programlisting>
</example></para>

</sect3>
    </sect2>
   <sect2>
      <title>Répétitives</title>
      <para>
Les structure répétitives (itératives) permettent de répeter un certain nombre de fois un bloc d'instructions. Nous en étudierons deux, la boucle <command>for</command> et la boucle <command>while</command></para>
<sect3>
	<title>La boucle <command>for</command></title>
	<para>L'instruction <command>for</command> permet de répeter un bloc d'instructions pour un nombre de fois défini. Elle doit définir la variable qui sera modifiée à chaque itération, sa valeur de départ, la valeur de fin de boucle, et l'opération à effectuer à chaque itération :
</para><para>

<example>
<title>Affichage des nombres inférieurs à 100</title>
	    <informalexample>
<programlisting><computeroutput>
<![CDATA[
<? 
for ($cpt=1;$cpt<100;$cpt++)
{
	echo "$cpt<br />";
}
?>
]]>
</computeroutput></programlisting></informalexample>
</example>

<example>
<title>Calcul de la somme des nombres pairs inférieurs à 100</title>
<programlisting><computeroutput>
<![CDATA[
<? 
$som=0;
$nb=100;
for ($cpt=1;$cpt<$nb+1;$cpt+=2)
{	
	$som=$som+$nb;
}
echo "La somme des $nb premiers entiers est de $som";
?>
]]>
</computeroutput></programlisting>
</example>


 </para>
</sect3>
<sect3>
	<title>La boucle <command>while</command></title>
	<para>L'instruction <command>while</command> permet de répeter un bloc d'instructions tant qu'une condition n'est pas remplie. Elle suit le synopsys suivant :
<informalexample>
<programlisting><computeroutput>
while (condition<co id="id31" />)
{
    bloc d'instructions ... ;
}
</computeroutput></programlisting>
<calloutlist>
   <callout arearefs="id31">
      <para>
       tant que cette condition est VRAI, on exécute le bloc et on réévalue la condition. 
      </para>
   </callout>
</calloutlist></informalexample></para>
<para>Bien sûr, il est à la charge du programmeur de bien s'assurer que la condition d'exécution de la boucle est modifiée et passe à un moment à FAUX .. sinon, on est dans le cas d'une boucle infinie.</para>
<example>
<title>Affichage des nombres inférieurs à 100</title>
<programlisting><computeroutput>
<![CDATA[
<? 
$cpt=1;
while ($cpt<100)
{
	echo "$cpt<br />";
	$cpt++;
}
?>
]]>
</computeroutput></programlisting>
</example>
<example>
<title>Une boucle infinie !!</title>
<programlisting><computeroutput>
<![CDATA[
<? 
$cpt=1;
while ($cpt<100)
{
	echo "$cpt<br />";
	//$cpt++; on commente la ligne, la valeur de $pt ne changera plus, 
        //la boucle ne sarrêtera pas
}
?>
]]>
</computeroutput></programlisting>
</example>
</sect3>
    <sect3>
	<title>Sortie d'une boucle</title>
	<para>Même si les boucles devraient être écrites pour s'arrêter d'elles mêmes, il peut être intéressant de forcer la sortie, avec l'instruction <command>break</command>. <command>break</command> permet de sortir complètement de la boucle et de reprendre le cours du programme après le bloc d'instructions.
<informalexample>
<programlisting><computeroutput>
<![CDATA[
$cpt = 0;
while ( $cpt < 5 )
{
  $cpt++;
  If ( $cpt == 3 )
  {
      echo "break<br>";
      break;
  }
  echo "Fin de boucle: cpt=$cpt<br>";
}
echo "Sortie de boucle<p>";
]]>

</computeroutput></programlisting></informalexample></para>


</sect3>

<sect3>
	<title>La boucle <command>foreach</command></title>
	<para>L'instruction <command>foreach</command> permet de faire des itérations sur les éléments d'un tableau. Elle suit le synopsys suivant :
<informalexample>
<programlisting><computeroutput>
foreach ($array<co id="id41" /> as $value<co id="id42" />;)
{
    bloc d'instructions ... ;
}
</computeroutput></programlisting>
<calloutlist>
   <callout arearefs="id41">
      <para>
        Le tableau qui va être parcouru
      </para>
   </callout>
   <callout arearefs="id42">
      <para>
        La variable qui contiendra la valeur de chaque cellule à chaque itération
      </para>
   </callout>
   
</calloutlist></informalexample>
</para>
<para>
En reprenant l'exemple du tableau créé dans le premier chapitre, on peut ainsi parcourir le tableau formateur en récupérant la valeur de chaque cellule (exemple 1) mais également la clef de la cellule (exemple 2).
<informalexample>
<programlisting>
Exemple :
 
<![CDATA[
$prof = array("Assoune", "Obré", "Lausin");
$prenoms_enseignant = array('Assoune' => "Maximin",
     'Obré' => "Philippe",
     'Lausin' => "Benoit");

foreach ($prof as $nom) {
  echo "Professeur :  $nom <br />";
}

foreach ($prenoms_enseignant as $n => $ $p) {
  echo "Professeur :  $n $p <br />";
}
]]></programlisting></informalexample>
</para>
	<para>Une utilisation des tableaux à plusieurs dimensions est également fréquente. Dans ce cas, il peut être intéressant d'imbriquer les parcours de chaque dimensions :  
<informalexample>
<programlisting>
<![CDATA[
//tableau à deux dimesion : catégorie et produits
$prod['vetements']['T-shirt'] = 20.00;
$prod['vetement'][`pantalon'] = 22.50;
$prod['literie']['taie'] = 25.00;
$prod['literie']['drap'] = 50.00;
$prod['fourniture']['lampe'] = 44.00;
$prod['fourniture']['table'] = 75.00;

//récupération du prix d'un T-Shirt
$prix = $prod['vetements']['T-shirt'];

//affichage du prix d'un pantalon
echo $prod['vetement'][`pantalon'];

//affichage d'un texte 
echo "le prix d'une lampe est \${$prod['fourniture']['lampe']}";

echo "<table border=1>";
foreach( $prod as $categorie )
{
   foreach( $categorie as $produit => $prix )
   {
     $ch_prix = sprintf("%01.2f", $prix);
     echo "<tr><td>$produit:</td><td>\$$ch_prix</td></tr>";
   }
}
echo "</table>";]]>
</programlisting></informalexample>
</para>
</sect3>
<sect3><title>Un petit mot sur les fonctions</title>
<para>
Dans l'exemple précédent, nous avons aperçu la fonction <command>sprintf</command>. Nous détaillerons dans le chapitre 4 ce qu'est une fonction, mais nous pouvons déjà dire qu'il s'agit d'un bloc d'instructions qui peut être appelé depuis un programme. S'il est possible au programmeur de concevoir lui même des fonctions, il existe également nombre de fonctions prédéfinies, c'est-à-dire intégrées nativement dans le langage, ou incluses dans des modules.</para>

<para>
Nous aurons bien sûr l'occasion de manipuler des fonctions liées à MySQL par exemple, mais le site <ulink url="http://www.php.net">php.net</ulink> vous donne déjà une idée du nombre de fonctions disponibles. La documentation les classe par <ulink url="http://www.php.net/manual/fr/funcref.php">catégories</ulink>. 
</para>

</sect3>
    </sect2>   
 
    <sect2>
      <title>Exercices d'applications</title>
      <sect3><title>Boucles et conditionnelles</title>
	<orderedlist>
	  <listitem>
	<para>Ecrivez un code Php qui affiche "hello world" en titre de niveau 1, niveau 2 .. niveau 6.</para></listitem>
	  <listitem>
	<para>Créer une balise de titre H1 : « Calcul sur les variables ». Affecter respectivement les valeurs 0.206, 150 et 10 aux variables TVA, prix et Nombre. Calculer le prix HT et le prix TTC pour les 10 articles et les afficher. On affichera également le type de chaque variable.
</para></listitem>
	  <listitem>
	<para>Affectez respectivement les valeurs 150, 50 et 10 aux variables prix_table, prix_armoire et Nombre. Calculez le prix HT total pour les 10 armoires. Comparez le prix de l'armoire et de la table et affichez quel est le prix le plus élevé.
</para></listitem> <listitem>
	    <para>Affectez une valeur à la variable <varname>nbre</varname> et afficher la somme des entiers de 1 à <varname>nbre</varname>. Donnez les versions du programme en utilisant l'instruction <command>FOR</command> puis avec l'instruction <command>WHILE</command>.
</para></listitem>
</orderedlist>

</sect3>
<sect3><title>Tableaux</title>
	<orderedlist>
	  <listitem>
	<para>Initialisez un tableau de 4 cellules, et faites en la somme en utilisant deux méthodes différentes.</para></listitem>
	  <listitem>
	<para>Initialisez un tableau de 4 cellules (contenant des nombres en francs) et en faire la conversion en euros. On affichera la somme totale des cellules du tableau en euros ainsi que chaque cellule du tableau.
</para></listitem>
</orderedlist>

</sect3>
<sect3><title>Interaction avec HTML</title>
	<orderedlist>
	  <listitem>
	<para>Affichez sur une page HTML un tableau présentant le calendrier du mois en cours. Ajoutez du code PHP permettant de mettre en rouge la cellule correpondant au jour d'aujourd'hui.</para></listitem>
	  <listitem>
	<para>Reprenez votre CV avec les variables PHP. Quels changement faudrait-il apporter pour afficher plusiseurs CV dans la même page ? 
</para></listitem>
</orderedlist>

</sect3>
      <sect3><title>Carré magique</title>

	<para>Un tableau de nombres entiers est dit <emphasis>magique</emphasis> quand la somme des cases de chaque colonne est égale à la somme des cases de chaque ligne, et à la somme des cases de chaque diagonale.</para>

<para>Vous devez écrire une page PHP qui affiche le tableau suivant, et qui prouve que le carré est magique. Vérfiez en changeant une des valeurs. Toutes les valeurs du carré doivent être stockées dans une seule variable.
 <table>
                  <title>Carré magique</title>

                  <tgroup cols="5">
		    <tbody>
                      <row>
                        <entry>17</entry>
                        <entry>24</entry>
                        <entry>1</entry>
                        <entry>8</entry>
                        <entry>15</entry>
                      </row>
                      <row>
                        <entry>23</entry>
                        <entry>5</entry>
                        <entry>7</entry>
                        <entry>14</entry>
                        <entry>16</entry>
                      </row>
                      <row>
                        <entry>4</entry>
                        <entry>6</entry>
                        <entry>13</entry>
                        <entry>20</entry>
                        <entry>22</entry>
                      </row>
                      <row>
                        <entry>10</entry>
                        <entry>12</entry>
                        <entry>19</entry>
                        <entry>21</entry>
                        <entry>3</entry>
                      </row>
                      <row>
                        <entry>11</entry>
                        <entry>18</entry>
                        <entry>25</entry>
                        <entry>2</entry>
                        <entry>9</entry>
                      </row>

                    </tbody>
                  </tgroup>
                </table>

</para> 

     </sect3>
    </sect2>
  </sect1>


 

<!--  ================================= Chapitre 3 ============================= -->
<sect1>
    <title>Passage de valeurs entre pages</title>  
<abstract>
      <para>La navigation de page en page sur un site Internet est une opération naturelle pour l'utilisateur. Du point de vue du développeur, il est parfois nécessaire de conserver des informations tout au long de la <emphasis>session</emphasis> d'un internaute, pour par exemple se souvenir de son <foreignphrase>login</foreignphrase>, du nombre de page qu'il a visité, de son panier d'achat, etc .. Nous distinguerons 4 manières différentes d'implémenter cette notion dans les codes PHP :
<orderedlist>
	  <listitem>
	    <para>l'ajout d'information dans un lien hypertexte (dans <emphasis>l'url</emphasis> cible)</para></listitem>
	  <listitem>
	  <para>le passage de données via un formulaire</para></listitem>
	  <listitem>
	  <para>l'utilisation de cookies</para></listitem>
	  <listitem>
	  <para>l'utilisation de variables de session</para></listitem></orderedlist>

Nous examinerons les 3 premières solutions dans ce chapitre, et nous reviendrons dans le dernier chapitre sur la notion de variables de session. 
</para>
</abstract>

    <sect2>
      <title>Passages de variables dans l'url</title>
      <para>Si les formulaires constituent un élément essentiel d'interaction avec l'utilisateur et les pages HTML, il est généralement nécessaire de passer des informations de page en page, sans utiliser de formulaires. Pour cela, nous utilisons la méthode GET du protocole HTTP, qui permet d'ajouter des valeurs à l'URL. Néanmois, il faut considérer cette méthode comme un risque de sécurité.</para>
<para>Le principe consiste à ajouter le couple variables/valeur en fin d'URL, en séparant chaque couple par des &amp;. L'ensemble des arguments est séparé de l'URL par un ?.</para>
<para>
<example>
<title>Passage de paramètre par URL</title>
<programlisting>
<![CDATA[
<a href="trait.php?nom=kurzweg&prenom=ivan">cliquez ici pour vous enregistrer</a>
<? $prenom="ivan" ?>
<? $nom="kurzweg" ?>
<a href="trait.php?nom=<?echo $nom;?>&prenom=<?echo $prenom;?>">
cliquez ici pour vous enregistrer</a>

]]>
</programlisting>
</example></para>
<note>
<para>Cette technique est limité par la longueur maximale d'une URL, qui varie d'un navigateur à l'autre, et d'un serveur à l'autre. Elle présente également le défaut de montrer en clair les valeurs passées en paramètres, y compris par exemple des mots de passe ! A n'utiliser donc qu'avec parcimonie !
</para>
</note>
    </sect2>
   <sect2>
      <title>Formulaires</title>
      <para>
Nous avons vu dans le cours HTML l'utilisation des formulaires et des différents champs qui peuvent les composer. Nous avons également vu l'attribut HTML <command>action</command> qui permet de spécifier la page sur laquelle seront traitées les données. </para>
      <para>PHP dispose bien sûr de caractéristiques intéressantes pour traiter les formulaires. Selon la méthode d'envoi du formulaire, <command>GET</command> ou <command>POST</command>, l'ensemble des valeurs sont stockées dans un tableau indicé sur le nom des champs. Ce tableau est <varname>$_GET</varname> ou <varname>$_POST</varname> selon le mode d'action. </para>
<para>
Le traitement des données du formulaires est donc lié au traitement du tableau. L'exemple ci-dessous montre le traitement d'un formulaire simple : 
     </para>
<example>
<title>Traitement d'un champ texte d'un formulaire</title>
<programlisting>
<![CDATA[

Exemple 1 : un formulaire simple, et le code PHP affichant le résultat : 

<form method="POST" action="exemple.php" >
    <input name="mon_champ" type="text"/>
    <input name="valider" type="submit" value="OK"/>
</form>

<?
if (isset($_POST['mon_champ'])) {
?>
    Votre champ contenait :
    <b><?php echo $_POST['mon_champ']; ?></b>
    <br/><br/>
<?php
}
?>

]]>
</programlisting>
</example>
<example>
<title>Traitement d'un champ radio d'un formulaire et ré-affichage du formulaire</title>
<programlisting>
<![CDATA[

<?php
$mon_champ = isset($_POST['mon_champ']) ? $_POST['mon_champ'] : '';
 
if ($mon_champ) {
?>
    Vous avez choisi :
    <b><?php echo $mon_champ; ?></b>
    <br/><br/>
<?php
}
?>
 
<form method="POST">
    <input type="radio" name="mon_champ" value="Option 1" 
       <?php if($mon_champ == "Option 1") { echo 'checked'; } ?>/>Option 1<br/>
    <input type="radio" name="mon_champ" value="Option 2" 
       <?php if($mon_champ == "Option 2") { echo 'checked'; } ?>/>Option 2<br/>
    <input type="radio" name="mon_champ" value="Option 3" 
       <?php if($mon_champ == "Option 3") { echo 'checked'; } ?>/>Option 3<br/>
    <input type="submit" value="OK"/>
</form>



]]>
</programlisting>
</example>

<example>
<title>Traitement d'un champ liste d'un formulaire et ré-affichage du formulaire</title>
<programlisting>
<![CDATA[
<?php
$mon_champ = isset($_POST['mon_champ']) ? $_POST['mon_champ'] : '';
 
if ($mon_champ) {
?>
    Votre champ contenait :
    <b><?php echo $mon_champ; ?></b>
    <br/><br/>
<?php
}
?>
 
<form method="POST">
    <select name="mon_champ">
        <option <?php if($mon_champ == "Option 1") { echo 'selected'; } ?>>
              Option 1</option>
        <option <?php if($mon_champ == "Option 2") { echo 'selected'; } ?>>
              Option 2</option>
        <option <?php if($mon_champ == "Option 3") { echo 'selected'; } ?>>
              Option 3</option>
    </select>
    <input type="submit" value="OK"/>
</form>

]]>
</programlisting>
</example>
    </sect2>   
   <sect2>
      <title>Cookies</title>
      <para>
Les cookies sont des petites quantités d'informations contenant des paires <emphasis>variables=valeur</emphasis>,  stockées sur le navigateur de l'utilisateur.  Ce stockage déporté sur le client pose bien évidemment des problèmes : l'utilisateur peut refuser les cookies, ou encore les supprimer régulièrement, empêchant ainsi votre application de fonctionner correctement. 
     </para>
<para>
La fonction <command>setcookie("variable", "valeur")</command> permet de créer un cookie et d'y stocker la paire de valeur. L'utilisation des cookies étant problématique, nous ne nous attardons pas plus sur leur fonctionnement. 
</para>

    </sect2>   
    <sect2>
      <title>Exercices d'applications</title>
   <para>
Ecrire un formulaire qui permettent de rentrer les données d'une fiche stagiaire. Le formulaire envoie les valeurs stockées vers votre page "cv", modifier pour être remplie dynamiquement par les valeurs fournies. 
     </para>
    </sect2>
  </sect1>


<!--  ================================= Chapitre 4 ============================= -->
<sect1>
    <title>Interaction avec Mysql</title>  
<para>
Nous avons vu dans le cours sur les bases de données la manière de stocker des valeurs et d'y accéder sur une base MySQL. Nous allons voir dans ce chapitre la façon d'interagir avec la base de données depuis des pages écrites en PHP. En particulier, nous détaillerons les étapes suivantes : 
<orderedlist>
	<listitem>
	  <para>    <emphasis> Connexion au serveur MySQL (authentification)</emphasis> : nous récupérons une ressource de connexion sur laquelle nous pourrons travailler.</para></listitem>
   	<listitem>
	  <para> <emphasis> Sélection d'une base de données </emphasis>: le serveur MySQL pouvant héberger plusieurs base de données, nous sélectionnons la cible de nos traitements</para></listitem>
  	<listitem>
	  <para>   <emphasis>Passage de la requête</emphasis> : nous récupérons ici une ressource, qui contient (mais pas de manière immédiatement accessible) la réponse à notre requête.</para></listitem>
   	<listitem>
	  <para> <emphasis> Vérification de la validité de la ressource récupérée </emphasis>: éventuellement des tests sur le nombre de lignes renvoyées par la requêtes, ou sur la bonne exécution de cette requête.</para></listitem>
  	<listitem>
	  <para>  <emphasis> Extraction des données à partir de la ressource</emphasis> : pour récupérer les informations dans un format exploitable par PHP.</para></listitem>
   	<listitem>
	  <para>  <emphasis>Fermeture de la connexion : indiquer au système de libérer les ressources monopolisées</emphasis>.</para></listitem></orderedlist>
Les différentes fonctions que nous allons voir sont bien sûr détaillées dans la documentation de php, sur <ulink url="http://www.php.net">http://www.php.net</ulink>.

</para>

    <sect2>
      <title>Accès au serveur MySQL</title>
      <para>
L'accès à un serveur MySQL depuis une page PHP se fait via la fonction  <function>mysql_connect(serveur, login, password)</function>. Les informations à passer sont donc : 
<itemizedlist>
	<listitem>
	<para> serveur : l'adresse IP ou le nom DNS du serveur hébergeant le SGBDR MySQL </para></listitem>
<listitem>
	<para>login : un compte utilisateur de MySQL, ayant les droits nécessaires sur la base que vous souhaitez exploiter</para></listitem>
<listitem>
	<para>password : le mot de passe du compte</para></listitem></itemizedlist>
Ces valeurs varient selon les cas : en local, elles dépendront de votre configuration, chez un hébergeur  internet elles sont généralement fournies au moment de l'abonnement.
</para>
<para>La fonction mysql_connect renvoie un identifant de ressource, qu'il est nécessaire de stocker dans une variable. C'est cette valeur qui permettra d'identifier le lien au serveur de la base de données pour les futures requêtes. En effet, rien n'interdit de se connecter simultanément à plusieurs serveurs !</para>
<example>
<title>Connexion à un serveur MySQL</title>
<programlisting>
<![CDATA[

Exemple 1: 

$connexion = mysql_connect("localhost", "initll", "pass_initll");

Exemple 2 : 

$host = "localhost";
$user = "init_ll";
$password = "pass_initll";

if (!$connexion = mysql_connect($host,$user,$password))
{
    $message = mysql_error();
    echo "$message<br>";
    die();
}

]]>
</programlisting>
</example>
      <para>Une fois la connexion avec le serveur établie, nous allons nous servir de ce lien pour sélectionner la base sur laquelle travailler. En effet, nous avons vu qu'il est possible d'héberger plusieurs bases de données sur un même serveur MySQL, mais nos futures requêtes à la base doivent s'appliquer à une seule base ! Pour cela, PHP dispose de la fonction <function>mysql_selectdb("nom_bdd", connexion)</function>. Les paramètres à passer à la fonction sont les suivants : 
<itemizedlist>
	<listitem>
	<para> nom_bdd : le nom de la base de données telle qu'il apparait sur le serveur MySQL</para></listitem>
<listitem>
	<para> lien : l'identifiant de la ressource que l'on a récupéré à la suite de l'exécution  de <function>mysql_connect</function>  </para></listitem></itemizedlist>
</para>
<example>
<title>Sélection de la base de données</title>
<programlisting>
<![CDATA[
Exemple 1 :

$db= mysql_select_db("init_ll", $connexion) or die(mysql_error());

Exemple 2 : 

$database = "init_ll";
$db = mysql_select_db($database,$connexion)
      or die ("Problème de sélection de la base de données");

]]>
</programlisting>
	<para>Dans cet exemple, on sélectionne la base de données <varname>init_ll</varname> sur le serveur auquel on se connecte via l'identifiant <varname>link</varname>.  Dans le cas où la fonction échoue, la fonction<function> mysql_error</function> sera exécutée, fournissant les informations nécessaires au débugage. </para>
</example>
<para>
Nous verrons dans le dernier chapitre la manière de globaliser ces opérations en les incluant dans des fichiers séparés des codes PHP. Dans le cas contraires, en cas de changement d'hébergement du site, il faut reprendre toutes les pages PHP contenant des connexions à la base de données, et les modifier pour faire apparaître les nouvelles informations ...
     </para>
    </sect2>
   <sect2>
      <title>Exécution de code SQL</title>
      <para>
Une fois la connexion au serveur de bases de données établie, et la base de données sélectionnée, il est alors possible de manipuler l'ensemble des données MySQL en écrivant les requêtes SQL, et en les faisant exécuter sur le serveur. </para>

      <note>
<para>L'ensemble des requêtes SQL disponible sous MySQL est à notre disposition, qu'il s'agisse de sélectionner des données, d'en ajouter, d'en supprimer ou encore d'en modifier. Ces requêtes ont été vues dans le cours MySQL, et nous n'allons pas les reprendre toutes. Rappelez vous cependant que si vous avez des soucis avec la rédaction des requêtes, il est possible de laisser à des outils tels que PhpMyAdmin le soin de les concevoir pour vous..
     </para></note>

      <para>La première étape consiste à concevoir la requête, qui n'est pas forcément une requête statique : il peut être nécessaire de la construire en utilisant des données provenant du code PHP, par exemple issues d'un formulaire. Il est ainsi préférable de construire la requête en la stockant dans une chaîne de caractères avant de l'exécuter. Une fois la requête conçue, l'exécution se fait en appelant la fonction <function>mysql_query($query,$connexion)</function>. <varname>$query</varname> contiendra la chaîne de caractère de la requête SQL, et <varname>$connexion</varname> l'identifiant obtenu à l'excéution de la fonction <function>mysql_selectdb()</function>.</para>
<example>
<title>Exécution d'un requête SQL</title>
<programlisting>
<![CDATA[
Exemple 1 : 

$query = "SELECT * FROM formateurs";
$result = mysql_query($query,$connexion)
     or    die ("Erreur d'exécution de la requête SQL !!");

Exemple 2 : 

$query = "SELECT * FROM formateurs WHERE FORM_NOM LIKE 'KURZWEG'";
$result = mysql_query($query,$connexion)
     or    die ("Erreur d'exécution de la requête SQL !!");

Exemple 3 : 

$query = sprintf("SELECT * FROM formateurs WHERE FORM_NOM LIKE '%s'",$_POST["nom"]);
$result = mysql_query($query,$connexion)
     or    die ("Erreur d'exécution de la requête SQL !!");

]]>
</programlisting>
	<para>Vous remarquerez l'emploi des apostrophes à l'intérieur de la requête SQL, alors que ce sont des guillemets qui encadrent la chaîne PHP. Dans le  troisième exemple, la requête est construite à partir d'informations récupérées depuis un formulaire, en utilisant la fonction <function>sprintf()</function> qui permet de <emphasis>formater</emphasis> une chaîne de caractères. </para>


</example>
<para>
La variable <varname>$result</varname> utilisée dans les exemples suivants possède un comportement différent selon que : 
<itemizedlist>
<listitem>
	<para>la requête SQL renvoie un résultat (une requête de sélection) : <varname>$result</varname> identifie le tableau qui contiendra toutes les informations issues de la requête</para></listitem>
<listitem>
	<para>
la requête SQL ne renvoie pas de résultat (insertion, modification, suppression d'enregistrement ) : <varname>$result</varname> est alors un booléen qui contiendra FALSE ou TRUE selon que la requête se soit bien passée ou non.</para></listitem> </itemizedlist>
</para>
    </sect2>   
    <sect2>
      <title>Traitement des résultats</title>
      
<sect3><title>
     Traitement des résultats d'une requête de type SELECT</title>
     <para>
Les fonctions MySQL permettent d'extraire les résultats d'une requête sous différentes formes, mais la plus commune est le tableau. 
Ce tableau extrait un enregistrement et un seul, chaque cellule du tableau étant identifié par le nom du champ de la table. Parcourir
tous les résultats de la requête nécessite ainsi de recharger le tableau pour chacune des lignes. Un méthode commune est l'emploi d'une
boucle while. La fonction <function>mysql_fetch_array</function> stocke une ligne résultat de la requête dans un tableau, et pointe sur la ligne suivante. Quand 
tous les résultats sont traités, la fonction renvoie FALSE.</para>  

<example>
<title>Traitement des résultats d'une requête</title>
<programlisting>
<![CDATA[


$query = "SELECT * FROM stagiaires";
$result = mysql_query($query,$connexion)
     or    die ("Erreur d'exécution de la requête SQL !!");

echo "<ul>";
while ($ligne = mysql_fetch_array($result)) {
  echo "<li>" . $ligne['STAG_NUM'] . " : " 
              . $ligne['STAG_NOM'] . " - " 
              . $ligne['STAG_PRENOM'] . "</li>" ;
  echo "<br />";
}
echo "</ul>
]]>
</programlisting>
	  <para>Cet exemple va sélectionner tous les champs de toutes les lignes dans la table <filename>stagiaires</filename>. Ensuite, la fonction <function>mysql_fetch_array</function>
	va stocker ligne par ligne les enregistrements. La boucle PHP va afficher une liste à puces, chaque item contenant le numéro, le nom et
	le prénom du stagiaire.</para>

</example>



     </sect3>       
<sect3><title>Test des résultats d'une requête de type SELECT</title>
     <para>Dans certains cas, il peut être nécessaire de connaître des informations sur les résultats de la requête. La plus courante est 
     le nombre de lignes renvoyées par la requête, ou encore le nombre de champs, respectivement connus via les fonctions <function>mysql_num_row($result)</function> et
     <function>mysql_num_fields($esult)</function>.
     </para>
     <example>
<title>Test des résultats d'une requête</title>
<programlisting>
<![CDATA[

$prenom = "ivan";
$query = sprintf("SELECT * FROM stagiaires WHERE STAG_PRENOM LIKE '%s'", $prenom;
$result = mysql_query($query,$connexion)
     or    die ("Erreur d'exécution de la requête SQL !!");

if (mysql_num_rows($result) == 0)
{
	echo "<p>Pas de stagiaires avec $prenom comme prenom !</p>";
}
else
{
	echo "<ul>";
	while ($ligne = mysql_fetch_array($result)) {
  		echo "<li>" . $ligne['STAG_NUM'] . " : " 
                            .  $ligne['STAG_NOM'] . " - " 
                            . $ligne['STAG_PRENOM'] . "</li>" ;
  		echo "<br />";
	}
	echo "</ul>
}
]]>
</programlisting>
	<para>Dans cet exemple, on vérifie que la requête a renvoyé au moins une ligne avant d'afficher les résultats. Si elle n'a rien 
	retourné, on affiche un message d'avertissement.</para>

</example>
     </sect3>     
        
    </sect2>  
    <sect2>
      <title>Fermeture de connexion à la base MySQL</title>
   <para>Il existe des configurations particulières pour lesquelles les connexions à la base de données initiées dans une page PHP peuvent
   être laissées ouvertes, mais dans la grande majorité des cas, il est largement préférable de fermer la connexion au serveur de base
   de données, juste après les traitements. Ainsi, même si de nombreux utilisateurs sont connectés sur le site simultanément, le risque
   d'arriver au maximum des utilisateurs accèdant à MySQL s'en trouve réduit. Il faut donc penser à tout le temps fermer la connexion à
   MySQL en fin de page PHP en utlisant la fonction <function>mysql_close($connexion)</function>

     </para>
     <example>
<title>Exemple de traitement complet</title>
<programlisting>
<![CDATA[

$host = "localhost";
$user = "init_ll";
$password = "pass_initll";

if (!$connexion = mysql_connect($host,$user,$password))
{
    $message = mysql_error();
    echo "$message<br>";
    die();
}

$prenom = "ivan";
$query = sprintf("SELECT * FROM stagiaires WHERE STAG_PRENOM LIKE '%s'", $prenom;
$result = mysql_query($query,$connexion)
     or    die ("Erreur d'exécution de la requête SQL !!");

if (mysql_num_rows($result) == 0)
{
	echo "<p>Pas de stagiaires avec $prenom comme prenom !</p>";
}
else
{
	echo "<ul>";
	while ($ligne = mysql_fetch_array($result)) {
  		echo "<li>" . $ligne['STAG_NUM'] 
                            . " : " .  $ligne['STAG_NOM'] 
                            . " - " . $ligne['STAG_PRENOM'] . "</li>" ;
  		echo "<br />";
	}
	echo "</ul>
	}

mysql_close($connexion);

]]>
</programlisting>

</example>   
   </sect2>
    <sect2>
      <title>Exercices d'applications</title>
   <para>
Travailler à partir de la base <filename>stagiaires</filename>. Faire une page où s'affiche la liste des stagiares (Nom, prenom, date de naissance) sous forme de liste ordonnée, la liste des formateurs, la liste des modules.  
     </para>
        <para>
Travailler à partir de la base ordinateurs. Modifier la pages PHP "index.html", de manière à indiquer dans la première le 
nombre total d'ordinateurs dans la base et le nombre d'ordinateurs dans chaque catégorie.Modifier ensuite la page <filename>portable</filename> de manière à en obtenir la liste depuis la base de données.   
     </para>
    </sect2>
  </sect1>



<!--  ================================= Chapitre 5 ============================= -->
<sect1>
    <title>Développement d'applications internet</title>


    <sect2>
      <title>Fonctions</title>
      <para>
Une application (Internet ou autre), doit souvent exécuter le même code à plusieurs endroits du programme, ou dans différents programmes. Un exemple pourrait être par exemple l'affichage d'un logo dans toutes vos pages web :
 <example>
<title>Affichage d'un logo en PHP</title>
<programlisting>
<![CDATA[

echo '<p><hr width="50" align="left" />',"\n";
echo '<img src="/images/logo.jpg" width="50" height="50" alt="logo" /><br />',"\n";
echo '<hr width="50" align="left" /></p>',"\n";
]]>
</programlisting>
</example> 
Un fonction <function>affiche_logo</function>  pourrait reprendre toutes les instructions précédentes. L'affichage du logo se ferait alors par simple appel à cette fonction :
 <example>
<title>Affichage d'un logo en PHP avec appel d'une fonction</title>
<programlisting>
<![CDATA[
display_logo();
]]>
</programlisting>
</example> 
     </para>

     <para>Cette notion de fonction a plusieurs avantage : 
<itemizedlist>
	  <listitem>
	  <para>moins de code à écrire</para></listitem>
	  <listitem>
	  <para>une meilleure lisibilité</para></listitem>
	  <listitem>
	  <para>moins d'erreurs au développement</para></listitem>
	  <listitem>
	  <para>une meilleure évolutivité</para></listitem>
</itemizedlist>
 </para>
<para>
La déclaration d'une fonction se fait de la manière suivante : 
<informalexample>
<programlisting>
<![CDATA[
function nom_fonction()
{
   bloc d'instructions;
   return;
}
]]>
</programlisting></informalexample>
Ce qui donnerait pour l'exemple précédent la déclaration suivante : 
 <example>
<title>Fonction d'affichage d'un logo en PHP</title>
<programlisting>
<![CDATA[
function affiche_logo() 
{
   echo '<p><hr width="50" align="left" />',"\n";
   echo '<img src="/images/logo.jpg" width="50" height="50" alt="logo" /><br />',"\n";
   echo '<hr width="50" align="left" /></p>',"\n";
   return;
}
]]>
</programlisting>
</example> 
Le mot clef <command>return</command> interrompt l'exécution de la fonction, et provoque le retour au programme appelant. Toute fonction devrait comporter au moins une instruction <command>return</command>.
</para>
<para>
Il est également possible de manipuler des variables dans les fonctions, et nous distinguerons alors les variables locales (celles qui ne sont visibles qu'à l'intérieur du corps de la fonction), et les paramètres de la fonction, variables qui sont affectées lors de l'appel à la fonction. 
</para>
<sect3>
<title>Utilisation de variables locales dans une fonction</title>
<para>
La déclaration d'une variable dans le corps d'une fonction a la particularité de ne la rendre visible que dans la fonction. On parle alors de <emphasis>portée</emphasis> de variable, limitée à une <emphasis>portée locale</emphasis> dans ce cas. L'exemple suivant ne produit pas de sortie : 
 <example>
<title>Fonction d'affichage d'un logo en PHP</title>
<programlisting>
<![CDATA[
//déclaration de la fonction
function format_nom()
{
   $prenom = "Ivan";           //déclaration de la variable en local
   $nom = "Kurzweg";
   $nom_complet = $prenom.", ".$nom; //pas d'erreurs à l'exécution
}

//appel de la fonction dans la page PHP
format_name();

//mais aucune sortie à l'exécution de echo, la variable name n'est pas connue
echo "$name";
]]>
</programlisting>
</example> 
Il existe la possibilité d'augmenter la portée d'une variable à toute la page PHP en utilisant le mot clef <command>global</command>. Mais cette technique est souvent source d'erreurs et de confusion, nous ne nous y attarderons pas.
</para>

</sect3>
<sect3>
<title>Passage de paramètres à une fonction</title>
<para>
Il est possible de passer des valeurs entre une fonction et le programme appelant, et ce dans les deux sens : du programme appelant vers la fonction en utilisant les paramètres de la fonction, et de la fonction vers le programme appelant en utilisant l'instruction <command>return</command>. </para>
<para>
Pour passer des paramètres (des valeurs) à une fonction, il faut au préalable avoir déclaré la fonction de manière à ce qu'elle attende ces valeurs : 
<informalexample>
<programlisting>
<![CDATA[
function nom_fonction($var1, $var2, ...)
{
   bloc d'instructions;
   return;
}
]]>
</programlisting></informalexample>
L'appel de la fonction se fait alors en renseignant les valeurs : 
<informalexample>
<programlisting>
<![CDATA[
nom_fonction(valeur,valeur,...);
]]>
</programlisting></informalexample>

 <example>
<title>Fonction de calcul d'un montant TTC</title>
<programlisting>
<![CDATA[
//déclaration de la fonction
function calul_ttc($montantHT,$tva)
{
  switch ( $tva )
  {
    case "HT" :
      $taxes = 0;
      break;
    case "DOM" :
      $taxes = 1.086;
      break;
    default:
      $taxes = 1.186;
      break;
  }
  $montantTTC = $montantHT * $taxes;
  echo "$=montantTTC<br>";
}

//initialisation des variables 
$prix = 2000.00;
$tauxTaxes = "DOM";

//appel de la fonction
calcul_ttc($prix,$tauxTaxes);

]]>
</programlisting>
</example> 

</para>

</sect3>
<sect3>
<title>Retour d'une valeur depuis une fonction</title>
	<para>S'il est possible de passer des valeurs en paramètres à une fonction, il est également possible d'obtenir une valeur de la fonction. C'est le rôle de l'instruction <command>return</command> de renvoyer la valeur selon le modèle suivant : 
<informalexample>
<programlisting>
<![CDATA[
function nom_fonction($var1, $var2, ...)
{
   bloc d'instructions;
   return valeur;
}
]]>
</programlisting></informalexample>
Il est alors possible d'affecter la valeur de retour de la fonction à une variable du programme appelant : 
<informalexample>
<programlisting>
<![CDATA[
$variable = nom_fonction(valeur,valeur,...);
]]>
</programlisting></informalexample>

 <example>
<title>Fonction de calcul d'un montant TTC</title>
<programlisting>
<![CDATA[
//déclaration de la fonction
function calul_ttc($montantHT,$tva)
{
  switch ( $tva )
  {
    case "HT" :
      $taxes = 0;
      break;
    case "DOM" :
      $taxes = 1.086;
      break;
    default:
      $taxes = 1.186;
      break;
  }
  $montantTTC = $montantHT * $taxes;
  //on ne fait plus l'echo, mais on va renvoyer la valeur obtenue
  //echo "$=montantTTC<br>";
  return $montantTTC;
}

//initialisation des variables 
$prix = 2000.00;
$tauxTaxes = "DOM";

//appel de la fonction, et affectation du résultat à une variable
$montant = calcul_ttc($prix,$tauxTaxes);

]]>
</programlisting>
</example> 

</para>

</sect3>
<sect3>
<title>Fonctions intégrées à PHP</title>
	<para>Il existe un certains nombres de fonctions intégrées au langage PHP, ou accessibles après l'ajout d'un module complémentaire. Nous avons par exemple vu des fonctions propres à MySQL, disponibles puisque nous avons installé le <emphasis>paquet</emphasis> <filename>PHP5-mysql</filename>. 
</para>
	<para>Ainsi, nous pouvons disposer de fonctions prédéfinies, qui permettent par exemple de manipuler des images, de générer des fichiers au format PDF, etc.. Le site <ulink url="http://www.php.net">www.php.net</ulink> vous en présente de nombreuses.</para>

</sect3>
    </sect2>

    <sect2>
      <title>Inclusion de fichiers</title>
      <para>Php permet de stocker des instructions dans des fichiers externes - un fichier séparé du programme - et l'ajouter dans toutes les pages nécessaires. L'instruction <command>include</command> permet de réaliser cette "importation". Cette méthode se révèle pratique pour stocker des instructions, des fonctions ou des variables utilisées fréquemment. Le format d'une inclusion est le suivant : 
<informalexample>
<programlisting>
<![CDATA[
include("chemin/nom_fichier");
]]>
</programlisting></informalexample>
Le fichier peut avoir n'importe quel nom, mais vous pouvez par exemple le suffixer de <filename>.inc</filename>. Si le fichier contient du code PHP, ne pas oublier les caractères signalant le début et la fin de ce code ..
     </para>
<para>De manière à rendre l'application Internet que vous développez facilement maintenable et lisible, voici la liste d'un certain nombre de données à inclure dans des fichiers séparés, appelés depuis les pages PHP : 
<itemizedlist>
	  <listitem>
	    <para> <emphasis>Du code HTML</emphasis> : il peut être intéressant de mettre beaucoup de code HTML dans des fichiers d'inclusion. Par exemple, la partie déclarative (doctype et entête de la page), les parties du code HTML fixes sur le site (bandeau de navigation, pied de page, etc ..), voir même des fomulaires .. De manière générale, il faut essayer de mettre toutes les parties de codes HTML répétitives dans es fichiers à inclure ...</para>
	  </listitem>
	  <listitem>
	    <para><emphasis>Les informations nécessaires pour accèder à la base de données</emphasis>. En effet, lors de la migration du site depuis l'environnement de développement vers l'environnement de production, il n'y aura que ce fichier à modifier :
<informalexample>
<programlisting>
<![CDATA[
<?
$host = "localhost";
$user = "init_ll";
$password = "pass_initll";

if (!$connexion = mysql_connect($host,$user,$password))
{
    $message = mysql_error();
    echo "$message<br>";
    die();
}
?>
]]>
</programlisting></informalexample>
</para>
	  </listitem>
	  <listitem>
	    <para><emphasis>Les fonctions PHP </emphasis>: nous avons vu dans les paragraphes précédents la manière de concevoir des fonctions. Il peut être intéressant de les mutualiser dans des fichiers d'inclusion. </para>
	  </listitem>

</itemizedlist>
 </para>
<para> Au final, une page PHP qui fournira une page HTML complète pourrait s'écrire : 
  <example>
<title>Inclusion de fichiers HTML et PHP</title>
<programlisting>
<![CDATA[

<?
//------------------------------------------------------------------
//      inclusions des entêtes et des codes PHP
//-----------------------------------------------------------------

//inclusion des entêtes HTML
include("entete.inc");

//inclusion des fonctions PHP
include("fonctions.inc");

//inclusion du bandeau de navigation
include("bandeau.inc");

//inclusion de la connexion à la base
include("connect.inc");

?>

<?
//-----------------------------------------------------------------------
//traitements PHP et affichage du corps de la page 
//des requêtes SQL, du code HTML , etc 
//----------------------------------------------------------------------

 ...
 ...
 ...
?>

<?
//----------------------------------------------------------------------
//      inclusions des codes HTML de base de page
//----------------------------------------------------------------------

//inclusion des pieds de page  HTML
include("pied_page.inc");

?>
]]>
</programlisting>
</example> 
</para>
    </sect2>
   <sect2>
      <title>Variables de sessions </title>
      <para>
On parle de <emphasis>session</emphasis> comme du temps passé par un utilisateur sur l'application développée. Durant cette session, il peut être nécessaire de stocker des informations de bout en bout, comme le numéro de l'utilisateur par exemple. Php propose ainsi les <emphasis>variables de session</emphasis>, attribuée à chaque utilisateur pour sa session.</para>
<para>
Pour permettre de distinguer les utilisateurs entre eux, PHP assigne un identifiant de session, unique. Ce numéro est stocké sur le serveur, dans un fichier, et chez le client soit via des cookies, soit de page en page en utilisant la méthode <computeroutput>POST</computeroutput> si les cookies sont désactivés. Les variables de session sont obtenues en utilisant le tableau <varname>$_SESSION</varname>. 
</para>   
<para>   
Les sessions doivent être <emphasis>démarrées</emphasis> depuis les pages PHP, en utilisant la fonction <function>session_start</function>. L'exemple suivant propose deux pages utilisant des variables de session :

  <example>
<title>Démarrer une session </title>
<programlisting>
<![CDATA[

<?
  session_start();
?>
<html>
<head><title>Premiere page</title></head>
<body>
<?
  $_SESSION['var_session'] = "testing";
?>
      <p>Un test ...
       <form action="sessionTest2.php" method="POST">
       <input type="hidden' name="var_form"    value="testing" />
       <input type="submit" value="Page suivante" />
       </form>
       </p>
</body></html>
]]>
</programlisting>
</example> 
<example>
<title>Récupérer la variable de session</title>
<programlisting>
<![CDATA[

<?
  session_start();
?>
<html>
<head><title>Seconde page</title></head>
<body>

<?php
  echo "variable_session = {$_SESSION["var_session"]}<br />\n";
  echo "var_form = {$_POST["var_form"]}<br />\n";
?>
</body></html>
]]>
</programlisting>
</example> 
     </para>
    </sect2>   
    <sect2>
      <title>Eléments de sécurisation</title>
      <para>
La sécurité a été longtemps quelque peu ignorée par les développeurs, mais un <emphasis>"défaçage"</emphasis> n'arrive pas qu'aux autres ! Les risques principaux d'une mauvaise sécurisation sont : 
<itemizedlist>
	  <listitem>
	    <para><emphasis>Vol d'information</emphasis> : revente des adresses mails stockées, réutilisation des numéros de cartes bleues, etc ...</para></listitem>
	  <listitem>
	    <para><emphasis>Défaçage</emphasis> : effacement complet du site et de la base de données</para></listitem>
	  <listitem>
	    <para><emphasis>Fishing</emphasis> : utilisation de votre site à des fins frauduleuses </para></listitem> 
<listitem>
	    <para><emphasis>...</emphasis>  </para></listitem> </itemizedlist>
     </para>
<para>
S'il n'est pas possible de donner la liste exhaustives des risques, des attaques et des moyens de défense, voici quelques items minimums sur lesquels s'attarder : 
<itemizedlist>
  <listitem>
	    <para><emphasis>Ne pas laisser des répertoires en accés direct </emphasis>: quand une <foreignphrase>url</foreignphrase> pointe vers un répertoire pluôt qu'un fichier - http://www.kurweg.info/InitLL2007/, le serveur renvoie automatiquement la page <filename>index.html, index.htm </filename>ou<filename> index.php</filename>. Si cette page n'est pas présente dans le répertoire, le serveur peut alors lister tous les fichiers du répertoires, sauf si l'option <command>Indexes</command> est en place. A ce moment là, le serveur refuse le listage du répertoire. </para></listitem>

  <listitem>
	    <para><emphasis>Sécuriser les mots de passe </emphasis>: nous avons vu qu'il était envisageable de stocker les informations de connexion à la base de données dans un fichier include. Bien évidemment, il faudra protéger ce fichier (utiliser les fichiers <filename>.htpasswd</filename>).</para></listitem>

  <listitem>
	    <para><emphasis>Sécuriser les formulaires</emphasis> : même si PHP propose maintenant d'office des mécanisme de protection contre les injections de codes, il peut être judicieux de bien vérifier l'emploi des données entrées dans les formulaires. </para></listitem></itemizedlist>

</para>
    </sect2>  

  </sect1>






  <!-- =================================================================== -->
  <bibliography> 
    <title>Références</title> 

    <bibliodiv> 
      <biblioentry> 
 	<abbrev>1</abbrev> 
	<authorgroup>
	  <author>	   
	    <personname>
	    <firstname>Welling</firstname>
	    <surname>Luke</surname>
	  </personname>	 
 </author> <author>
	    <personname>
	    <firstname>Thomson</firstname>
	    <surname>Laura</surname>
	  </personname>	  
 	</author>
	</authorgroup>
 	<title>PHP and MySQL - Web Development</title> 
 	<edition> 
SAMS Edition
         </edition> 
      </biblioentry> 

      <biblioentry> 
 	<abbrev>2</abbrev> 
	<authorgroup>
	  <author>	   
	    <personname>
	    <firstname>Ratschiller</firstname>
	    <surname>Tobias</surname>
	  </personname>	 
   </author> <author>
	    <personname>
	    <firstname>Gerken</firstname>
	    <surname>Till</surname>
	  </personname>	  
 	</author>
	</authorgroup>
 	<title>Web Application Development with Php 4.0</title> 
 	<edition> 
New Riders
         </edition> 
      </biblioentry> 

      <biblioentry> 
 	<abbrev>3</abbrev> 
	<authorgroup>
	  <author>	   
	    <personname>
	    <firstname>Valade</firstname>
	    <surname>Janet</surname>
	  </personname>	 
  
 	</author>
	</authorgroup>
 	<title>PHP and MySQL for Dummies</title> 
 	<edition> 
Wiley Publishing, Inc
         </edition> 
  </biblioentry> 
      <biblioentry> 
 	<abbrev>4</abbrev> 
	<authorgroup>
	  <author>	   
	    <personname>
	    <firstname>Lane</firstname>
	    <surname>David</surname>
	  </personname>	 
  
 	</author>
	</authorgroup>
 	<title>Web database applications</title> 
 	<edition> 
O'Reilly
         </edition> 
      </biblioentry>     
 

      <biblioentry> 
 	<abbrev>5</abbrev> 
	<authorgroup>
	  <author>	   
	    <personname>
	    <firstname>Rasmus</firstname>
	    <surname>Lerdorf</surname>
	  </personname>	 

 	</author>
	</authorgroup>
 	<title>Programming PHP</title> 
 	<edition> 
O'Reilly
         </edition> 
      </biblioentry>     

    </bibliodiv> 
  </bibliography> 
</article>

