SQUELETTE SITE MULTILINGUE+MYSQL+CSS

monoceros01 Messages postés 420 Date d'inscription vendredi 28 novembre 2003 Statut Membre Dernière intervention 20 mars 2006 - 3 nov. 2005 à 07:15
monoceros01 Messages postés 420 Date d'inscription vendredi 28 novembre 2003 Statut Membre Dernière intervention 20 mars 2006 - 3 nov. 2005 à 13:46
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/34458-squelette-site-multilingue-mysql-css

monoceros01 Messages postés 420 Date d'inscription vendredi 28 novembre 2003 Statut Membre Dernière intervention 20 mars 2006
3 nov. 2005 à 13:46
Oui bon, ImmortalPC j'ai pas poussé le vice jusqu'à lui demander d'optimiser son code hein :) j'ai préféré insister sur ce que je pense être le plus important :)
monoceros01 Messages postés 420 Date d'inscription vendredi 28 novembre 2003 Statut Membre Dernière intervention 20 mars 2006
3 nov. 2005 à 13:38
XD merci merci :p
Mais je vais ajouter un truc que j'ai oublié =)

Dans mon exemple de structure de base de données, j'ai mis pour la table `pages` la paire de champs `id_page` et `id_lang` en PRIMARY KEY ce qui veut dire que tu peux avoir des doublons dans les colones, mais pas dans les paires.

Par exemple :

id_page | id_lang
--------------------
1 | 1
1 | 2
1 | 3
2 | 1
2 | 2
2 | 3
3 | 1
3 | 2
3 | 3

Est bon, mais pas :

id_page | id_lang
--------------------
1 | 1
1 | 2
1 | 3
1 | 2 <== Cette ligne forme un doublon de la paire (`id_page`, `id_lang`)

Ce qui permet d'avoir ainsi, plusieurs langues pour la même page, mais pas deux versions d'une même langue pour la même page.
ImmortalPC Messages postés 954 Date d'inscription mardi 11 mai 2004 Statut Membre Dernière intervention 11 novembre 2008 2
3 nov. 2005 à 13:34
Salut,
Mono t'as oublié des trucs !!!
1) <? n'est pas valide !
Replacer par <?php

2) Les " sont pas térrible ! C'est lent mais ça reste encore un choix de codage.
Replacer par '

3) Les normmes XHTML ;-) c'est le bonus.....

4) éviter les echo en trop !!
@+
malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 25
3 nov. 2005 à 09:21
Hello,

qu'est-ce que tu veux ajouter à ça...? lol, Mono, le tueur de commentaires ;-)
monoceros01 Messages postés 420 Date d'inscription vendredi 28 novembre 2003 Statut Membre Dernière intervention 20 mars 2006
3 nov. 2005 à 07:15
Bon il y a plusieurs choses à en dire =):
Résumons son fonctionnement :
Tout le script part du fichier indexmysql.php (le nommer index.php aurait été plus logique donc).
Puis, on va diviser les différentes actions de ce fichier:
- tu récupères les variables envoyées dans l'url
- tu commences à envoyer le début de la page html (DOCTYPE, HEAD et début du BODY)
- tu crées et affiche tes liens vers les versions fr, en et nl de tes pages
- tu te connectes à la base
- tu selectionnes tout le contenu de ta table $tablename (="page".$lang)
- tu fais une boucle while pour vérifier qu'on inclut bien une page répertoriée dans ta bdd

Maintenant considérons que l'on inclut en/page1.php
- tu définis la variable id et lui assigne la valeur 1
- tu inclus include/middleindex.php

Que se passe-t-il dans middleindex.php ?
- tu te connectes (à nouveau) à la base de données
- tu sélectionnes la page $tablepage et tu ajoutes une clause pour ne sélectionner que la ligne ou $id_page = 1 (id_page étant en PRIMARY KEY)
- tu fais une boucle while pour afficher le résultat



Bon maintenant critiquons tout cela transversalement :)

Tu as inclus le fichier connexion/config.php et t'es connecté(e) à la base de données deux fois alors qu'une seule suffit :) et tu n'as fermé(e) aucune de tes connexions.
Tu devrais rajouter dans ton fichier connexion/config.php :
$id_con = mysql_connect($host,$user,$pass) or die(mysql_error());
mysql_select_db($bdd) or die(mysql_error());
(oui je déconseilles l'utilisation des @)
Et il te suffit d'inclure ce fichier une seule fois au début de la page indexmysql.php, puis de mettre :
mysql_close($id_con);
à la fin de ce dernier.


Ensuite, la création de tes liens fr, en et nl :
echo"[.indexmysql.php?lang=fr&page= fr] |";
echo"[.indexmysql.php?lang=nl&page= nl] |";
echo"[.indexmysql.php?lang=en&page= en]";
Ceci est tout de même plus rapide (bon ok je chipotte).


En ce qui concerne tes requêtes de sélection :
"SELECT * FROM $tablepage"
"SELECT * FROM $tablepage WHERE id_page='$idpage' "
Tu utilises le joker * ce qui implique que tu sélectionnes tous les champs de ta table. Mais, dans le cas de la première requête, tu n'utilises qu'un seul champ (`titre_page`) et, dans le cas de la seconde, que sept sur onze. Donc tu sélectionnes des champs inutilement.
De plus, ta seconde requête ne selectionnera quoiqu'il arrive qu'une seule ligne. Donc la boucle while qui suit est inutile.


Sinon, j'aimerais revenir sur une condition que tu as affichée dans le while de indexmysql.php :
if ($page == '$lang/page1.php')
{
require_once("$lang/page1.php");//page par défaut
}
Déjà, je pense que tu aurais dû mettre
if ($page == $lang.'/page1.php')
ou
if ($page == "$lang/page1.php")
Ensuite, tu cherches à vérifier si $page est égale à "fr/page1.php" ou "en/page1.php" "nl/page1.php". Or, $page contient le nom du fichier sans son chemin ni son extension. Donc ta condition ne sera jamais vrai.
Dans la logique de ton script, j'aurais plutôt écrit :
if ($page == $result['titre_page'] && file_exists($lang.'/'.$result['titre_page'].'.php'))
{
include($lang.'/'.$result['titre_page'].'.php'); //la page existe et est répertoriée
}
else if(file_exists($lang.'/'.page1.php'))
{
include($lang.'/'.page1.php'); //la page n'existe pas donc on affiche celle par défaut si elle existe
}
else
{
die('fichier spécifié introuvable'); //la page par défaut n'existe pas
}


Enfin, j'aimerais que tu réfléchisses sur l'utilité d'inclure les différentes pages (en/page1.php , en/page2.php,...). Car en effet, leur fonction actuelle est juste :
- de définir la variable id et lui assigner une valeur (1, 2,...)
- d'inclure include/middleindex.php
Or, la variable id pourrait facilement être définie dans l'url (?lang=en&id=1). Ces informations seraient alors suffisantes pour aller chercher le contenu de tes pages dans la table 'page'.$lang et dans la ligne id_page = $id, et les formater via ta page middleindex.php (qui n'est autre qu'un template en passant :) )



Bon voilà pour ton code. Nous allons passer à la structure de ta base de données qui n'est malheureusement pas terrible je pense.

Déjà, il faut savoir que la structure d'une base de données nécessite une réflexion importante car toute ton application repose dessus.

Ta base est organisée en autant de tables que l'on souhaite avoir de langues différentes et chaque table est constituée des mêmes champs. Mais, si deux tables (ou plus) de structures exactement identiques cohéxistentent dans la même base de données, c'est en général une erreur!
En effet, la structure d'une base de données est quelque chose qui, en général, ne doit pas bouger. Ton application est sensée fonctionner sans avoir à y toucher.
A moins d'ajouter une fonctionnalité à ton site. Mais l'ajout d'une langue n'en est, à mon sens, pas une.

Comment faire alors?
Il ne faut pas oublier que MySQL est un Système de Gestion de Base de Données RELATIONNELLES (SGBDR). Établir des relations entre tes données te permettras de résoudre ce problème.
Je vais te montrer comment j'aurais fait (je n'ai pas passer beaucoup de temps à y réflechir donc il se peut que ça ne soit pas optimal) :

CREATE TABLE `langues` (
`id` int(11) NOT NULL auto_increment,
`abreviation` varchar(2) NOT NULL default '',
`nom` varchar(20) NOT NULL default '',
PRIMARY KEY (`id`),
) Type=MyISAM ;

CREATE TABLE `pages` (
`id_page` int(11) NOT NULL auto_increment,
`id_langue` int(11) NOT NULL,
`maj_page` date NOT NULL default '0000-00-00',
`menu_page` varchar(50) NOT NULL default '',
`ordre_page` varchar(20) NOT NULL default '',
`pagename_page` longtext NOT NULL,
`titlecadre1_page` longtext NOT NULL,
`contenucadre1_page` longtext NOT NULL,
`img_page` varchar(100) NOT NULL default '',
`typeimg_page` varchar(10) NOT NULL default '',
`fichier_page` varchar(100) NOT NULL default '',
PRIMARY KEY (`id_page`,`id_langue`)
) Type=MyISAM ;

Voici la relation : Pour une langue répertoriée dans la table `langues` correspond zéro, une ou plusieurs pages contenues dans la table `pages`.
En pratique, il te suffit de créer dynamiquement, en listant les langues disponibles dans la table `langues`, tes liens vers les version fr, en et nl de tes pages de cette façon :
$query = "SELECT `id`, `abreviation`, `nom` FROM `langues` ORDER BY `nom` ASC";
$result = mysql_query($query);
$liens = '';
while($datas = mysql_fetch_array($result))
{
$liens. = ($liens !== '') ? ' | ' : '';
$liens. = '['.$_SERVER['REQUEST_URI'].'?lang='.$datas['id'].'&page='.$_GET['page'].' '.$datas['nom'].']' ;
}
Ce qui t'afficheras des liens du style :
en

Et pour accéder au contenu de la page, tu as juste à faire :
$query = 'SELECT `maj_page`, `menu_page`, `ordre_page`, `pagename_page`, `titlecadre1_page`, `contenucadre1_page`, `img_page`, `typeimg_page`, `fichier_page` FROM `pages` WHERE `id_page`=\''.$_GET['page'].'\' AND `id_langue`=\''.$_GET['lang'].'\'' ;
$result = mysql_query($result);
if(mysql_num_row($result) === 0)
{
die('la page n'existe pas dans cette langue');
}
else
{
$datas = mysql_fetch_array($datas);
include('include/template.php');
}

Et voilà =)
Oui bon! La requête est immense et c'est pour cela qu'on est tenté de mettre un *, mais au moins tu as un visuel de chaque champ sélectionné. Ainsi, pour afficher tes variables tu n'as pas besoin de tout le temps vérifier leur syntaxe dans phpmyadmin =). De plus, j'ai mis les variables $_GET['page'] et $_GET['lang'] dans la requête, ce qui est évidemment une erreur du point de vu sécurité. Il faut d'abord vérifier si elles existent et si ce sont bien des nombres entiers (is_int())

Sinon, je te conseille de mettre carrément toute ta page HTML (du Doctype au </html>) dans template.php, et de mettre en variable tout ce que tu compte y afficher (comme la variable $liens ou $datas).

Bon je pense avoir tout dis =) (hem! quoi trop dit?)

Voilà, Voilà.
Bonne journée, bon codage, bon... p'tit dèj' :)

P.S. :
Je n'ai pas commenté les autres fichiers car ils n'intervenaient pas dans ton script principal visiblement (mais il y aurait pas mal de chose à en dire (notamment sur une boucle while qui affiche un TITLE, un META et un LINK) dans header.php... ahem!)
Rejoignez-nous