samedi 26 mars 2005

Les conditions

LES CONDITIONS
Les conditions sous Bash sont très différentes de ce qu'on peut retrouver dans les autres langages de programmation telle que le C, pascal, Java... Les espaces sont importants, s'ils ne sont pas pris en considérations, il est possible que le script ne puisse fonctionner. Une autre particularité est qu'il existe différents paramètres selon ce qu'on désire tester.

Tableau des opérateurs

Opérateur Description (retourne vrai si..)
-d si le répertoire existe
-e si le fichier existe
-f si le fichier (pas un répertoire ou fichier de périphérique: /dev/sda1...)
-r si le fichier peut être lu
-w si le fichier peut être écrit
-x si le fichier peut être exécuté
-L si le fichier est un lien symbolique
-z si la chaine de caractère est nulle
-n si la chaine de caractère n'est pas nulle
-eq s'ils sont équivalents (nombre)
-neq s'ils ne sont pas équivalents
= ou == si les chaines de caractère ou nombre sont égaux
!= s'ils ne sont pas égaux
-lt est plus petit que
-gt est plus grand que
-le est plus petit ou égale
-ge est plus grand ou égale
-a ou && et logique
-o ou || ou logique

Quelques exemples

On vérifie ci-dessous si le fichier qemu.htm existe. S'il existe, nous affichons un message.
if [ -e qemu.htm ]; then
  echo "Qemu.htm existe";
fi
On vérifie ci-dessous si le contenu de la variable X est plus petit que Y.
X=3
Y=12
if [ $X -lt $Y ]
then
  echo "\$X=$X, est plus grand ou égale \$Y=${Y}"
fi
Notez que si on ne met pas de ";" à la fin du if, le then doit être sur la prochaine ligne. En mettant "\" devant le nom de la variable existante, c'est le nom de la variable qui est affiché.
On vérifie si les chaînes de caractères sont identiques
X="allo"
Y="aillo"
if [ $X = $Y ]; then
 echo "les chaines sont identiques";
else
 echo "les chaines ne sont pas identiques";
fi
Il est possible de savoir si une chaîne de caractère débute ou se termine par un certain caractère.
X="allo"
if [[ $X == a* ]]; then
 echo "$X commence par a";
fi

X="allo2"
if [[ $X == *2 ]]; then
 echo "$X fini par 2";
fi
Les comparaisons binaires peuvent être faites de deux façons avec les opérateurs. Soit, on utilise -a ou && pour le et binaire. Soit on utilise -o ou || pour le ou binaire.
X=33
Y=23
A=12
B=23
if [ $X -gt $Y ] && [ $A -lt $B ]; then
 echo "$X est plus grand que $Y et $A est plus petit que $B ";
fi
Notez que si vous utilisez directement -a (ou -o) vous devez écrire:
X=33
Y=23
A=12
B=23
if [ $X -gt $Y -a $A -lt $B ]; then
 echo "$X est plus grand que $Y et $A est plus petit que $B ";
fi

Imbrication de if

Lorsqu'on a plusieurs de suites, on doit utiliser elif.
X=20
Y=30
Z=40
if [ $Z -lt $X ]; then
 echo "$Z est plus petit que $X";
elif [ $Z -lt $Y ]; then
 echo "$Z est plus petit que $Y";
else
 echo "$Z est plus petit que 50";
fi

Case

Au lieu d'utiliser de nombreux if et else, il peut être pratique d'utiliser un case afin de simplifier le code et de le rendre plus lisible.
echo "Fait t'il soleil ? [oui or non]: "
read reponse
    case $reponse in
        o* | O*)
                echo "vous avez repondu qu'il faisait soleil";
                ;;
        n* | N*)
                echo "vous avez repondu qu'il ne faisait pas soleil";
                ;;
        *)
                echo "vous avez mal répondu à la question";
                ;;
    esac
Vous pouvez noter que chaque condition se termine par ")", qu'à la fin de chaque commande on a ";;" et qu'on inscrit esac à la fin. Il arrive souvent qu'on inscrive la commande à l'envers en bash. Au début de ce script, on pose une question à l'usager. Lorsque l'utilisateur tapera sur une touche et appuiera sur entrée, cette touche sera lu (grâce à la fonction read) et une action sera faite selon sa valeur.

Nous avons completé la partie traitant des conditions. Un script avec tous les exemples peut être téléchargé ici

jeudi 24 mars 2005

Forum


FORUM

Dans ce tutoriel, nous allons créer un forum compatible à norme xhtml 1.0. La création d'un forum n'est pas si complexe, il est seulement nécessaire de bien définir les fonctionnalités désirées et de bien modéliser sa base de données. Le forum qui sera créé sera assez complet.

Il y aura 3 niveaux d'accès pour le forum. Le premier sera pour un usager standard, le deuxième pour un modérateur et le troisième sera pour le webmestre. Ce dernier sera utile pour le tutoriel sur l'espace membre. Les fonctionnalités standards sont d'envoyer un message et de répondre à un message. Un usager peut aussi modifier et supprimer un message. Un modérateur peut modifier et supprimer les messages des autres membres. D'autres fonctionnalités seront expliquées en temps et lieu.

Base de donnée

Les données des membres et du forum seront entreposées dans une base de donnée MySQL. Il y a de nombreuses façons de modéliser la base de donnée nécessaire pour les fonctionnalités prévues. Afin de simplifier au minimum les requêtes, nous allons créer une table message, une table réponse, une table membre et une table section. La table section sert à déterminer à quelle section : delphi, c++, math, science.... que le message appartient. Un tel forum permettra ainsi d'avoir de multiples sections. Plusieurs sujets différents pourront donc y être traités. La table membre sert à spécifier les informations de l'usager. La table message est la question et la table réponse est une réponse à un message. Il y a donc un lien entre membre et question, question et section, et question et réponse.
Voici un petit schéma pour faciliter la compréhension.



Code sql

Table Membre

DROP TABLE IF EXISTS `membre`;
CREATE TABLE `membre` (
  `MEM_NOMEMBRE` int(11) NOT NULL auto_increment,
  `MEM_NOM` varchar(30) NOT NULL default '',
  `MEM_PRENOM` varchar(30) NOT NULL default '',
  `MEM_NOMUSAGER` varchar(30) NOT NULL default '',
  `MEM_MOTPASSE` varchar(30) NOT NULL default '',
  `MEM_COURRIEL` varchar(30) NOT NULL default '',
  `MEM_TYPE` int(11) NOT NULL default '0',
  `MEM_SITEWEB` varchar(100) default NULL,
  `MEM_SIGNATURE` varchar(50) default NULL,
  `MEM_NBMESSAGE` int(11) default '0',
  PRIMARY KEY  (`MEM_NOMEMBRE`)
) TYPE=MyISAM AUTO_INCREMENT=9 ;

Table Section

DROP TABLE IF EXISTS `section`;
CREATE TABLE `section` (
  `SEC_NOSECTION` int(11) NOT NULL auto_increment,
  `SEC_NOMSECTION` varchar(25) default NULL,
  `SEC_NBMESSAGE` int(11) default '0',
  `SEC_DATEDERNIERMSG` timestamp(14) NOT NULL,
  PRIMARY KEY  (`SEC_NOSECTION`),
  KEY `SEC_NOSECTION` (`SEC_NOSECTION`)
) TYPE=MyISAM AUTO_INCREMENT=5 ;

Table Message

DROP TABLE IF EXISTS `message`;
CREATE TABLE `message` (
  `MES_NOMESSAGE` int(11) NOT NULL auto_increment,
  `SEC_NOSECTION` int(11) NOT NULL default '0',
  `MEM_NOMEMBRE` int(11) NOT NULL default '0',
  `MES_MESSAGE` text,
  `MES_DATE` timestamp(14) NOT NULL,
  `MES_TITRE` varchar(100) default NULL,
  PRIMARY KEY  (`MES_NOMESSAGE`),
  FULLTEXT KEY `MES_MESSAGE` (`MES_MESSAGE`)
) TYPE=MyISAM AUTO_INCREMENT=43 ;

Table Réponse

DROP TABLE IF EXISTS `reponse`;
CREATE TABLE `reponse` (
  `REP_NOREPONSE` int(11) NOT NULL auto_increment,
  `MES_NOMESSAGE` int(11) NOT NULL default '0',
  `MEM_NOMEMBRE` int(11) NOT NULL default '0',
  `REP_REPONSE` text,
  `REP_DATE` timestamp(14) NOT NULL,
  PRIMARY KEY  (`REP_NOREPONSE`),
  FULLTEXT KEY `REP_REPONSE` (`REP_REPONSE`)
) TYPE=MyISAM AUTO_INCREMENT=22 ;

forum.php

Ce script, affichera les différentes sections du forum.
session_start();
  
  include("bd.php");
  include ("footer.php");
  
  //connexion à la base de données
  connectionbd();

Le fichier bd.php contient différentes fonctions reliées à la base de données. Nous expliquerons au fur à mesure de ce tutoriel les fonctions qu'on utilisera.
La fonction connectionbd(), sert à se connecter à la base de données.

$serveur = "localhost";
$utilisateur = "test";
$motDePasse  = "test";
$base        = "test";
$link        = "";

function connectionbd()
{
  global $serveur, $utilisateur, $motDePasse, $base, $link;
  $link = mysql_connect($serveur, $utilisateur, $motDePasse);
  mysql_select_db($base) or die("Connexion impossible");
}

Les variables $serveur, utilisateur... sont des variables globales, lorsque nous les utilisons au sein d'une fonction, nous devons utiliser le mot global.
 
  //si l'usager est déjà connecté
  if(session_is_registered("username")){
    include ("header2.php");
    entete("Forum","Forum programmation, Forum de développement");
    echo '<br/><div class="titresection">Forum</div>';
    echo'<div id="main">';
  }
  else{
    include ("header.php");
    entete("Forum","Forum programmation, Forum de développement");
    echo '<br/><div class="titresection">Forum</div>';
    echo'<div id="main">';
    echo'<div class="cmdforum"><a href="login">Connexion</a> | <a href="inscription">Inscription</a></div><br/>';
  }

Les fichiers: headers, headers2, footers ont été expliqué dans un article précédent. Cette portion de code sert à changer ce qui est affiché à l'écran selon que l'on s'est branché ou non. Si on est pas branché, il est possible de se connecter ou de s'inscrire si l'on n'est pas déjà membre.

//affiche la liste de forum
  $requete = mysql_query("SELECT sec_nosection, sec_nbmessage, sec_nomsection, DATE_FORMAT(sec_datederniermsg,'%d/%m/%Y %H:%i:%s') as datefr from section");
  
  echo'<table class="tabforum">';
  echo'<tr><td class="tabligntitre">:: Forum ::</td><td class="tabligntitre">:: Sujet ::</td><td class="tabligntitre">:: Derniers Message ::</td></tr>';
  $debut=0;
  while ($ligne = mysql_fetch_assoc($requete))
  {
   echo'<tr><td><a href="vueforum.php?sec_nosection='.$ligne['sec_nosection'].'&debut='.$debut.'">'.$ligne["sec_nomsection"].'</a></td><td>'.$ligne["sec_nbmessage"].'</td><td>'.$ligne["datefr"].'</td></tr>';  
  }
  echo'</table><br/>';
  
  echo'</div>';

Ce code affiche les différentes sections disponibles, par exemple sur ce site, ça serait Delphi, Génie logiciel....Il affiche le nom de la section, le nombre de messages de la section ainsi que la date du dernier message. En cliquant sur le nom de la section, le message lié à cette dernière s'affichera.

closebd();
piedpage(); 

Ce code ferme la base de données et affiche un pied de page.
function closebd()
{
  global $link;
  mysql_close($link);
}
Ce code utilise une variable globale définie plus haut et ferme la connexion à la base de données. Le pied de page utilisé est fort simple, le nom du webmestre est affiché ainsi que deux images liées au standard Web.

vueforum.php

Ce script, affichera les messages liés au forum qu'on a choisi. Au début de ce script, il y a une fonction qui permet d'afficher 20 messages par pages. Ce script a été inspiré de celui qu'on retrouve sur le site phpfacile. Ce script peut être trouvé à affichage page par page, des explications y sont données.

entete("Forum","Forum de programmation, Forum de programmation");
  connectionbd();
  
  $nb_affichage_par_page = 20; // on va afficher 20 résultats par page.
  
  echo '<br/><div class="titresection">Forum</div>';
  echo'<div id="main">';
  
  $sec_nosection = $_GET['sec_nosection'];
  
  //compte le nombre de message - utile pour l'affichage page par page
  $requete = mysql_query("SELECT count(mes_nomessage) FROM message where sec_nosection = $sec_nosection");
  $nb_total =  mysql_fetch_array($requete);

Nous nous connectons à la base de données, on affiche 20 résultats par page. Nous obtenons le numéro de la section à partir du script qu'on a vu précédemment. Nous comptons le nombre de messages disponible dans la section. Ce nombre sert à l'affichage. Par exemple si le nombre est 45, nous allons avoir 3 pages. Deux qui auront 20 données et une qui en aura 5.

if (!isset($_GET['debut'])) 
  $debut = 0;
else 
  $debut = $_GET['debut'];
echo'<div class="cmdforum"><a href="inserermsg'.$sec_nosection.'">Nouveau</a></div><br/>';
  
//affiche les informations dans un tableau
echo'<p class="tabforum">';
echo'<tr><td class="tabligntitre">:: Sujet ::</td><td class="tabligntitre">:: Auteur ::</td><td class="tabligntitre">:: Derniers Message ::</td><td class="tabligntitre">:: Nb ::</td></tr>';
   
// Préparation de la requête avec le LIMIT
$requete = mysql_query("SELECT mes_nomessage, mes_titre, mem_nomusager from message msg inner join membre m on m.mem_nomembre = msg.mem_nomembre where sec_nosection=$sec_nosection limit $debut, $nb_affichage_par_page");

Le début de ce code provient de lephpafacile. Cette variable est utile lorsqu'on a plus qu'une page à afficher. C'est la variable qui détermine où qu'on se situe. Nous avons ensuite une ligne qui permet d'insérer un message dans une section. L'affichage des messages (questions) débute, quelques informations sont affichées : le titre, l'auteur, la date du dernier message et le nombre de messages. Par la suite, la requête sélectionne les 20 messages à partir du lieu qu'on se trouve (à partir de la variable debut). Si on reprend l'exemple précédent, avec 45 réponses, la requête pourra avoir 3 valeurs : 0, 20 - 1, 20 - 2, 20.
while ($ligne = mysql_fetch_assoc($requete)) {
      
  $nbreponse= mysql_query("select count(rep_noreponse) as nbreponse from reponse where mes_nomessage=".$ligne['mes_nomessage']."");
      
  $maxdate= mysql_query("select max( DATE_FORMAT( rep_date, '%d/%m/%Y %H:%i:%s' ) ) AS datefr from reponse where mes_nomessage=".$ligne['mes_nomessage']."");
      
  $lignerep = mysql_fetch_assoc($nbreponse);
  $lignedate = mysql_fetch_assoc($maxdate);
      
       
  if ($lignerep["nbreponse"] !=0)
    $rep_noreponse = $lignerep["nbreponse"]; 
  else
    $rep_noreponse = 0;  

  if($lignedate["datefr"] != NULL){
    $rep_date = $lignedate["datefr"];
  }
  else
    $rep_date = "Aucun message";  

  echo '<tr><td><a href="liremsg.php?sec_nosection='.$sec_nosection.'&mes_nomessage='.$ligne["mes_nomessage"].'&debut='.$debut.'">'.$ligne["mes_titre"].'</a></td><td>'.$ligne["mem_nomusager"].'</td><td>'.$rep_date.'</td><td>'.$rep_noreponse.'</td></tr>';  
}
    
echo'</table><br/>';

À partir des résultats de la requête précédente, les informations sont affichées. Lorsqu'aucune réponse n'est trouvée au lieu de rien afficher, nous affichons 0 et aucun message. Lorsqu'on cliquera sur le titre d'un message, les réponses qui lui sont liées s'afficheront (à partir du script liremsg.php).

// on libère l'espace mémoire alloué pour cette requête
    mysql_free_result ($requete);
    mysql_free_result ($nbreponse);
    mysql_free_result ($maxdate);
  }
  
  // on lance la création de la barre de navigation à l'aide de notre fonction, le dernier argument de la fonction étant le nom de notre page WEB sur laquelle on va afficher les résultats de notre requête
  $barre = barre_navigation($nb_total, $nb_affichage_par_page, $debut);

   // on affiche enfin notre barre
  echo '<b>'.$barre.'</b>'; 
  
  echo'</div>';
  
  closebd();
  piedpage();

Ce code libère les ressources allouées pour les requêtes, affiche la barre de navigation, ferme la connexion à la base de données et affiche le pied de page.

liremsg.php

Ce script affiche la question et ses réponses. Le début de ce script est semblable au précédent, s'il y a plus de 20 réponses, il y a une barre de navigation.
entete("Forum","");
  
  connectionbd();
  
  $nb_affichage_par_page = 20; // on va afficher 20 réponses par page.
  
  echo '<br/><div class="titresection">Forum</div>';
  echo'<div id="main">';
  
  $sec_nosection = $_GET['sec_nosection'];
  $mes_nomessage = $_GET['mes_nomessage'];
  
  //compte le nombre de message - utile pour l'affichage page par page
  $requete = mysql_query("SELECT count( rep_noreponse ) FROM reponse rep INNER JOIN message mes ON mes.mes_nomessage = rep.mes_nomessage WHERE mes.mes_nomessage = $mes_nomessage");
  $nb_total =  mysql_fetch_array($requete);
  
  //inserer un nouveau message;
  echo'<div class="cmdforum"><a href="repondremsg'.$sec_nosection.''.$mes_nomessage.'">Répondre</a></div>';

  //afficher la question - requete
  $requete = mysql_query("SELECT mes_nomessage, DATE_FORMAT(mes_date,'%d/%m/%Y %H:%i:%s') AS datefr, mes_message, mes_titre, m.mem_nomembre, mem_nomusager, mem_siteweb, mem_nbmessage, mem_signature from message msg inner join membre m on m.mem_nomembre = msg.mem_nomembre where mes_nomessage=$mes_nomessage");
  
  echo'<table class="tabforum">';
  //info de l'usager
  echo'<tr><td class="membre">'.$ligne['mem_nomusager'].'<br/>'.$ligne['mem_nbmessage'].' messages<br/>'.$ligne["datefr"].'<br/>'.$ligne['mem_siteweb'].'<br/>'.$ligne['mem_signature'].'</td>';
  //sa question
  
  //(si membre de type 1 ou 2) ou c'est notre question
  if((( $_SESSION['type'] == 1) or ($_SESSION['type'] == 2)) or($_SESSION['mem_nomembre']==$ligne['mem_nomusager']))
  {
    //gérer la modification de la question et des réponses - géré avec les variables de session
    //message= 1 si une question
    
    echo'<td><div class="fctforum"><a href=modifiermsg.php?nosection='.$sec_nosection.'&nomessage='.$ligne['mes_nomessage'].'&message=1>Modifier </a>';
    
    echo'<a href=effacermsg.php?nosection='.$sec_nosection.'&nomessage='.$ligne['mes_nomessage'].'&message=1>Supprimer</a></div><br/>';
    echo ''.$ligne['mes_message'].'</td></tr>';
  }
  else
    echo'<td>'.$ligne['mes_message'].'</td></tr>';
  
  
  echo'</table><br/>';

Nous comptons le nombre de réponses au message, un lien est créé enfin d'ajouter une réponse au message existant. Le message et chaque réponse sont affichés chaque fois dans un tableau. Les informations de la question sont affichées. Selon le type du membre: un modérateur ou webmestre, il y a possibilité de d'effacer ou de modifier le message. Cette particularité est une mesure de sécurité.

if (($nb_total = $nb_total[0]) != 0){    
    // sinon, on regarde si la variable $debut (le x de notre LIMIT) n'a pas déjà été déclarée, et dans ce cas, on l'initialise à 0
    if (!isset($_GET['debut'])) 
      $debut = 0;
    else 
      $debut = $_GET['debut'];
  

    //afficher la ou les réponse - requete  DATE_FORMAT(mes_date,'%d/%m/%Y %H:%i:%s') AS datefr 
    $nbreponse = mysql_query("SELECT rep_noreponse, rep_reponse, DATE_FORMAT(rep_date,'%d/%m/%Y %H:%i:%s') AS datefr , m.mem_nomembre, mem_nomusager, mem_siteweb, mem_nbmessage, mem_signature from reponse rep inner join membre m on m.mem_nomembre = rep.mem_nomembre where mes_nomessage=$mes_nomessage limit $debut, $nb_affichage_par_page");
    
    if ( mysql_num_rows($nbreponse) != 0 ){
    //afficher les réponses
    while ($ligne = mysql_fetch_assoc($nbreponse))
    {
      echo'<table class="tabforum">';
      //info de l'usager
      echo'<tr><td class="membre">'.$ligne['mem_nomusager'].'<br/>'.$ligne['mem_nbmessage'].' messages<br/>'.$ligne["datefr"].'<br/>'.$ligne['mem_siteweb'].'<br/>'.$ligne['mem_signature'].'</td>';
      //sa réponse
      //(si membre de type 1 ou 2) ou c'est notre réponse
      if((( $_SESSION['type'] == 1) or ($_SESSION['type'] == 2)) or($_SESSION['mem_nomembre']==$ligne['mem_nomusager']))
      {
        //message= 0 si une réponse
        echo'<td><div class="fctforum"><a href=modifiermsg.php?nosection='.$sec_nosection.'&noreponse='.$ligne['rep_noreponse'].'&message=0>Modifier </a>';
        echo'<a href=effacermsg.php?nosection='.$sec_nosection.'&noreponse='.$ligne['rep_noreponse'].'&message=0>Supprimer</a></div><br/>';
        echo ''.$ligne['rep_reponse'].'</td></tr>';
        
      }
      else
        echo'<td>'.$ligne['rep_reponse'].'</td></tr>';
      
      echo'</table><br/>';
    }
    
    }
  }
  
  // on lance la création de la barre de navigation à l'aide de notre fonction, le dernier argument de la fonction étant le nom de notre page WEB sur laquelle on va afficher les résultats de notre requête

 $barre = barre_navigation($nb_total, $nb_affichage_par_page, $debut);

 // on affiche enfin notre barre
 echo '<b>'.$barre.'</b>'; 

  
 echo'</div>';
  
  closebd();
  piedpage();

Cette portion de code est semblable que la précédente à l'exception que ces les réponses du message qui sont affichées.

inserermsg.php

Le code de ce script ainsi que les prochains ne seront pas affichés, mais une description sera faite. Ce script sert à insérer un nouveau message à une section. Il y a un formulaire pour le message.

modifiermsg.php

Ce script sert à modifier une réponse ou un message. Il y a un formulaire pour le message. Les champs sont déjà remplis par le texte existant. L'usager peut modifier le message.

effacermsg.php

Ce script sert à effacer une réponse ou un message. Le numéro du message est donné à une requête afin d'effacer le message de la base de données.

Téléchargement

Tous les scripts de ce forum peuvent être téléchargé ici.

samedi 19 mars 2005

Espace membre

ESPACE MEMBRE

Dans cet article, nous allons voir comment créer un espace membre. Il y a plusieurs raisons de créer un espace membre, la première peut être la sécurité. Il peut être intéressant de laisser tout le monde lire des messages sur notre forum, mais seulement ceux qui sont membres d'y écrire. Nous avons ainsi de moyen de savoir qui a écrit le message, son adresse IP...
Dans cet article, nous allons voir:
  • Inscription
  • Authentification
  • Oublie de mot de passe
  • Déconnection

Inscription

L'inscription d'un membre est l'occasion d'obtenir diverses informations sur l'usager. Voici une structure de table possible :

DROP TABLE IF EXISTS `membre`;
CREATE TABLE `membre` (
  `MEM_NOMEMBRE` int(11) NOT NULL auto_increment,
  `MEM_NOM` varchar(30) NOT NULL default '',
  `MEM_PRENOM` varchar(30) NOT NULL default '',
  `MEM_NOMUSAGER` varchar(30) NOT NULL default '',
  `MEM_MOTPASSE` varchar(30) NOT NULL default '',
  `MEM_COURRIEL` varchar(30) NOT NULL default '',
  `MEM_TYPE` int(11) NOT NULL default '0',
  `MEM_SITEWEB` varchar(100) default NULL,
  `MEM_SIGNATURE` varchar(50) default NULL,
  `MEM_NBMESSAGE` int(11) default '0',
  `MEM_ENREGISTRE` int(11) default '0',
  PRIMARY KEY  (`MEM_NOMEMBRE`)
) TYPE=MyISAM AUTO_INCREMENT=9 ;
Au niveau du code, il suffit de créer un formulaire. Afin de limiter les inscriptions automatiques par des scripts malicieux, il est possible d'ajouter une série de lettres dans une image. L'usager devra taper ces lettres. De nombreux sites utilisent cette technique.

Protection

Tel que dit précédemment, il est important d'ajouter une protection afin d'éviter des inscriptions multiples. Afin de mettre en oeuvre cette protection, nous allons générer une suite de lettre de façon aléatoire et ensuite créer une image avec ces lettres. Il est ainsi beaucoup plus complexe d'obtenir la valeur des lettres.
function gen_reg_key() {

   //on initialise la variable $key à "vide"

   $key = "";

   //on définit la taille de la chaine (6 caractères ca suffit ;))

   $max_length_reg_key = 6;

   //on définit le type de caractères ascii de la chaine (l'alphabet suffit amplement, mais libre a vous)

   $chars = array(

      "a","b","c","d","e","f","g","h","i","j","k","l","m",

      "n","o","p","q","r","s","t","u","v","w","x","y","z");

   //on comptabilise le nombre total de caractères possibles (26 pour l'alphabet)

   $count = count($chars) - 1;

   //on initialise la fonction rand pour le tirage aléatoire

   srand((double)microtime()*1000000);

   //on tire aléatoirement les $max_length_reg_key caracteres de la chaine

   for($i = 0; $i < $max_length_reg_key; $i++) $key .= $chars[rand(0, $count)];

   //on renvois la clé générée

   return($key);

} 
Maintenant que la chaîne est générée, nous allons créer une image cette chaîne. Noter que la source ci-dessus provient d'une source inconnue.
//En-tête définissant le format png header

header ("Content-type: image/png"); 

//Crée une nouvelle image à palette d'une taille de 100 pixels de largeur par 50 pixels de hauteur

$im = @ImageCreate (100, 50) or die ("Erreur lors de la création de l'image");

//Alloue une couleur pour le fond de l'image

$bgcolor = ImageColorAllocate ($im, 0xC0, 0xC0, 0xC0); //Ca correspond à #C0C0C0

//Alloue une couleur pour le texte de l'image

$font = ImageColorAllocate ($im, 0x00, 0x00, 0x00);

ImageString ($im, 5, 20, 15,base64_decode($_GET['code']),$font);

//Envoie l'image PNG vers le navigateur

ImagePng ($im);

//Désalloue la mémoire de l'image
ImageDestroy($im);

La chaîne générée est passée à ce script d'où le $_Get. La protection ainsi que les données entrées par l'usager doivent être validées afin d'insérer des données uniquement valides dans la base de données. Au niveau des validations, vous pouvez vérifier si le courriel est valide, si le nom de l'utilisateur est déjà présent.

Envoie du courriel

Il est très aisé d'envoyer un courrier en PHP. Le code ci-dessous est employé pour activer le mot compte de l'usager lors de son inscription. Il faut s'assurer d'avoir la fonction PHP mail().
function envoiecourrielvalidation($nom, $nomusager, $to, $motpasse, $nomembre)
  {
    /* sujet */
    $subject = "Inscription: La boîte à prog";
  
    /* message */
    $message = "Bonjour, ".$nom." ! \n\nMerci de vous être enregistré.   Vous êtes priés de conserver cet e-mail dans vos archives. \nVoici les informations concernant votre compte : \n \nNom d'utilisation : ".$nomusager." \nMot de passe: ".$motpasse." \n \nPour activer votre compte, veuillez cliquer sur ce lien :  http://www.laboiteaprog.com/activation.php?mem_nomembre=$nomembre  \n\nL'équipe Forum La boîte à prog";
  
    $headers = "From: La boite à prog <collinm@laboiteaprog.com>\r\n";
    /* and now mail it */
    mail($to, $subject, $message, $headers);
 }

Validation du courriel

Une manière de limiter les abus est de valider le compte de l'usager en lui envoyant un courriel. Cette façon permet de savoir si le courriel inscrit par l'usager est valide et assure de pouvoir retracer l'usager si nécessaire. La validation du courriel se fait si toutes les données entrées par l'usager sont valides. Utiliser la fonction mail de PHP pour envoyer un courriel. Utiliser un gabarit tel que:

Bonjour, Paul Newman !
Merci de vous être enregistré.   
Vous êtes priés de conserver ce courriel dans vos archives.

Voici les informations concernant votre compte : 
Nom d'utilisation : pauln
Mot de passe: arlvlr

Pour activer votre compte, veuillez cliquer sur ce lien :  http://www.laboiteaprog.com/activation.php?mem_nomembre=1

L'équipe Forum La boîte à prog";

Dans le script activation, on vérifie si l'usager à déjà activer son compte. Le champ MEM_ENREGISTRE sert à savoir si l'usager a déjà activé son compte. Si la valeur est 0, son compte n’est pas actif.

connectionbd();
    entete("Activation","");
    
    $mem_nomembre = $_GET['mem_nomembre'];
    
    
    $requete = mysql_query("SELECT mem_nomembre, mem_motpasse, mem_type, mem_enregistre from membre where mem_nomembre=$mem_nomembre ");
    
    $ligne = mysql_fetch_assoc($requete);
    
    //verifier dans la bd si le compte est déjà actif... si oui on affiche un message
    if($ligne["mem_enregistre"] == 1){
    
      echo '<div>Activation</div>';
      echo'<div>';
        
      echo"Votre compte a déjà été activé. Merci";
        
      echo'</div>';
    
    }
    else{
    
      $_SESSION['username'] = $username;
      $_SESSION['password'] = $password;
      $_SESSION['mem_nomembre'] = $mem_nomembre;
      
      mysql_query("update membre set mem_enregistre = 1 where  mem_nomembre= $mem_nomembre ");
      
      echo '<div >Activation</div>';
      echo'<br/><div>';
      echo"Vous venez d'activer votre compte, vous pouvez maintenant envoyez des messages et participer au site. Merci";
        
      echo'</div>';
      
    }
    closebd();
    piedpage();
  }
Si le compte de l'usager n'est pas encore actif, il le devient et on enregistre des variables de session afin que l'usager puise avoir accès aux fonctions réservées au membre.

Authentification

Cette partie consiste à vérifier le nom d'utilisateur ainsi que le mot de passe entrée par l'usager, si les informations sont valides, l'usager à accès au site et on enregistre dans des variables de session quelques informations (tel que vue précédemment). Le code nécessaire pour vérifier les données est identique à celui montré précédemment. Si les données sont valides, nous pouvons rediriger l'usager par exemple dans une section spéciale du site.

Oublie de mot de passe

Il est possible, qu'un usager oublie son mot de passe pour de multiples raisons. Un script qui génèrera un mot de passe aléatoire permettra de nouveau à l'usager de se connecter au site.

Le script pour générer un mot aléatoire qui a été utilisé lors d'un l'inscription de l'usager peut être réutilisé de nouveau pour l'oublie d'un mot de passe. Le nouveau mot de passe est envoyé par courriel à l'usager. Un gabarit qui pourrait ressembler à celui montré dans la section Validation du courriel peut être utilisé.

Déconnection

Cette fonctionnalité supprime les variables de session créée lors de la connexion de l'usager et redirige l'usager sur la page principale du site.

session_start();
if(session_is_registered("username")){
  session_destroy();
$url="/index";
header("location: $url");

Fonctionnalité

Une fois que l'utilisateur est connecté, tous vous est permis. Prenons exemple sur ce site, une fois connecté, vous pouvez participer au site, modifiez votre profil...
Nous avons vu quelques fonctionnalités de base pour gérer un espace membre sur un site.

D'autres fonctionnalités peuvent être ajoutées, un chat en ligne, amélioration de la sécurité... afin d'avoir un espace membre encore plus riche.

lundi 28 février 2005

KQemu


KQEMU

Une nouvelle étape a été franchie dans le projet d'émulation de processeur Qemu (QEMU Accelerator Module). Kqemu est un module qui permet d'utiliser le processeur hôte au lieu d'utiliser le processeur de la cible. Par exemple, nous sommes sous Linux et on utilise Windows à l'aide de Qemu. Windows fonctionne à l'aide du processeur émulé par Qemu, ça fonctionne très bien, mais le système d'opération Windows fonctionne lentement. Lorsqu'on utilise Kqemu, le système Windows utilise directement notre processeur ainsi les performances sont bien meilleur. Kqemu fonctionne que de PC à PC, donc n'espérer pas d'avoir de meilleure performance sur votre G5 en tentant d'émuler Beos. En utilisant ce module, les performances sont très près de Win4lin.

Préalable

  • Kqemu
  • une version supérieure à 0.6.1 de Qemu
  • les sources du noyau
  • la sdl
  • la sdl-devel
  • textinfo
Notez que j'ai dû installer les paquets et logiciels ci-dessus (suse 9.2). Il est possible que vous deviez en installer d'autres si vous utilisez une autre distribution.

Installation

Vous devez télécharger le code source de Qemu à partir du cvs. Pour de plus amples renseignements concernant cvs, allez lire le tutoriel que j'ai créé.
Vous pouvez obtenir les sources avec une commande similaire à:
cvs -z3 -d:ext:anoncvs@savannah.gnu.org:/cvsroot/qemu co qemu

Ensuite téléchargez Kqemu et décompressez-le dans le répertoire de qemu. Dans l'exemple ci-dessous, on supposera que:
/home/collinm/Documents/qemu
contient les sources de qemu et kqemu. En mode console:
cd /home/collinm/Documents/qemu

./configure --target-list=i386-softmmu

make
Connectez vous en root
make install

Qemu est maintenant installé, si vous désirez utiliser Kqemu, vous devez taper:
modprobe kqemu

Démarré qemu et vous pouvez vérifier si kqemu est réellement utilisé en tapant:
/sbin/lsmod | grep kqemu
Cette commande devrait vous retourner
kqemu                  43272  2

Si 2 n'est pas là, kqemu n'est pas chargé.

Notez qu'actuellement, Kqemu ne fonctionne pas encore avec la série de Windows 9x.
Vous pouvez maintenant démarrer une installation de beos, qnx, solaris Windows.... Insérez-le cd du système voulu
dd of=hd.img bs=2048 seek=3000000 count=0

L'installation du système voulu démarrera. Ce module permet de faire fonctionner Windows 2000 et Windows 98 avec de bonnes performances sous un 1800+ et 512 megs de RAM.

lundi 7 février 2005

Gestion de BB-Code


GESTION DE BB-CODE

Le bb-code est utilisé afin de simplifier l'utilisation de diverses fonctionnalités pour un usager. Souvent sur les sites lorsqu'on inscrit :), c'est une image avec un sourire... plusieurs images existent pour s'exprimer. Le bb-code consiste donc à taper un code qui sera transformé en une image ou en un autre code.

L'usager pourrait toujours taper http://www.yahoo.com, mais c'est beaucoup plus simple pour lui de faire [url]www.yahoo.com[/url]. En fait, on n'a qu'à filtrer le code que l'usager entre.

function bbcode($m) {
    switch($m[1]) {
        // balise <code>
        case 'code' :
           return '<div class="code"><pre>'.htmlentities($m[2]).'</pre></div>'; 
        break;
        // balise <url>
        case 'url' :
          if (preg_match ('`^http://`', $m[2]))
            return '<a href="'.$m[2].'" class="machin">'.$m[2].'</a>';
          else
            return '<a href="http://'.$m[2].'" class="machin">'.$m[2].'</a>'; 
        break;
        // balsie <img>
        case 'img' :
        return '<img src="'.$m[2].'" alt="mon image"/>';
    }
}
La fonction ci-dessus est appelée avec:
$st4="mon site web préféré est: [url]www.laboiteaprog.com[/url]
$str = preg_replace_callback('`\[(code|url|img)\](.+?)\[/\1\]`si', 'bbcode', $str);

Chaque fois que les mots: code, url ou img se retrouveront en [], la fonction bbcode est appelée. Pour avoir cet effet, preg_replace_callback est utilisé. $m[1] contient les mots et $m[2] contient ce qui entre les tags. Par exemple avec <url>www.yahoo.com</url>, url est le mot et www.yahoo.com est ce qui entre les deux. Lorsque le mot code est trouvé, ce qui est entre les balises sera affiché dans un div. Tel que montré, nous pouvons convertir le code aisément, ce qui permet d'utiliser des fichiers css et de personnaliser davantage ce qui est écrit sans trop de difficulté pour l'usager. Pour le mot url, on vérifie si la chaîne contient http://, si elle le contient pas, on l'ajoute.

Nous avons vu comment créer le bb-code, dans l'exemple montré, les balises s'écrivaient: [tag]. Cette fonction retourne la chaîne après les changements effectués. C'est donc cette chaîne qui doit être insérée dans la BD ou fichier si vous désirez sauvegarder le tout. Le script montré ci-dessus a été inspiré à partir d'un autre de source inconnue.

jeudi 6 janvier 2005

Gambas


GAMBAS

Les environnements de développent intégré (rad) tel que Delphi, Visual basic ne sont pas légion sous Linux surtout en opensource. On retrouve bien sûr Kylix de Borland, mais il comporte de nombreuses erreurs et coûte très cher. Sinon il y a Netbeans pour le Java. En commerciale il y a Jbuilder, IntelliJ. Les fanatiques de Visual basic ou de Delphi étaient un peu oublié sous Linux. Gambas tente de combler cette lacune.

Gambas est un rad qui utilise le langage Basic. Il a de forte ressemblance avec Visual basic. Gambas vient d'arriver à la version 1. Il est enfin stable. Même si Gambas n'atteint pas le niveau de son confrère, il permettra de créer des applications très aisément. Il est possible d'obtenir Gambas à l'adresse : http://gambas.sourceforge.net/

Fonctionnalité Gambas

  • Présentement la librairie graphique utilisée est qt, mais puisque l'interface est un composant, il serait possible d'utiliser d'autres librairies.
  • Traducteur linguistique(manuel)
  • Gestionnaire de base de données
  • Création de programme graphique ou non
  • Les fichiers sont compilés et ensuite exécutés par un interpréteur
  • Débuggeur

Problème Gambas

Il y a peu de composant graphique disponible. Les fonctionnalités ne sont pas nombreuses si on compare ce produit à Delphi. Néanmoins, il permettra surement à des admirateurs de rad sous Windows de débuter à programmer sous Linux.
Le départ de l'application nous affiche une fenêtre pour nous guider.


Cet environnement de développement intégré possède déjà le minimum de ce qu'on peut attendre de ce genre d'outils. Quelques exemples sont inclus afin de familiariser avec le langage Basic et Gambas.




La création de l'interface est très simple, mais surement différente des autres rad que vous avez pu utiliser. On doit cliquer sur un composant, ensuite on doit cliquer sur le formulaire et faire un agrandissement avec la souris... faut essayer si on comprend pas réellement. Le projet est ouvert donc si vous voulez y contribuer, n'hésiter pas. C'est un outil qui peut s'avérer très intéressant pour ceux désirant s'initier à la programmation.

mercredi 22 décembre 2004

Comment connaître la liste de carte pci d'installé?


Comment connaître la liste de carte pci d'installé?

/sbin/lspci

Il existe aussi la commande

scanpci
0000:00:00.0 Host bridge: VIA Technologies, Inc. VT8375 [KM266/KL266] Host Bridge
0000:00:01.0 PCI bridge: VIA Technologies, Inc. VT8633 [Apollo Pro266 AGP]
0000:00:09.0 SCSI storage controller: Adaptec AHA-3960D / AIC-7899A U160/m (rev 01)
0000:00:09.1 SCSI storage controller: Adaptec AHA-3960D / AIC-7899A U160/m (rev 01)
0000:00:11.0 ISA bridge: VIA Technologies, Inc. VT8233 PCI to ISA Bridge
0000:00:11.1 IDE interface: VIA Technologies, Inc. VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE (rev 06)
0000:00:11.2 USB Controller: VIA Technologies, Inc. VT82xxxxx UHCI USB 1.1 Controller (rev 1b)
0000:00:11.3 USB Controller: VIA Technologies, Inc. VT82xxxxx UHCI USB 1.1 Controller (rev 1b)
0000:00:11.4 USB Controller: VIA Technologies, Inc. VT82xxxxx UHCI USB 1.1 Controller (rev 1b)
0000:00:11.5 Multimedia audio controller: VIA Technologies, Inc. VT8233/A/8235/8237 AC97 Audio Controller (rev 30)
0000:00:11.6 Communication controller: VIA Technologies, Inc. AC'97 Modem Controller (rev 70)
0000:00:12.0 Ethernet controller: VIA Technologies, Inc. VT6102 [Rhine-II] (rev 70)
0000:01:00.0 VGA compatible controller: nVidia Corporation NV25 [GeForce4 Ti 4200] (rev a3)

Quand JPA rencontre ses limites, pensez à jOOQ et au MULTISET

Une seule requête, un graphe d'objets complet — ce n'est pas de la magie, c'est du SQL. La base du problème Dans le monde JPA, q...