Archive for the ‘Webdesign’ Category

Einfache Mehrsprachigkeit in PHP

Sonntag, August 15th, 2010

Soll eine Webanwendung erfolgreich sein muss sie Heute vor allem Global Funktionieren sprich jeder auf der Welt soll sie Verstehen. Hierfür gibt es natürlich wie immer viele Wege.

Am einfachsten ist es alle Sprachvariablen in ein Array zu schreiben auf das man dann zugreift z.B gibt man dann einfach echo $lang['download_success'] aus um den Benutzer in seiner Sprach mitzuteilen das ein Download erfolgreich war usw. Jeder der so schon mal gearbeitet hat wird schnell feststellen das dieses System ein entschiedenen Nachteil hat. Will man dem Benutzer jetzt beispielsweise begrüßen mit Meldungen wie “Hallo Name, schön das du wieder da bist” taucht ein erstes Problem auf wie bekomme ich den Namen in den String die wohl einfachste aber zugleich umständlichste Methode wäre es die Sprachvariable in zwei Teile zu zerlegen. Sprich

$lang[welcome_1] = „Hallo“;

$lang[welcome_2]= „, schön das du wieder da bist“;

Echo $lang[welcome_1] . $sUsername . $lang[welcome_2];

Das ist eine Lösung die bei größeren Projekten total versagt da sie meiner Meinung nach vieeel zu umständlich ist. Viel Sinnvoller ist es doch in die Sprachstrings Variablen reinzuschreiben und diese dann zu ersetzen. Das sähe dann z.B. so aus:

$lang[welcome] = „Hallo %name%, schön das du wieder da bist“;

Echo str_replace(‚%name‘ , $sUsername , $lang[‚welcome‘];

Vom Grundsatz her ist das schon mal ganz gut aber immer noch nicht sehr produktiv.

Ich habe das Problem letztlich so gelöst:

Die Sprachvariablen stehen in einer INI-Datei nach dem Schema

Name_der_Variable=“Hallo ich bin der Sprach String %s <- das ist eine Variable in der Sprachvariable“

Der Konstruktor der Klasse lädt die Sprachvariablen in ein assoziatives Array. Um auf eine Variable zuzugreifen habe ich die Methode lang($name , $values… ) definiert. $name ist der Name der Sprachvariable $values… sind die Werte mit denen die Variablen in den Sprachstrings ersetzt werden sollen (vgl. printf ).

Teil 2 folgt noch.

PHP-Array mit allen Virtual Key Codes

Montag, März 15th, 2010

Nach 20min nervigen tippen hab ich es dann mal hingekommen alle Virtual Key Codes in ein PHP-Array zu Tippen und weil ich weiß wie nervig derartige Arbeit ist stelle ich das Ergebnis hier mal jeden zur Verfügung.

$vk_keys = array(
"0xC1" => "Abnt C1",
"0xC2" => "Abnt C2",
"0x6B" => "Numpad +",
"0xF6" => "Attn",
"0x08" => "Backspace",
"0x03" => "Break",
"0x0C" => "Clear",
"0xF7" => "Cr Sel",
"0x6E" => "Numpad .",
"0x6F" => "Numpad /",
"0xF9" => "Er Eof",
"0x1B" => "Esc",
"0x2B" => "Execute",
"0xF8" => "Ex Sel",
"0xE6" => "IcoClr",
"0xE3" => "IcoHlp",
"0x30" => "0",
"0x31" => "1",
"0x32" => "2",
"0x33" => "3",
"0x34" => "4",
"0x35" => "5",
"0x36" => "6",
"0x37" => "7",
"0x38" => "8",
"0x39" => "9",
"0x41" => "A",
"0x42" => "B",
"0x43" => "C",
"0x44" => "D",
"0x45" => "E",
"0x46" => "F",
"0x47" => "G",
"0x48" => "H",
"0x49" => "I",
"0x4A" => "J",
"0x4B" => "K",
"0x4C" => "L",
"0x4D" => "M",
"0x4E" => "N",
"0x4F" => "O",
"0x50" => "P",
"0x51" => "Q",
"0x52" => "R",
"0x53" => "S",
"0x54" => "T",
"0x55" => "U",
"0x56" => "V",
"0x57" => "W",
"0x58" => "X",
"0x59" => "Y",
"0x5A" => "Z",
"0x6A" => "Numpad *",
"0xFC" => "NoName",
"0x60" => "Numpad 0",
"0x61" => "Numpad 1",
"0x62" => "Numpad 2",
"0x63" => "Numpad 3",
"0x64" => "Numpad 4",
"0x65" => "Numpad 5",
"0x66" => "Numpad 6",
"0x67" => "Numpad 7",
"0x68" => "Numpad 8",
"0x69" => "Numpad 9",
"0xBA" => "OEM_1 ( : ; )",
"0xE2" => "OEM_102 (> <)",
"0xBF" => "OEM_2 (? /)",
"0xC0" => "OEM_3 (~ `)",
"0xDB" => "OEM_4 ({ [)",
"0xDC" => "OEM_5 (| \)",
"0xDD" => "OEM_6 (} ])",
"0xDE" => "OEM_7 (\" ')",
"0xDF" => "OEM_8 (§ !)",
"0xF0" => "Oem Attn",
"0xF3" => "Auto",
"0xE1" => "Ax",
"0xF5" => "Back Tab",
"0xFE" => "OemClr",
"0xBC" => "OEM_COMMA (< ,)",
"0xF2" => "Copy",
"0xEF" => "Cu Sel",
"0xF4" => "Enlw",
"0xF1" => "Finish",
"0x95" => "Loya",
"0x93" => "Mashu",
"0x96" => "Roya",
"0x94" => "Touroku",
"0xEA" => "Jump",
"0xBD" => "OEM_MINUS (_ -)",
"0xEB" => "OemPa1",
"0xEC" => "OemPa2",
"0xED" => "OemPa3",
"0xBE" => "OEM_PERIOD (> .)",
"0xBB" => "OEM_PLUS (+ =)",
"0xE9" => "Reset",
"0xEE" => "WsCtrl",
"0xFD" => "Pa1",
"0xE7" => "Packet",
"0xFA" => "Play",
"0xE5" => "Process",
"0x0D" => "Enter",
"0x29" => "Select",
"0x6C" => "Separator",
"0x20" => "Space",
"0x6D" => "Num -",
"0x09" => "Tab",
"0xFB" => "Zoom",
"0xFF" => "no VK mapping",
"0x1E" => "Accept",
"0x5D" => "Context Menu",
"0xA6" => "Browser Back",
"0xAB" => "Browser Favorites",
"0xA7" => "Browser Forward",
"0xAC" => "Browser Home",
"0xA8" => "Browser Refresh",
"0xAA" => "Browser Search",
"0xA9" => "Browser Stop",
"0x14" => "Caps Lock",
"0x1C" => "Convert",
"0x2E" => "Delete",
"0x28" => "Arrow Down",
"0x23" => "End",
"0x70" => "F1",
"0x79" => "F10",
"0x7A" => "F11",
"0x7B" => "F12",
"0x7C" => "F13",
"0x7D" => "F14",
"0x7E" => "F15",
"0x7F" => "F16",
"0x80" => "F17",
"0x81" => "F18",
"0x82" => "F19",
"0x71" => "F2",
"0x83" => "F20",
"0x84" => "F21",
"0x85" => "F22",
"0x86" => "F23",
"0x87" => "F24",
"0x72" => "F3",
"0x73" => "F4",
"0x74" => "F5",
"0x75" => "F6",
"0x76" => "F7",
"0x77" => "F8",
"0x78" => "F9",
"0x18" => "Final",
"0x2F" => "Help",
"0x24" => "Home",
"0xE4" => "Ico00 *",
"0x2D" => "Insert",
"0x17" => "Junja",
"0x15" => "Kana",
"0x19" => "Kanji",
"0xB6" => "App1",
"0xB7" => "App2",
"0xB4" => "Mail",
"0xB5" => "Media",
"0x01" => "Left Button **",
"0xA2" => "Left Ctrl",
"0x25" => "Arrow Left",
"0xA4" => "Left Alt",
"0xA0" => "Left Shift",
"0x5B" => "Left Win",
"0x04" => "Middle Button **",
"0xB0" => "Next Track",
"0xB3" => "Play / Pause",
"0xB1" => "Previous Track",
"0xB2" => "Stop",
"0x1F" => "Mode Change",
"0x22" => "Page Down",
"0x1D" => "Non Convert",
"0x90" => "Num Lock",
"0x92" => "Jisho",
"0x13" => "Pause",
"0x2A" => "Print",
"0x21" => "Page Up",
"0x02" => "Right Button **",
"0xA3" => "Right Ctrl",
"0x27" => "Arrow Right",
"0xA5" => "Right Alt",
"0xA1" => "Right Shift",
"0x5C" => "Right Win",
"0x91" => "Scrol Lock",
"0x5F" => "Sleep",
"0x2C" => "Print Screen",
"0x26" => "Arrow Up",
"0xAE" => "Volume Down",
"0xAD" => "Volume Mute",
"0xAF" => "Volume Up",
"0x05" => "X Button 1 **"
);

PHP Script-System 1.0

Sonntag, August 30th, 2009

Aufgrund von Langeweile habe ich in den letzten 45 Minuten an einem PHP-Script gearbeitet. Der Name ist: PHP Script-System. Was macht es? Es vereinfacht das erstellen von kleinen Scripts (z.B. zum Berechnen von physikalischen Werten etc.), indem es einem die Arbeit abnimmt, Formulare zu erstellen. So muss man sich nur noch um die Berechnungen kümmern und nicht mehr um das Formular, das auslesen der Formulareingaben, das wieder Ausgeben der Formulareingaben und um den HTML Code allgemein.

Das Script benutzt die Smarty Template Engine, so dass man das Design leicht anpassen kann. Standardmäßig ist nur ein schlichtes Schwarz auf weiß – Design vorhanden. Außerdem sind drei Beispielscripts vorhanden.

Zum herunterladen HIER klicken. Anleitung ist in der _read.txt zu finden.

Hier ein Beispielscript – example2.phpsys.php:

<?php
 	// Example 2. Calculate C = Q / U (Capacity = charge / voltage) (i dont know if charge is the right english word for "elektrische Ladung" xD
    $script = new ScriptParser();
	$script->init('POST');
	$script->setNote('You have to define 2 of the variables. The one you want to calculate has to be 0 or left out');
	$script->initVar('C', 'Capacity', '', 'C/V or F');
	$script->initVar('Q', 'Charge', 50, 'C');
	$script->initVar('U', 'Voltage', 25, 'V');

	if($script->vars['C'] &amp;&amp; $script->vars['Q'] &amp;&amp; $script->vars['U'])
		$script->addOutput('You have to define exactly 2 variables, not more, not less.');
	else
	{
		if(!$script->vars['C'])
		{
			if(!$script->vars['Q'] || !$script->vars['U'])
				$script->addOutput('You have to define exactly 2 variables, not more, not less.');
			else
			{
				$script->addOutput('Capacity - C = '. $script->vars['Q']/$script->vars['U'] .' Farad');
				$script->addNLandOutput(' [  C=Q/U  ] ');
			}
		}

		if(!$script->vars['Q'])
		{
			if(!$script->vars['C'] || !$script->vars['U'])
				$script->addOutput('You have to define exactly 2 variables, not more, not less.');
			else
			{
				$script->addOutput('Charge Q = '. $script->vars['C']*$script->vars['U'] .' Q');
				$script->addNLandOutput(' [  Q=C*U  ] ');
			}
		}
		if(!$script->vars['U'])
		{
			if(!$script->vars['C'] || !$script->vars['Q'])
				$script->addOutput('You have to define exactly 2 variables, not more, not less.');
			else
			{
				$script->addOutput('Charge U = '. $script->vars['Q']/$script->vars['C'] .' V');
				$script->addNLandOutput(' [  U=Q/C  ] ');
			}
		}
	}

	$script->Run();
?>

wbb2 externer Login

Mittwoch, August 5th, 2009

Vor kurzen war ich mit dem Problem konfrontiert einen Externen Login für das wbb2 zu bauen ,also eine Loginbox auf der Hauptseite.Man sollte nach dem Login natürlich nicht im Forum landen sonder wieder auf der Seite auf der man sich ursprünglich eingeloggt hatte. Diese Tatsache machte meinen ersten Lösungsansatz, einfach die entsprechenden POST-Daten dann die login.php des Forums zu senden, hinfällig. Also sah ich mir mit Tampa Data die gesendeten Cookies an. Und siehe da drei Cookies wbb2_userid,wbb2_userpassword,wbb2_lastvist. Also hier die erste Funktion zu Login.

function LoginUser($username, $password)
{
		global $db;
	  //db ist ein mysqli-Objekt siehe hierfür http://de3.php.net/manual/de/book.mysqli.php
		$sql = "SELECT userid FROM bb1_users WHERE username = '".mysql_escape_string($username)."' AND password = '" . md5($password) . "'";
    if ($result=$db->query($sql))
		{
		  $row = $result->fetch_assoc();
		  //gibt es das Feld userid im Array sind die Login-Daten gültig
			if($row['userid'])
			{
					setcookie("wbb2_userid", $row['userid'], time()+3600*24*356, "/", ".example.com");
					setcookie("wbb2_userpassword", md5($password), time()+3600*24*356, "/", ".example.com");
					setcookie("wbb2_lastvist", //name des Cookies
                     time(), // Wert in diesen fall der aktuelle Timestamp
                     time()+3600*24*356, //Ablaufdatum des Cookies
                     "/", // mit / wird der Cookies für alle Unterverzeichnise der Domain verfügbar gemacht
                     ".example.com" // .domain.tld machen wir den Cookies für alle Subdomains verfügbar für den fall dass das Forum sich auf einer Subdomain befindet.);
					//true zurückgeben
					return true;
			}
	}
	//Im falle eines Datenbankfehlers oder üngültigen Login-Daten wird false zurückgegeben
	return false;
}

Jetzt wollen wir aber auch wissen ob der User eingeloggt ist. Dafür reicht es aber leider nich einfach zu prüfen ob der Cookie gesetzt ist oder nicht, da bei einer Anmeldung im Forum nur eine Session gesetzt wird. Hier wieder meine Funktion

function IsUserLoggedIn($get_data=false)
{
  global $db;
    //wenn ein Cookie gesetzt ist
		if(isset($_COOKIE['wbb2_userid']))
		{
		  //und der Cookie wbb2_userid eine Zahl ist
			if (is_numeric($_COOKIE['wbb2_userid']))
			{
				$sql = "SELECT userid, username FROM bb1_users WHERE userid = '".mysql_escape_string($_COOKIE['wbb2_userid'])."' AND password = '".mysql_escape_string($_COOKIE['wbb2_userpassword'])."';";
				$result = $db->query($sql);
				$row = $result->fetch_assoc();
        //Dann Checken wir wieder obs den User gibt und ob seine Passwort stimmt
				if($row['userid'])
				{
				  //wenn der Parameter $get_data gesetzt ist geben wir den namen un die id in einen array zurück
					if($get_data)
						return array("userid" => $row['userid'], "username" => $row['username']);
					//ansonsten nur true
					else
						return true;
				}
				//false zurückgeben wenns den user nich gibt
				else
				{
					return false;
				}
			}
		}
		//Wenn jetzt also kein Cookie gesetzt ist checken wir die Session
		else
		{
		  //hier fragen wir einfach ab ob für den Aktuellen besucher (ip) eine Session existiert
			$sql="SELECT userid FROM bb1_sessions WHERE ipaddress = '".$_SERVER['REMOTE_ADDR']."' ORDER BY userid DESC";
			if($result=$db->query($sql))
			{
				$row = $result->fetch_assoc();
				//Da nicht eingeloggte user die userid 0 bekommen muss die id größer 0 sein
				if($row['userid'] > 0)
				{
					$sql = "SELECT userid, username FROM bb1_users WHERE userid = '".mysql_escape_string($row['userid'])."';";
					$result = $db->query($sql);
					$row = $result->fetch_assoc();
					//siehe oben
					if($row['userid'])
					{
						if($get_data)
							return array("userid" => $row['userid'], "username" => $row['username']);
						else
							return true;
					}
				}
			}
		}
		//für alle anderen fälle wird false zurückgegeben
		return false;
	}

Zum Schluss noch der Logout, wie oben reicht es nicht einfach nur die Cookies zu löschen auch die Session muss weg.

	function LogoutUser()
	{
		global $db;
		$user=IsUserLoggedIn(true);
		//unsere funktion von oben
		if(is_array($user))
		{
      //die wbb2 Session-Daten des eingeloggen User löschen
			$db->query("DELETE FROM bb1_sessions WHERE userid = '".mysql_escape_string($user['userid'])."'");
			//und die PHP session löschen
			session_destroy();
		}
		//dann noch die Cookies löschen
		setcookie("wbb2_userid", -1, time()-3600, "/", ".example.com");
		setcookie("wbb2_userpassword", -1, time()-3600, "/", ".example.com");
		setcookie("wbb2_lastvist", -1, time()-3600, "/", ".example.com");
	}

So ich hoffe mal dass das Ganze einigermaßen verständlich war und ich jemanden damit Helfen konnte ;-) . Fragen, Anregungen und Kritik sind erwünscht.

YouTube stellt Unterstützung für Internet Explorer 6 ein

Dienstag, Juli 14th, 2009

Die Videoplattform YouTube will als eine der ersten großen Internetplattformen in der nächsten Zeit die Unterstützung für Microsofts Internet Explorer 6 einstellen, um die, durch den vom Browser verursachten zusätzlichen Aufwand, Kosten bei der Weiterentwicklung der Webseite zu senken. Besucht man die Seite dann mit dem IE6, werden einem Downloadlinks zu neueren Browsern gezeigt. Da YouTube Google gehört, ist zu vermuten, dass dabei Google Chrome hervorgehoben wird.

Dass ich das sehr gut finde versteht sich denke ich mal von selbst.

(Quelle: heise online)

Was hat Microsoft beim IE 6 eigentlich falsch gemacht?

Montag, Juli 13th, 2009

Mein aktuelles Projekt ist der Relaunch eines großen Online-Portals. Dabei liegt das Hauptaugenmerk auf der Neugestaltung des Designs. Als ich dann das angelieferte Design vollständig umgesetzt hatte hab ich mich natürlich sofort ans Testen mit verschiedenen Browsern gemacht. Und siehe da FF2 & 3,  IE 7,  Safari, Opera und Chrome alles Super. Dann IE6.  Schock! Und die Frage wie MS das eigentlich geschafft hat das der IE6 alles so anders darstellt.

c.a. 700 Zeilen extra Stylsheet für den IE6 später sah es dann gleich aus. Aber die feine Art is das ja wirklich nicht. Bleibt nur zu hoffen das der IE6 bald “ausgerottet” wird…

Update:

So hier mal ein paar Möglichkeiten die IE6 auszuschließen bzw. den User Darauf hinzuweißen einen anderen Browser zu nutzen.

JS mit Jquery :

<script type="text/javascript">
$(document).ready(function(){
if($.browser.msie && $.browser.version.substr(0,1)<7) {
$("body").empty();
$("body").html("<h1>This page won't work with IE6 use Firefox or IE7</h1>") ;
}
});
</script>

HTML mit Conditional Comments:

<!--[if lte IE 6]>
<h2>Use Firefox or Update your Browser!</h2>
<![endif]-->

und zu guter letzt mit PHP :

<?php
$browser = get_browser(null, true);
if($browser['majorver'] <= 6 AND $browser['browser'] == 'IE')
die('Don\'t use IE....');
?>