Multilanguage Class

Nein. Deine Klasse braucht mit deinem Code bei mir doppelt so lange. :) Das bedeutet ich brauch nen schnelleren Rechner...

EDIT: Hmm, irgendwas ist da kaputt: Verarbeitungszeit des Skripts: -0.909 Sekunden

EDIT: Aha! Gefunden! Ich hatte keine en.php, das hat alles verzögert: Jetzt bekomme ich das hier:

Code:
Notice: Undefined variable: lang in D:\web\htdocs\trans\System\Language.php on line 113

Warning: array_merge(): Argument #2 is not an array in D:\web\htdocs\trans\System\Language.php on line 113

Notice: Undefined variable: lang in D:\web\htdocs\trans\System\Language.php on line 113

Warning: array_merge(): Argument #1 is not an array in D:\web\htdocs\trans\System\Language.php on line 113

Warning: array_key_exists() expects parameter 2 to be array, null given in D:\web\htdocs\trans\System\Language.php on line 138
test9999Verarbeitungszeit des Skripts: 0.035 Sekunden
 
Zuletzt bearbeitet:
Hmm diese Fehler kann ich bei mir leider nicht nachvollziehen....

Hatte das mit der -0.0.. vorhin auch einmal nach der änderung kam es bei mir nicht mehr vor.
PHP:
$start = microtime(true);
echo "Verarbeitungszeit des Skripts: ".sprintf('%.3f', (microtime(true) - $start))." Sekunden";

Edit: Habe den Code mal bei Strato hochgeladen und dort werden auch keine Fehler angezeigt.
Verarbeitungszeit des Skripts: von 0.032 bis 0.045 Sekunden bei Strato...
Bei einer Array Größe von 10004 Einträgen.
 
Zuletzt bearbeitet:
Ja, war mein Fehler, die en.php hatte keinen Inhalt. Evtl. sollte sowas auch behandelt werden, um es wenigstens in Log zu schreiben. IMHO.

EDIT: Natürlich könntest du auch den Code der Klasse anpassen, statt funktionale sachen in den Language-Dateien zu haben:

PHP:
	private function loadLanguage()
	{
		foreach($this->_language_path as $path)
		{
			###
			$file = $path . $this->getLanguage() . '.php';

			if(!file_exists($file))
			{
				$file = str_replace($this->getLanguage(), "en", $file);
			}

			include($file);

                        if(empty($lang) || !is_array($lang))
                        {
                        	$lang = array();
                        }

			$this->_lang = array_merge($this->_lang, $lang);
		}
	}
 
Habe den Fehler nachgestellt und bin auf noch ein paar andere Fehler gestoßen die ich jetzt erstmal genau analysieren muss...

Edit:
So sollte es keinen Fehler mehr anzeigen.... Wenn die Datei im Verzeichnis fehlt.
Desweiteren ist das Problem mit den Datei-Extensions gelöst.
Wird aber nochmal von mir überarbeitet weil mir das noch nicht so gefällt...

PHP:
	private $_exts = array('.php' => '','.txt' => '','.xml' => '');

	private function loadLanguage()
	{
		$lang = array();
		
		foreach($this->_path as $path)
		{
			foreach($this->_exts as $ext => $val)
			{
				$file = ROOT . DS . $path . DS . $this->getLanguage().$ext;
				
				if(file_exists($file))
				{
					include($file);
				}
				else
				{
					// Error
				}
			}
			
			$this->_lang = array_merge($this->_lang, $lang);
		}
	}
Jetzt ist mir aber aufgefallen selbst wenn ich jetzt eine Sprache als .txt speichere
das sie das folgende Format besitzen muss:

it.txt
PHP:
<?php

$lang = array_merge($lang, array(
	'DE'	=> "Tedesco",
	'EN'	=> "Inglese",
	'FR'	=> "Francese",
	'IT'	=> "Italiano",
));

?>
 
Zuletzt bearbeitet:
Eigentlich meinte ich damit, das du prüfst, ob der Dateiname der zu includierenden Datei auf .php endet. ;-) kann man mit einem regex oder auch substr (einfacher) prima lösen.
 
Habe mir gestern und heute nochmal gedanken gemacht über setPath, getLanguage und loadLanguage....

Ich kann natürlich auch glob($path, '.php') nehmen ^^

habe inzwischen setPath geändert das es jetzt so aussieht:
PHP:
	public function setPath($path)
	{
		// remove absolute path with '' and holds relative path
		$path = str_replace(ROOT.DS, '', $path);

		// replace / and \ with DIRECTORY_SEPARATOR for OS compatibility
		$path = preg_replace('/\//', DS, $path);
		
		// remove DIRECTORY_SEPARATOR from the end of this path string
		if (substr($path, -1) == DS)
		{
			$path = substr($path, 0, -1);
		}
		
		// checks is this path exists
		if(is_dir($path))
		{
			// checks is this path not in patharray
			if(!array_key_exists($path, $this->_path))
			{
				// add the path to array
				array_push($this->_path, $path);
			}
		}
	}
Damit formatiere ich den Pfad so das ich ihn ohne bedenke weiter verwenden kann.
So wird aus jedem absoluten/relativer Pfad ein relativer Pfad
also:
PHP:
array(3) {
  [0]=>
  string(13) "lang\bla_bla\"
  [1]=>
  string(17) "X:\Pfad\www\lang/"
  [2]=>
  string() "/usr/www/lang"
}
wird zu:
PHP:
array(3) {
  [0]=>
  string(12) "lang\bla_bla"
  [1]=>
  string(4) "lang"
  [2]=>
  string(4) "lang"
}
Doch gibt es nicht eine elegantere Lösung dafür....

Die anderen beiden Funktionen kommen nachher muss leider noch mal weg ...
 
Für Informationen über die Datei, zB auch die Endung, bietet sich folgende Funktion an: http://php.net/manual/de/function.pathinfo.php

Das Austauschen des Back- bzw Foreslashes ist sinnlos, immer den Foreslash ("/") verwenden: Auch Windows kommt damit klar ;)

Deine Umbauten sind auch teilweise gefährlich, zB wenn man soetwas wie "../../lang" eingibt. Ich würde da auch garnicht so einen Aufwand betreiben: Der Pfad MUSS relativ übergeben werden, ansonsten: Exception ;)
 
So aber nicht mehr xD
PHP:
public function setPath($path)
	{
		$path = str_replace(ROOT.DS, '', $path);
		$path = preg_replace('/(\.+\/+)*/', '', $path);
		$path = preg_replace('/\//', DS, $path);
		
		if (substr($path, -1) == DS)
		{
			$path = substr($path, 0, -1);
		}
		
		if(is_dir($path))
		{
			if(!array_key_exists($path, $this->_path))
			{
				array_push($this->_path, $path);
			}
		}
		else
		{
			throw new Exception("Directory");
		}
	}
 
Language.php (Ausschnitt)
PHP:
/**
 * Short Description....
 *
 * Long Description.....
 * .......
 * 
 * @access	public
 * @param	string	$path
 * @throws	Exception
 * @return	void
 */
public function setPath($path)
{
	$path = preg_replace(
		array(
			'!([\\\/]+?)!', 
			'!([\\\/]+?)(\.+)!'
		), 
		array(
			DS, 
			''
		), 
		str_replace(
			ROOT, 
			'', 
			rtrim(
				$path, 
				'/\\'
			)
		)
	);
	
	if(is_dir(ROOT.DS.$path))
	{
		if(!array_key_exists($path, $this->_LangPath))
		{
			array_push($this->_LangPath, $path);
		}
	}
	else
	{
		throw new Exception( $path . "does not exists!" );
	}
}
PHP:
/**
 * Short Description....
 *
 * Long Description.....
 * .......
 * 
 * @access	private
 * @throws	Exception
 * @return	void
 */
private function loadLanguage()
{
	$lang = array();
	
	foreach($this->_LangPath as $path)
	{
		$file = ROOT . DS . $path . DS . $this->getLanguage() . '.php';

		if( !file_exists( $file ) )
		{
			throw new Exception( "Could not found: " . $file );
		}

		include($file);

		$this->_LangTags = array_merge( $this->_LangTags, $lang );
	}
}
PHP:
/**
 * Short Description....
 *
 * Long Description.....
 * .......
 * 
 * @access	public
 * @return	string
 */
public function getLanguage()
{
	return in_array( $this->_Language, $this->_LangList ) ? $this->_Language : 'en';
}
 
So nach langer Zeit mal der bisherige Fertige Code...
Findet ihr noch Dinge die man ändern sollte bzw. verbessern könnte?

Language.php
PHP:
<?php

/**
 * @class	
 * @brief	
 */
class Language
{
	/**
	 * Holds all available paths to language files.
	 * 
	 * @access	private
	 * 
	 */
	private $_LangPath = array('lang');
	
	
	/**
	 * A list of available languages.
	 *
	 * @access	private
	 * 
	 */
	private $_LangList = array();
	
	
	/**
	 * Holds all language tags from current language.
	 * 
	 * @access	private
	 * 
	 */
	private $_LangTags = array();
	
	
	/**
	 * Holds the current language.
	 *
	 * @access	private
	 * 
	 */
	private $_Language = '';
	
	/**
	 * 
	 * 
	 * @access	public
	 * @return	void
	 */
	public function __construct()
	{
		if(file_exists(CACHE.'lang.data'))
		{
			$this->_LangList = unserialize(file_get_contents(CACHE.'lang.data'));
		}
		else
		{
			$this->getFiles();
			file_put_contents(CACHE.'lang.data', serialize($this->_LangList));
		}
		
		$this->detectedBrowserLanguage();
	}
		
	
	/**
	 * 
	 * 
	 * @access	public
	 * @param	string	$path
	 * @return	void
	 */
	public function setPath($path)
	{
		$path = preg_replace(array('!([\\\/]+?)!', '!([\\\/]+?)(\.+)!'), array(DS, ''), str_replace(ROOT, '', rtrim($path, '/\\')));
		
		if(is_dir(ROOT.DS.$path))
		{
			if(!array_key_exists($path, $this->_LangPath))
			{
				array_push($this->_LangPath, $path);
			}
		}
		else
		{
			throw new Exception("Can not open $path!");
		}
	}
	
	
	/**
	 * 
	 * 
	 * @access	private
	 * @return	void
	 */
	private function getFiles()
	{
		foreach($this->_LangPath as $path)
		{
			$path = ROOT.DS.$path.DS;
			
			foreach(glob($path.'*.php') as $file)
			{
				array_push($this->_LangList, str_replace(array($path, '.php'), array('',''), $file));
			}
		}
		$this->_LangList = array_unique($this->_LangList);
	}
	
	
	/**
	 * 
	 * 
	 * @access	private
	 * @return	void
	 */
	private function detectedBrowserLanguage()
	{
		$lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
		$this->setLanguage($lang);
	}
	
	
	/**
	 * 
	 * 
	 * @access	public
	 * @return	void
	 */
	public function setLanguage($lang)
	{
		$this->_Language = (in_array($lang, $this->_LangList)) ? $lang : 'en';
		$this->loadLanguage();
	}
	
	
	/**
	 * 
	 * 
	 * @access	public
	 * @return	string
	 */
	public function getLanguage()
	{
		return in_array($this->_Language, $this->_LangList) ? $this->_Language : 'en';
	}
	
	
	/**
	 * 
	 * 
	 * @access	private
	 * @return	void
	 */
	private function loadLanguage()
	{
		$lang = array();
		
		foreach($this->_LangPath as $path)
		{
			$file = ROOT.DS.$path.DS.$this->getLanguage().'.php';
			
			if(!file_exists($file))
			{
				throw new Exception("File was not found by searching path: $file!");
			}
			
			include($file);
			
			$this->_LangTags = array_merge($this->_LangTags, $lang);
		}
	}
	
	
	/**
	 * 
	 * 
	 * @access	public
	 * @return	array
	 */
	public function getLanguageList()
	{
		return $this->_LangList;
	}
	
	
	/**
	 * 
	 * 
	 * @access	public
	 * @param	string
	 * @return	string
	 */
	public function get($key)
	{
		$key = strtoupper($key);
		return array_key_exists($key, $this->_LangTags) ? $this->_LangTags[$key] : '';
	}
	
	
	/**
	 * 
	 * 
	 * @access	public
	 * @param	
	 * @return	void
	 */
	public function set()
	{
		$args = func_get_args();
		
		if(is_array($args[0]))
		{
			foreach($args[0] as $key => $value)
			{
				$key = strtoupper($key);
				
				if(!array_key_exists($key, $this->_LangTags))
				{
					$this->_LangTags[$key] = $value;
				}
			}
		}
		else
		{
			$this->_LangTags[strtoupper($args[0])] = (isset($args[1])) ? $args[1] : $args[0]." has no value!";
		}
	}
}

?>
 
Zurück