chiefrebelangel
Goto Top

Homepage mehrsprachig machen mit PHP und MySQL

In diesem Tutorial möchte ich euch zeigen wie ihr ganz einfach und schnell eure Homepage mehrsprachig machen könnt - mit Hilfe von PHP und MySQL. Ich benutze in meinem Beispiel die Sprachen Deutsch und Englisch. Aber ihr könnt jede beliebige Sprache benützen. Ihr könnt natürlich auch mehr als zwei Sprachen benutzen, aber dann müsst ihr die MySQL-Tabelle entsprechend anpassen. Wenn ich ein bisschen mehr Zeit habe ändere ich das Tutorial noch und bringe euch noch Beispiel wie man das ganze auch ohne MySQL machen kann.

Manchmal ist es erforderlich, das der Inhalt einer Homepage in mehreren Sprachen verfügbar ist. Sei es nun um die Firmen-Homepage internationalen Kunden zu präsentieren oder um ein Produkt/eine Idee/ein Service international bekannt zu machen. Der normale Weg ist der Weg des statischen HTML. Das bedeutet aber jede HTML-Datei von Hand zu Fuss zu übersetzen. Und das bedeutet eine Menge Schreibkram. Darum ist diese PHP/MySQL-Lösung äußerst bequem und elegant. Und nachdem ihr dieses Tutorial gelesen habt wisst ihr auch wie es geht!


Zunächst einmal müssen wir auf unserem Datenbank-Server eine Datenbank anlegen. Ich gehe mal davon aus, das ihr wisst wie man phpMyAdmin oder ähnliche Tools benutzt. Trotzdem schreibe ich euch hier den SQL Code auf.
   CREATE DATABASE my_db;
Mit dem Befehl \u my_db; wechseln wir in unsere neu erstellte Datenbank. Jetzt können wir die Tabelle anlegen, die wir benötigen um den Text zu speichern.
   CREATE TABLE lang (
      id int(11) NOT NULL default '0',  
      `key` varchar(254) NOT NULL default '',  
      de text,
      en text,
      PRIMARY KEY  (id)
   ) TYPE=MyISAM;
In dieser Tabelle gibt es drei Spalten, die besonders wichtig sind. Das sind `key`, de und en! In `key` wird ein Schlüsselwort abgespeichert, mit dessen Hilfe wir uns später den gewünschten Text anzeigen lassen können. In de bzw. en ist der deutsche bzw. englische Text gespeicher.
Um die multilingualität unserer Homepage zu testen, müssen wir auch einen Test-Eintrag in unserer MySQL-Tabelle speichern. Das geht so:
   INSERT INTO lang VALUES (1, 'willkommen', 'Willkommen auf meiner Homepage', 'Welcome to my homepage');  
Jetzt sind wir bereit uns dem PHP-Code zuzuwenden!


Um es schön sauber und ordentlich zu machen erstellen wir mit unserem Editor am besten eine neue Datei die wir module.inc.php nennen. Diese Datei speichern wir in dem dafür angelegten Verzeichnis "inc/". Der Inhalt der module.inc.php-Datei ist folgende Funktion:
<?php
   function LoadLang($lang) {
      $text = array();
      if(mysql_connect("host", "user", "passwort")):  
         mysql_select_db("my_db);  
	 $GETlang = "select `key`,`".$lang."` from lang order by id;";  
	 $RESlang = mysql_query($GETlang);
	 while($row = mysql_fetch_row($RESlang)):
	    $text[$row[0]] = $row[1];
	 endwhile;
      endif;
			
      return $text;
   }
?>
Sehen wir uns diese Funktion jetzt etwas genauer an. Als erstes fällt auf, das die Funktion ein Argument erwartet, nämlich $lang. $lang muss die Sprache enthalten, die man gerne hätte. Zum Beispiel "de" für Deutsch oder "en" für Englisch. Warum ausgerechnet "de" bzw. "en"??? Ganz einfach: Weil so unsere Spalten in der MySQL-Tabelle heißen. Wenn wir den Query-String den wir an die Datenbank senden näher untersuchen fällt uns auch auf, wieso das so sein muss! $GETlang = "select `key`,`".$lang."` from lang order by id;"; bedeutet das SQL die Spalten `key` und `de|en` ausspucken soll!
In einer while-Schleife wird die Tabelle solange ausgelesen wie Daten gespeichert sind. Und diese Daten werden in einem Array gespeichert. Auch hier gibt es eine kleine Besonderheit. Wir benutzen hier kein normales Array, sondern ein assoziatives Array (auch Hash genannt). Hier wird nicht über einen Index auf die Daten zugegriffen sondern über ein Schlüsselwort. Nach der while-Schleife wird das erzeugte Array als Rückgabewert zurückgegeben.

Jetzt kümmern wir uns um unsere fiktive index.php-Datei. Hier müssen wir als erstes unsere Modul-Datei einbinden, damit wir auf die Funktion zugreifen können.
   require_once("inc/module.inc.php");  
Jetzt müssen wir nur noch unsere Funktion aufrufen und dann sind wir fertig. Zunächst möchte ich aber noch etwas erläutern! Ich gehe davon aus, das die Sprache, die man sehen möchte als Argument an die Datei index.php übergeben wird.Dabei ist es unabhängig ob der Benutzer auf einen Link klickt oder die Sprache in einem Drop-Down-Menü auswählt. Wichtig ist nur das die Daten per GET an die Datei übergeben werden. Das sieht dann in der URL-Leiste eures Browsers so aus:
   http://www.eure-homepage.tld/index.php?lang=de
lang ist der Name der Variable und de ist ihr Wert! Wir überprüfen jetzt, ob es die Variable $_GET['lang'] gibt und interagieren entsprechend.
<?php
   if(!empty($_GET['lang'])):  
      $lang = LoadLang($_GET['lang']);  
   else:
      $lang = LoadLang("de");  
   endif;
?>
Wir überprüfen hier, ob die Variable $_GET['lang'] leer ist. Wenn nicht, wir unsere Funktion von oben aufgerufen und ihr als Argument die gewünschte Sprache ("de" oder "en") übergeben.
Wenn $_GET['lang'] leer ist rufen wir die Funktionauf und übergeben ihr als Wert unsere Standard-Sprache. Das ist hier im Beispiel "de".


Soweit, so gut! Nun müssen wir nur noch unsere Daten aus dem Array $lang holen, damit wir sie auf dem Bildschirm darstellen können.
<?php
echo $lang['willkommen'];  
?> 


Ich hoffe das dieses kleine Tutorial für euch verständlich und vor allem nützlich ist. Bei Fragen oder Problemen einfach posten!
Änderung(en):
Ich hab mir erlaubt die Codes in Codeblocks zu packen.
@masterG
23.06.2007

Content-Key: 16094

Url: https://administrator.de/contentid/16094

Printed on: April 19, 2024 at 19:04 o'clock

Mitglied: 36213
36213 Oct 03, 2006 at 20:54:37 (UTC)
Goto Top
Hi, du schreibst (unter anderem):

>    if(!empty($_GET['lang'])):  
>       $lang = LoadLang($_GET['lang']);  
>    else:
>       $lang = LoadLang("de");  
>    endif;
> 

wieso nicht einfacher und sicherer:
#oben im code (oder in einer config.inc, die entsprechend früher eingebunden wird)

$lang ='de';  

# ...viel Code...
$allowedLanguages = array('de','en','es');  
if($_GET['lang']){  
    if(in_array($_GET['lang'], $allowedLanguages){  
        $lang = $_GET['lang'];  
    }
}
# und erst hier wird $lang ausgewertet.

Fragend,

Netzbaer
Member: francesco
francesco Oct 05, 2006 at 18:10:44 (UTC)
Goto Top
Warum nicht so, default-Sprache ist immer deutsch und geht auch ohne Mysql.
 //Start der Session
 session_start();

 // Gültige Sprachen definieren
 $gueltige_sprachen = array ( 'de', 'en' );  

 if(isset($_GET['lang']) && in_array($_GET['lang'], $gueltige_sprachen) ) {  
    $_SESSION['language'] = $_GET['lang'];  
 } else {
    if (!isset($_SESSION['language'])) {  
        //default ist immer deutsch
        $_SESSION['language'] = "de";  
    }
 }
 //aus dem imcludeverzeichniss die sprachdatei auslesen
 @include("includes/" . $_SESSION['language'] . "/language.php");  

mfg
Francesco
Änderung:
Ich hab mir hier erlaubt den Code in einen Codeblock zu packen.
masterG(Moderator)
23.06.2007
Member: chris23
chris23 Dec 08, 2007 at 10:45:58 (UTC)
Goto Top
Hallo zusammen,
ich habe das Script von ChiefRebelAngel getestet. Es funktioniert, wenn man in der Zeile mysql_select_db("my_db); noch die Anführungszeichen schließt nach dem Namen der Datenbank.

Hat jemand eine Idee, wie ich auf dieselbe Weise Bilder aus der Datenbank importieren kann? Die Navigationspunkte bestehen aus Icons, kein HTML-Text.

Vielen Dank und viele Grüße
Chris
Mitglied: 36213
36213 Dec 08, 2007 at 11:18:32 (UTC)
Goto Top
Hat jemand eine Idee, wie ich auf dieselbe Weise Bilder
aus der Datenbank importieren kann? Die Navigationspunkte
bestehen aus Icons, kein HTML-Text.

Indem Du die Pfade zu den Bildern in die DaBa schreibst?

$bildpfad= './img/';  

DaBa:
id,name, alt, pfad
1 ,"schoenesBild.jpg", "meine Katze", "privat/kater/"

<img src="<?php echo getBild(1, $bildpfad);?>" />  

<?php
function getBild($bildid,$bpfad)){
    dbCon();
    sql = "select name, alt, pfad from table where id =".$bildid;  
    $res = mysql_query($sql);
    $erg = mysql_fetch_array($res);
    $size = getimagesize($bpfad.$erg['pfad'].$erg['name'];  
    $retVal = $bpfad.$erg['pfad'].$erg['name'].' alt="'.$erg['alt'] . $size[3];  
    return $retVal;
}

HTH
Member: rompers
rompers Mar 08, 2008 at 17:36:27 (UTC)
Goto Top
habe es bei mir auch eingebaut leider geht es nicht wenn ich es in einer while schleife
habe dann habe ich zb.: $name in der sprache mit drin dann setzt er immer den ersten
namen der als erstes ausgelesen wird

wo habe ich da den fehler?
Mitglied: 36213
36213 Mar 08, 2008 at 18:21:13 (UTC)
Goto Top
habe es bei mir auch eingebaut leider geht es
nicht wenn ich es in einer while schleife
habe dann habe ich zb.: $name in der sprache
mit drin dann setzt er immer den ersten
namen der als erstes ausgelesen wird

wo habe ich da den fehler?

Du fragst die Sprache nicht mit ab. Da Du mit dem Code hinterm Berg hälst ist das die einzig mögliche Antwort.

Tipp: Speichere die Sprache in einer Session und hänge hinter jede Abfrage "and lang = $_SESSION['lang']
Member: rompers
rompers Mar 08, 2008 at 18:34:23 (UTC)
Goto Top
in meiner while gebe ich ihm ja auch $name mit an
habe jetzt mit
eval("\$lang[gbook_mail]=\"$lang[gbook_mail]\";");  
einen namen angezeigt bekommen allerdings auch nur einen
und der ist dann auch bei denn anderen mit drin
		while($daten = mysql_fetch_array($sqlanfrage)) {
			$page_entry_start = $page_entry_start-1;
			$datum = $daten['date'];  
			$name = $daten['name'];  
			$lang[gbook_mail] = preg_replace('/\{(.*?)}/', $name, $lang[gbook_mail]);  
			$email = stripslashes($daten['email']);  
			$homepage = stripslashes($daten['homepage']);  
			$zeit = datetime($datum, $sprache, 0);
			$nachricht = stripslashes(bbcode($daten['message']));  
			eval("\$gaestebuch_bit.= \"".$tpl->get("gaestebuch_bit")."\";");  
		}
und da steht ja auch $name
Member: HeikoD
HeikoD Apr 23, 2008 at 18:14:18 (UTC)
Goto Top
Hallo,

ich setze für die Mehrsprachigkeit XML und simplexml ein. Ich habe eine Zugriffsklasse (als Singleton) geschrieben die je nach Anforderung den Text in der jeweiligen Sprache zurückgibt. Wenn die Sprachdatei nicht existiert wird der Text zurückgegeben der Im Quellcode als default definiert wird.

Beispiel:
/*irgendwo im Start*/
$_SESSION["language"]='de';

/* Aufruf im PHP File*/

/* Laden der Klasse*/
$Language = Language::getLanguage($_SESSION["language"]);
/* Hier der Text der angezeigt werden soll*/
$Output= "<p>".$Language->get('txt_hello_world','hello world')."</p>";
/* wenn die Sprachdatei existiert und der xml knoten ->txt_hello_world'<- existiert dann wird der Wert des Knotens ausgegeben*/

<p>Hallo Welt</p>
/* ansonsten*/
<p>hello world</p>
/*wenn kein default text dann*/
<p>*no default value</p>

Die XML Datei hat ungefähr den Aufbau (language_de.xml):
<root>
<page id="login">
<txt_hello_world>Hallo Welt</txt_hello_world>
</page>
</root>

Die Klasse ist etwas mehr Text.
Aber vom Prinzip geht es so.

/*CODE*/
class Language
{
private static $instance=null;
private $_Language="de";
private $path_to_languages="";
private function __construct($Language ="de")
{
$_Language = $Language;
$this->loadXml($this->path_to_languages."languagefile_".$Language.".xml";


public static function getLanguage($language="de")
{
if(self::$instance==null)
{
self::$instance = new self();
}
return self::$instance;
}

private function loadXml($File="")
{
If File exists
read XML into simple xml

}
public function get($NodeName="",$DefaultText="")
{
check if node exist
return escaped node vale
if not exist return DefaultValue if not empty

otherwise return "* no default value";
}
}


Vorteil: XML ist besser zu lesen, kann jederzeit im Lauf geändert werden (Rechtschreibfehler face-smile ), Viele beliebige Sprachen können eingebunden werden.

Wer Interresse Hat kann sich ja bei mir melden.

Achso: wenn man nicht alles immer laden will kann man auch kleine Rubrikdateien mache wie zb: module_xy_de.xml
und so weiter.

Mfg Heiko.
Mitglied: 70648
70648 Oct 11, 2008 at 12:30:21 (UTC)
Goto Top
//aus dem imcludeverzeichniss die sprachdatei auslesen
@include("includes/" . $_SESSION['language'] .
"/language.php");


Ist das so zu verstehen, dass in Sprachdatei (language.php) nur die Wörter in der relevanten Sprache in Variabelen oder Konstanten schreibt, die dann verwendet werden? Ginge das auch als INI-Datei? Oder sind das ganze Sites, die mehrfach(sprachig) gecodet sind?

Viele Grüße steffen700
Member: MKzero
MKzero May 20, 2009 at 10:14:14 (UTC)
Goto Top
Zitat von @HeikoD:
Hallo,

ich setze für die Mehrsprachigkeit XML und simplexml ein. Ich
habe eine Zugriffsklasse (als Singleton) geschrieben die je nach
Anforderung den Text in der jeweiligen Sprache zurückgibt. Wenn
die Sprachdatei nicht existiert wird der Text zurückgegeben der
Im Quellcode als default definiert wird.

Alles ganz nette ansätze, aber ich würde das eher über eine einfache Datei machen. Also entweder CSV-ähnlich(da ist die Lesbarkeit für die meisten sogar noch höher als in der XML ;) ) oder z.B. als DBM, die sind beide performanter als die normale DB(zumindest für so einen Zweck) und für DBM muss man sich nur in die entsprechende Doku schnell einlesen