Table multilangues

Mammouth du PHP | 725 Messages

29 juil. 2012, 04:28

Bonjour,

J'ai une table qui comprend du texte traduit en 2 langues:

Original: Francais
Traduction: Anglais, Allemand

Alors je dois verifier si cet article au moins est traduit en une seule langue pour afficher la phrase (cet article est disponible en ces langues: drapeaux des langues)

table SQL:

CREATE TABLE IF NOT EXISTS `articles` (
  `id` int(3) NOT NULL AUTO_INCREMENT,
  `article` LONGTEXT NOT NULL,
  `article_en` LONGTEXT NOT NULL,
  `article_al` LONGTEXT NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;

--
-- Dumping data for table `chansons`
--

INSERT INTO `chansons` (`id`, `article_en`, `article_al`, `article_es`) VALUES
(1, 'Bonjour', 'Good Morning', 'Hallo'),
(2, 'Bonsoir, 'Good Evening', 'guten Abend'),
(3, 'Bonne Nuit, 'Good Night', 'Gute Nacht');
Ce n'est qu'un petit exemple, donc je veux verifier que la traduction d'une langue est disponible pour au moins une entree (un id), si c'est bon je vais afficher dans la page:
Cet article est disponible en EN et DE:
Bonjour Bonsoir Bonne Nuit

La traduction ici
Merci a vous

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

29 juil. 2012, 18:51

Et c'est quoi la question ? :P

Comment sais-tu si une traduction est présente en base ou non ?
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Mammouth du PHP | 2278 Messages

29 juil. 2012, 21:07

J'aurais commencé par élaborer des tables qui permettent une évolution plus facile:

Code : Tout sélectionner

table_principale: id_ouvrage automatique, date_publication,auteur,éditeur .... table textes_fr id copié depuis table_principale, titre, texte table textes_en_gatinais_moyen id copié depuis table_principale, titre, texte
Une jointure devrait alors venir à bout de la question
Vanitas vanitatum et omnia vanitas
Mes derniers livres :
Sauvez les Mots chez BoD,
Tous les chemins mènent à ROM chez BoD

Mammouth du PHP | 725 Messages

01 août 2012, 09:07

donc je vais etablir 2 requete:
SELECT * FROM table_en

SELECT * FROM table_de

if($result_en) OR ($result_de)

echo 'cet article est dispo en langues:';

if($result_en) echo '<img src="en.png"" />';
if($result_de) echo '<img src="de.png"" />';

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

01 août 2012, 10:10

Ou plus simplement faire une jointure externe pour aller vérifier si des traductions existent en ne faisant qu'une seule requête :
SELECT table_principale.champ, ..., table_en.champTraduit, table_de.champTraduit
  FROM table_principale
    LEFT OUTER JOIN table_en ON table_principale.idTruc = table_en.idChose
    LEFT OUTER JOIN table_en ON table_principale.idTruc = table_de.idChose
WHERE ...
L'intérêt de la jointure externe ici (LEFT OUTER JOIN), est qu'elle te retournera les résultats de ta table principal, même s'il n'y a pas de traduction dans les autres tables (alors qu'un INNER JOIN ne retournerait que celles qui sont entièrement traduites)

Après, personnellement plutôt que de créer une table par langue, je préfère me limiter à une seule table pour les traductions avec un id "langue". Cela permet de facilement ajouter de nouvelles langues (puisqu'il suffit d'un nouvel enregistrement en espagnol ou en italien) sans avoir pour cela à modifier la structure de la bdd ni intervenir sur le code.
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Mammouth du PHP | 725 Messages

02 août 2012, 08:34

alors le mieux est de creer une seule table ou bien une table par langue

Mammouth du PHP | 725 Messages

02 août 2012, 08:54

En se basant sur cette table et cet exemple, comment le faire en une seule requete?
<?php
$db_host = 'localhost';
$db_user = 'root';
$db_passwd = 'root';
$db_name = 'test';
# Charset
$db_charset = 'utf8';



$connexion = new PDO('mysql:host='.$db_host.';dbname='.$db_name, $db_user, $db_passwd
    		, array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES '.$db_charset.'')); //SET NAMES utf8
			$connexion->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);



$select = 'SELECT * FROM articles';
//echo $select;
$req = $connexion->query($select);
$result = $req->fetchAll();
$total = count($result);
echo 'Total des articles: '.$total.'<br />';


foreach($result as $k=>$v)
	{
		$article 	= $v['article'];
		$article_en = $v['article_en'];
		$article_al = $v['article_al'];
	} // end foreach
	
		//echo $article_en.'<br />';
		//echo $article_al.'<br />';
	
	if(($article_en) OR ($article_al))
	{
		echo 'Cet article est disponible en langues suivantes<br />';
	}
		
		
		
		if($article_en)
		{
			echo '<a href="multilangue.php?lang=en">Anglais</a> ';
		}
		
		if($article_al)
		{
			echo '<a href="multilangue.php?lang=de">Allemand</a> ';
		}
	
	
	$lang 		= Isset($_GET['lang'])		? $_GET['lang']			 		: $lang 	= Null;
	
		switch($lang)
		{
			case 'en';
			echo $article_en;
			break;
			
			case 'de';
			echo $article_al;
			break;
			
			default:
			echo $article;
		}

?>


Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

02 août 2012, 11:12

C'est difficile de dire ce qui est mieux, puisque cela dépend surtout de ton contexte. Tu es seul développeur ou tu travail en équipe ? c'est un dev perso ou un dev pro ? c'est un site internet ou intranet ? c'est une application ? est-ce toi qui interviendra dessus pour la maintenir dans 6 mois ou quelqu'un d'autre... J'aurais tendance à dire qu'il faut faire avec ce qui te rends le plus à l'aise (ou vous rends, ou rendra à ceux qui passeront à près toi :))

Pour le comment faire la jointure, il te suffit de reprendre ma requête (je me suis d'ailleurs planté dans le 2ème outer join, c'est bien sur la table_de qu'on interroge) et de remplacer ce qui doit l'être :
- au lieu d'un "SELECT * " tu listes les champs que tu veux récupérer (c'est plus fastidieux, mais au moins, tu n'as aucun doute sur les données que tu récupères où sur l'ordre dans lequel elles arrivent)
- au lieu de table_principale, tu utilises ta table article
- au lieu de table_en, tu utilises ta table de traduction en anglais
- au lieu de idTruc et idChose, tu utilises les noms de tes colonnes qui font que tu sais que pour un idTruc dans ta table article, tu dois aller chercher les enregistrements associés dans ta table de traduction :)

(je t'ai tout expliqué - du moins en principe - alors nan, je le ferais pas pour toi :p)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Mammouth du PHP | 725 Messages

03 août 2012, 03:46

Tu es seul développeur ou tu travail en équipe ?
Je suis le seul
c'est un dev perso ou un dev pro ?
Pro
c'est un site internet ou intranet ?
Internet
c'est une application ?
C'est un script de traduction des articles
est-ce toi qui interviendra dessus pour la maintenir dans 6 mois ou quelqu'un d'autre...
Le seul qui interviendra

Je prefere bien mettre une seule table, si c'est possible, ca ne contient pas plus de 100 enregistrements, ce n'est qu'une phase de test

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

03 août 2012, 12:20

Alors tu peux effectivement le gérer avec une seule table "articles" qui serait constituée de id, langue, titre, article, auteur, ... (ta clé primaire étant alors id+langue) mais personnellement je trouve plus confortable de faire une table principale avec toutes les informations de ton article (y compris celles qui ne seraient pas traduites : id, dates, auteur, ...) et une seconde table de traductions qui contient uniquement les données traduites (id de l'article, langue, titre & article).

Tu pourra ainsi :
- récupérer les articles en français (ou dans une autre langue) :
SELECT art.id, art.date, art.auteur, ... trad.titre, trad.article, ... 
  FROM articles art 
    INNER JOIN traductions trad ON art.id = trad.id AND trad.langue = 'FR' 
  WHERE art.id = xxx
- connaitre les langues disponibles pour un article
SELECT trad.langue 
  FROM traductions trad
  WHERE trad.id = xxx
- ajouter des contraintes d'intégrité (la suppression d'un article en base supprimerait en cascade toutes les traductions associées ; empêcher la saisie d'une traduction si l'article n'existe pas au préalable, ...)

Ce ne sont là que quelques pistes, à toi de voir ce qui te convient le mieux :)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Mammouth du PHP | 725 Messages

03 août 2012, 17:36

J'ai compris votre idee Ryle pour une seule table, sur cette table, je n'ai que quelques mots a traduire, pas de langues phrases au maximum 100 enregistrements, et ne seront pas supprimes, alors pour la 2eme etape, je vais mettre 2 tables comme t'as propose sur un autre script, je vais essayer la premiere etape (une seule table), apres je vais passer a la 2eme qui est gourmande