Mehrsprachigkeit auf Webseite

thehasso

Erfahrenes Mitglied
Hallo zusammen,

ich überlege seid einiger Zeit welcher Methode ich bei der Umsetzung der Mehrsprachigkeit auf meiner Website durchführen soll.


Bei Meiner Website handelt es sich um eine wie Studivz oder Facebook jedoch noch nicht so erfolgreich :(.. halt eine seite wo man Menschen kennenlernen kann.

Wählt ein User eine Sprache aus dann wird dieser User immer diese Sprache angezeigt, solange er diese nicht wechselt.

Und zwar sind mir folgende eingefallen:


1.Ich Speicher in der Datenbank die Übersetzungen
2.Ich schreibe in der Phpdatei direkt die übersetzungen wobei jede sprache definiert ist Deutsch = 1 und English = 0 Arabisch = 2
klickt ein user auf English dann wird die 2 in der Datenbank Geupdatet. Das Heisst jedesmal wenn man die Seite betretet wird die Nummer aus der DB gelesen und anhand der Nummer wird der Textteil ausgegeben, der bei der If Abfrage zutrifft.

Beispiel:

Es wurde 1 gewählt:

If ( $Sprache == 1 ) {
echo "Bild Hochladen";
} else if ($Sprache == 0 ){
echo "Upload Picture";
} else {
echo "7ot Sura";
}



-> Die Alternative ist nicht schwer und hat den Vorteil, das man nicht immer mehre select durchführen muss mit verschiedenen Attributen also Spalten, mann muss nur den Wert auslesen welche Sprache gelesen wird.

Nachteil: Wenn man änderungen vornimmt mussman im Code nach der Stelle Suchen und diese manuell entfernen, müsste man aber auch tun wenn man in der db die ändrung vornehmen möchte.


3. Diese Idee hat mir mein professor vorgeschlagen, man speichert in einer Php Datei alle Übersetzungen, und erstellt ein Assoziatives Array. Dieses Array könnte man dann immer für beliebige Sprachen vergrößern und anpassen.

Wie das geht 100% weißß ich nicht.


Meine frage,welche Variante würdet ihr auswählen? Also es würden max. 4 Sprachen werden Deswegen Frage an euch Welche findet ihr für die sinnvollste ?


Vielen Dank im Voraus

LG thehasso
 
Also die 2. Variante würde ich schon mal ausschließen, da erstens das mit der If-Anweisung nicht sehr Professionell aussieht, Vergleichbar viel Ressourcen friesst und bei vielen Text auf einer Seite im Quellcode sehr unübersichtlich macht.

Die 1. Variante würde ich bei Seiten einsetzen, die Dynamisch sein sollen und vielleicht vom Nutzer geändert werden sollen.

Die 3. Seite würde ich bei Primär statischen Seiten anwenden, wo sich der Inhalt selten bis nie ändert.

Als Code Bsp. für Variante 3.

PHP:
// Spracharray füllen
$lang=array("1" => array( "welcome" => "Willkommen auf meiner Seite",
                                                           "upload" => "Bild Hochladen"),
                       "0" => array("welcome" => "Welcome to my site",
                                                           "upload" => "Upload Picture"),
                       "2" => array("upload" =>"7ot Sura")
                     );

// Ausgabe der Texte 
 echo $lang[$countrycode]["upload"];
Dabei müsste vorher $countrycode, je nachdem die Sprache ist, gesetzt werden.
 
Oder du nimmst den Java-Ansatz und machst Sprach-Dateien (properties) die du dann ansprichst.
Nun, mindestens für die ganzen statischen Texte (Menüführung, Tastenbeschriftungen etc)

Dazu macht man sich ein kleiner Property-reader (oder kopiert den meinen).

So kann man dann das anwenden:

de.properties
Code:
##
# DE-Übersetzungen für die Applikation XY
##
cancel  = abbrechen
password = Passwort
notLogedIn = Du bist nicht eingelogt

en.properties
Code:
##
# EN-Übersetzungen für die Applikation XY
##
cancel  = cancel
password = password
notLogedIn = you are not loged in

test.php
PHP:
<?php
    include_once("PropertyReader.php");
    $lan = 'de';
    $trans = new PropertyReader("{$lan}.properties");
    echo "<p><b>deutsch</b></br>";
    echo $trans->cancel;
    echo "<br />{$trans->notLogedIn}</p>";

    $lan = 'en';
    $trans->openPropertyFile("{$lan}.properties");
    echo "<p><b>english</b></br>";
    echo $trans->cancel;
    echo "<br />{$trans->notLogedIn}</p>";
?>

Natürlich ist es noch schöner, wenn man eine Ableitung des PropertyReaders erstellt, bei dem man nicht mehr den Filenamen und Pfad mitgeben muss, sondern nur noch die Sprache.

Ebenfalls sollte man, wenn man mehrere Module programmiert hat, pro Modul eigene properties-Dateien erstellen. Macht das ganze flexibler

Und hier noch der PropertyReader. Einfach beide Dateien so übernehmen.
IPropertyClass
PHP:
<?php
/**
* mpl           by ERB software
* @author       stefan.erb(at)erb-software.com
*/
interface IPropertyClass extends ArrayAccess{

	/**
	* @param   String  FilePath
	* @access  public
	*/
    public function openPropertyFile($propertyFileName);

    /**
    * @param    String
    * @return   Variant
    * @access   public
    */
    public function __get($name);

    /**
    * @param    String
    * @param    Variant
    * @access   public
    */
    public function __set($name, $value);
	/**
	* getProperties
	* @return propertyarray
	*/
	public function toArray();
}
?>

PropertyReader.PHP
PHP:
<?php
/**
* mpl	        by ERB software
* @author		stefan.erb(at)erb-software.com
*/
include_once(dirname(__FILE__)."/IPropertyClass.php");
class PropertyReader extends ArrayObject implements IPropertyClass{
    const PATTERN_ARRAY = '|\A\((.+)\)\Z|';
    const DEFAULT_SEPERATOR = '=';

    /**
    * In diesem Array können Standartpfade definiert werden, in denen bei fehlendem
    * Pfad nach der Propertydatei gesucht wird 
    * @var      Array<String>
    * @access   protected
    */
	protected $paths = array('ear/cfg');

    /**
    * @var      String
    * @access   protected
    */
    protected $seperator = self::DEFAULT_SEPERATOR;

	/**
	* construct
	* @param propertyFilePath
	*/
	public function __construct($propertyFileName = NULL, $seperator = self::DEFAULT_SEPERATOR){
        $this->seperator = $seperator ? $seperator : self::DEFAULT_SEPERATOR;
        if($propertyFileName) $this->openPropertyFile($propertyFileName);
	}
	
	/**
	* @param   String  FilePath
	* @access  public
	*/
    public function openPropertyFile($propertyFileName){
        try {
            $this->exchangeArray(array());
            $propertyFilePath = $this->findFile($propertyFileName);
            $this->readPropertiesFromFile($propertyFilePath);
        } catch (Exception $e){
            echo ($e);
        }
    }

	/**
	* @param   String  file name of the property
	* @return  String  file path
	* @access  protected
	*/
	protected function findFile($propertyFilePath){
        if (!file_exists($propertyFilePath) or !is_file($propertyFilePath)) {
            /** search the file in all property file paths */
            foreach ($this->paths as $path){
                if (file_exists("{$path}/{$propertyFilePath}")) {
                    $propertyFilePath = "{$path}/{$propertyFilePath}";
                    break;
                }
            }
            if (!file_exists($propertyFilePath) or !is_file($propertyFilePath)) throw new Exception("File '{$propertyFilePath}' not found");
        }
        return $propertyFilePath;
    }

	/**
	* @param   String  file path
	* @return  Array<key=>value>
	* @access  protected
	*/
    protected function readPropertiesFromFile($propertyFilePath){
        $lines=file($propertyFilePath);
        $array = array();
        foreach($lines as $i => $line){
            /** filter the lines */
            if(strlen(trim($line))!=0 and substr_compare($line, '#', 0, 1)){
        		while(is_numeric($length=eregi('~([0-9]+)~', $line, $found))){
                    $line = str_replace($found[0], chr($found[1]), $line);
                }
                $this->addPropertyFromLine($line);
            }
        }
    }

	/**
	* addPropertyFromLine
	* @param String property line
    */
	protected function addPropertyFromLine($line){
		$property = explode($this->seperator, $line);
        $key = trim($property[0]);
        $value = trim($property[1]);

        if (preg_match(self::PATTERN_ARRAY, $value, $found)) {
            $value = ArrayObj::getInstanceFromString($found[1], ',');
        }
        $this[$key] = $value;
	}

    /**
    * @param    String
    * @return   Variant
    * @access   public
    */
    public function __get($key){
        return $this[$key];
    }

    /**
    * @param    String
    * @param    Variant
    * @access   public
    */
    public function __set($key, $value){
        $this[$key] = $value;
    }
    
	/**
	* getProperties
	* @return propertyarray
	*/
	public function toArray(){
	    return $this->getArrayCopy();
	}
}
?>
 
Hi,

generell ist es auf jeden Fall besser, jede Sprache in eine eigene Datei zu laden. Denn warum sollte man 10 andere Sprachen laden, wenn diese gar nicht benötigt werden?

Ich würde allerdings die Strings nicht in eine Property file auslagern sondern in verschiedene PHP Dateien.

de.php
PHP:
<?php
$strings = array (
  "welcome" => "Willkommen!",
  "goodbye" => "Aufwiedersehen!"
);
?>

en.php
PHP:
<?php
$strings = array (
  "welcome" => "Hey there!",
  "goodbye" => "Please don't go!!"
);
?>

Auf diese Art muss man nicht erst eine komplette Datei parsen, was ja schließlich auch Zeit kostet.

Grüße
Manuel Freiholz
 
Bis jetzt hat noch gar keiner einen mySQL Ansatz vorgeschlagen ...
Wieso nicht? Dann könnte man das auch bequem in ein AdminInterface einbauen ...
 
Ich sehs zwar immernoch net, wo es erwähnt wurde, aber wenn anscheinend doch net so ausführlich :P

Du hast mich glaube ich falsch verstanden; nicht vom User - sondern vom Admin einfacher zu verwalten.
Vorteile meiner Meinung nach wären auf jeden Fall:
- Flexibel
- Leicht erweiterbar / veränderbar ohne immer Dateien anlegen zu müssen + hochladen etc.
- Nur die benötigte Sprache auslesbar

Zudem kann man das ganze ja dann cachen, dass nicht immer alles neu geladen werden muss.
 
Ich sehs zwar immernoch net, wo es erwähnt wurde, aber wenn anscheinend doch net so ausführlich :P
Punkt 1 im ersten Post.
Darauf geht wohl nur niemand ein, weil es unökonomisch ist. ;)

Du hast mich glaube ich falsch verstanden; nicht vom User - sondern vom Admin einfacher zu verwalten.
Vorteile meiner Meinung nach wären auf jeden Fall:
- Flexibel
- Leicht erweiterbar / veränderbar ohne immer Dateien anlegen zu müssen + hochladen etc.
- Nur die benötigte Sprache auslesbar

Zudem kann man das ganze ja dann cachen, dass nicht immer alles neu geladen werden muss.

Das sind alles keine Punkte, die man nicht auch Dateibasiert umsetzen kann. Ob - wenn man im ACP auf "speichern" klickt - eine Datei verändert wird oder auf eine Datenbank zugegriffen wird, merkt keiner und interessiert auch niemanden.

Und das nur die jeweilige Sprache geladen wird, die auch benötigt wird, lässt sich ebenso einfach umsetzen.

Der Punkt ist einfach, dass man nicht "alles" in die Datenbank kippen sollte. Es sollte ein gewisses Gleichgewicht zwischen der Last des Dateisystems und der Datenbank herrschen.
Wenn Inhalte oft geändert werden, können sie natürlich in die Datenbank, keine Frage, nur Standard-Strings wie "Suche", "zurück", "nächste Seite" haben da beim besten Willen nichts verloren. Das bläht die Datenbank nur unheimlich auf.
Hab mal ein System mit 14 Sprachen, da wirst du das früher oder später auch so sehen. ;)
 
Hallo,

danke euch für die Beiträge, das was mir aufgefallen ist was ichnicht beachtet hatte ist Wrum soll man mehrere Sprachen Laden, wenn man diese nicht aufruft.


Ich denke dann werde ich mich für die 3 Alternative entscheiden das heisst mit Assoziativen Arrays das ganze so umzusetzen das Jede Sprache in einer eigenen Datei ist.


Die Frage die Ich mich nun stelle wo ruft man dieses Array dann auf? Beispielsweise hab ich bei mir auf der Website oben Rechts folgendes stehen:


PHP:
<div class="buttonscontaine">
        <div class="button">
       
         <a href="meineseite.php"><? echo $vorname; echo " "; echo $nachname; ?></a>      
        <a href="einfache_suche.php">suche</a> 
        <a href="kontakt.php" >hilfe?</a>
        <a href="<?php echo $logoutAction ?>" target="_parent">abmelden</a> </div>
      </div>


Das ganze ist dann noch in einen div implementiert.

In dem array sind dann z.b die 3 Schlüsselwörter drin welche die jeweilige Übersetzung beeinhaltet. Jedoch wo lass ich das Array laufen.

Bei der Umsetzung tu ich mir bei der Methode noch schwer.
Danke euch.

LG
 
Hi,

du lässt das Array nicht "laufen". Du kannst die Sprach-PHP-Datei am Anfang der Seite einbinden und dann einfach direkt auf die Elemente Zugreifen:

PHP:
<?php
// Sprachdatei einbinden.
include( "pfad/zur/sprachdatei/de.strings.php" );
?>
<div class="buttonscontaine"> 
        <div class="button"> 
        
         <a href="meineseite.php"><? echo $vorname; echo " "; echo $nachname; ?></a>       
        <a href="einfache_suche.php"><?php print($strings["search"]); ?></a>  
        <a href="kontakt.php" ><?php print($strings["help"]); ?></a> 
        <a href="<?php echo $logoutAction ?>" target="_parent"><?php print($strings["logout"]); ?></a> </div> 
      </div>

Jetzt musst du je nach Ausgewählter Sprache nur eine andere Sprachdatei einbinden und schon klappt es.

Grüße
Manuel Freiholz
 
Zurück