Speedport W720V Reconnect Script

Sonntag, 29. Januar 2012 - Keine Kommentare

Folgendes Script weißt euren Router an, die Internetverbindung zu trennen, um sich eine neue IP-Adresse zu besorgen.
Dabei wird auf dem Router eine ominöse Datei namens “disconnect.exe” aufgerufen, welche anscheinend für das Trennen und Wiederaufbauen der Verbindung verantwortlich ist – darum der zweimalige Aufruf.

Windows Batch: (setzt CURL vorraus)

curl http://192.168.2.1/cgi-bin/disconnect.exe
timeout /t 3 /nobreak
curl http://192.168.2.1/cgi-bin/disconnect.exe

JDownloader LiveHeader/CURL: (User und Passwort werden nicht benötigt)

[[[HSRC]]]
    [[[STEP]]]
        [[[REQUEST]]]
        GET /cgi-bin/disconnect.exe HTTP/1.1
        Host: %%%routerip%%%
        [[[/REQUEST]]]
    [[[/STEP]]]
 
    [[[STEP]]]
        [[[WAIT seconds="3"/]]]
    [[[/STEP]]]
 
    [[[STEP]]]
        [[[REQUEST]]]
        GET /cgi-bin/disconnect.exe HTTP/1.1
        Host: %%%routerip%%%
        [[[/REQUEST]]]
    [[[/STEP]]]
[[[/HSRC]]]

Advanced Javascript Tricks

Montag, 12. September 2011 - Keine Kommentare

Recently I’ve watched a few presentations about Javascript on YouTube and learned some tricks I want to share:
1. A Big Closure Around your Code
2. Faster jQuery Selection
3. JavaScript’s odd Boolean Comparison Operators

1. A Big Closure Around your Code

When you’re writing a more complex piece of code, you’re likely to have the need for private variables and prevention of code collision (e.g. with frameworks). The following is a very nice pattern that offers not only both mentioned things, but will also speed up your code a little bit and make sure, that undefined really is what it seems to be, NOT defined:

var undefined = "foo";  // This is perfectly legit in today's JS, and now:
undefined === "foo";    // Which is just completely wrong and potentially dangerous
 
(function(window, document, undefined){
 
    var test;  // Local scope = Not accessible from outside = Private
 
    var getTest = function(){
        return test;  // Accesses the local scope variable
    }
 
    document.getFooByBar();  // This accesses the local scope variables "document" 
    window.doSomething();    // and "window", instead of the ones in global scope,
                             // which makes access a bit faster
 
    test === undefined;  // We access the local scope variable "undefined" 
                         // here, which is in fact undefined, and are thus
                         // preventing bad things from happening
 
})(window, document);

Wrap your code in a closure-function like shown when ever possible. This will also benefit code-minification, since all the local variables (including window and document) can and will be minified.

Many jQuery Plugins use this method to pass in the framework root, too:

(function($){
    $.fn.foo = ...
})($);

2. Faster jQuery Selection

While we’re at it: If you‘re using jQuery in your application/site and you want to select elements that are descendants of an element that has a DOM Id given, you might be using one of theese queries:

$("#element_id foo.bar");
$("#element_id > foo.bar");

And actually, this is not the best way to perform this selection. The following version is more structured (imho) and a bit faster – not a lot, but if you’re running this a thousand times, you’ll notice a good difference:

$("#element_id").find("foo.bar");
$("#element_id").children("foo.bar");

This version selects an element by it’s DOM Id and then searches in it’s descendants/children. Why is this faster? Because jQuery can parse the DOM id-selector directly (using the document.getElementById() function) instead of passing the whole query into Sizzle (which is the CSS-selection engine jQuery uses) and thus being faster, because Sizzle only has to parse the find() part within the selected element.

3. JavaScript’s odd Boolean Comparison Operators

In case you didn’t know: JavaScript won’t evaluate the following statement as you might expect it from other languages:

var test = (false || 4 || "foo");
 
// What we expect:
test === true;
 
// Result:
test === true;  // FALSE
test === 4;     // TRUE

First: This is awesome! Second: Why is that? Since JavaScript is a typeless language, everything that isn’t an empty string, a zero, false, null/NaN or undefined will be equal (==) to true. That’s why there is no need for JS to parse comparison operator statements into booleans, but rather have them return the original value.

This is very nice, because you can do the following to create an easy way to have default values:

var classNames = {
    "test":      "testClass",
    "odd":       "colorOdd",
    "_default_": "normal"
};
 
var foo = "notExistingKeyName";
var className = classNames[foo] || classNames._default_;
                   // undefined || "normal"
 
// Result:
className === classNames._default_ === "normal";

In the case that the classNames object had a key called notExistingKeyName, that value would have been returned. But the script, as is, will fall back and return the value of the object’s _default_ key.

Note how that won’t affect the function of those operators in any way you’re used to:

var foo = false;
var bar = 4;
 
var compare = (foo || bar);  // This will turn into:
compare === bar === 4;       // And thus:
compare == true;
 
// If you need a boolean, use a double negation
var bool = !!(foo || bar);
bool !== 4;
boll === true;

The AND operator will return the last value, if all values are equal to true, or the first value that is equal to false:

var foo = null;
var bar = 4;
var john = "doe";
 
var a = (foo && bar && john);
a === null;
a == false;
 
var b = (bar && foo);
b === foo;
 
// This will also work with undefined:
var undef;
var c = (undef && bar);
var c === undefined;

Zend_Db_Table and the $_primary Array

Dienstag, 19. Juli 2011 - Keine Kommentare

So, we’re currently developping another ZF application at work. Because it’s nice to have such a function, I’ve added a method count() to our base DbTable class.

/**
 * Returns the count of rows matching the given WHERE clause
 * @param array  $where       An SQL WHERE clause.
 * @param string $countColumn (Optional) The column to apply the count to.
 * @return int|bool Returns false if an error occured
 */
public function count($where, $countColumn = "")
{
	// Column not set -> set to primary key
	if(!$countColumn)
	{
		$countColumn = $this->_primary;
	}
 
	// Build the select
	$select = $this->select();
 
	// Set FROM
	$select->from($this->_name, array(
		"count" => "COUNT(`".$countColumn."`)"
	));
 
	// Set WHERE
	$select = $this->_where($select, $where);
 
	// Fetch the row
	$row = $this->fetchRow($select);
 
	// Return count, or if not successful, return false
	return (isset($row["count"])) ? (int)$row["count"] : false;
}

It worked as expected the first time you called it; but after that, the model wouldn’t work anymore.

After investigating in the problem, I found out that somehow (don’t ask me which line of code does this) the from() method of Zend_Db_Table_Select rewrites the $_primary property of the Zend_Db_Table it’s running on from string to array.
This caused an “Error #1054: Unkown column ‘Array’ in ‘field list’”, because $_primary was an array containing a string with it’s previous value – the primary key.

I don’t know why ZF does that, but my workaround seems to work perfectly:

/**
 * Returns the primary key of this table
 */
public function getPrimaryKey()
{
	$pk = $this->_primary;
 
	// Is it a compound primary key?
	if(is_array($pk))
	{
		// Fetch first key
		foreach($pk as $null => $key)
		{
			if(is_string($key))
			{
				$pk = $key;
				break;
			}
		}
	}
 
	return $pk;
}

I know it’s not perfect, but until I know more about it this should do the trick.

HowTo: PHP References (v2)

Mittwoch, 6. Juli 2011 - Ein Kommentar

Nachdem ich ja schonmal etwas über PHPs merkwürdige Referenzen geschrieben habe, wurde mir das Thema die letzten Tage erneut etwas näher gebracht. Da mir der alte Artikel als wenig informativ erschien, möchte ich hier noch einmal ausführen, wie PHP die ganze Geschichte wirklich anstellt ;)

Im PHP-Sourcecode gibt es zwei Abstraktionen des Speichers:
1. z_ref, welche den Zugriff auf eine z_val ermöglichen
2. z_val, welche den Speicherbereich halten und managen

Erstellt man eine Variable in PHP, so wird ihr Wert in eine z_val geschrieben. Die Variable selber ist lediglich eine menschenlesbare Form einer z_ref, also eines Verweises auf die eben gespeicherte z_val.

$foo          // z_ref
     =        // Ist-Gleich weißt einer z_ref eine z_val zu.
       "bar"; // z_val

Erstellt man nun eine Referenz auf die Variable, so wird der z_ref Inhalt, also der Verweis auf eine z_val, kopiert, und in die neue z_ref geschrieben.

$foo = "bar";
 
$foo2          // z_ref
      =&       // Ist-Gleich-Et weißt einer z_ref den Inhalt einer anderen z_ref zu.
         $foo; // z_ref

Damit enthalten $foo und $foo2 immer genau den gleichen Wert, da beide auf die selbe z_val zeigen. Werden Änderungen in $foo2 geschrieben, so sind diese über $foo auslesbar, und natürlich umgekehrt.
PHP-Referenzen sind also lediglich Etiketten für Container (Variablen), und zeigen nicht direkt auf einen Speicherbereich, wie z.B. Pointer in C.

Beachten muss man hierbei, dass der =&-Operator eine z_ref auf der rechten Seite vorraussetzt. Steht dort eine z_val, so führt dies zu einem Fatal Error.

$foo2           // z_ref
      =&        // Versucht die z_ref zu kopieren, scheitert aber, weil eine z_val vorliegt.
         "bar"; // z_val

Möchte man mit einer Funktion eine z_ref statt einer z_val zurückgeben, um z.B. Instanzen (anstatt Kopien) von Objekten zu transportieren, so muss man dem Funktionsnamen ein & vorhängen.

// Gibt eine z_ref auf die z_val hinter der Variable $z_ref zurück
function &getZRef()
{
    $z_ref = "z_val";
    return $z_ref;
}
 
// Referenziert die zurückgegebene z_ref
$z_ref2 =& getZRef();
 
// Wird der normale Ist-Gleich-Operator verwendet, so wird die z_val hinter der
// zurückgegebenen z_ref kopiert und in $z_val2 geschrieben. Damit besteht keine
// Verbindung mehr zwischen $z_ref innerhalb der Funktion und $z_val2.
$z_val2 = getZRef();

Um die Parameter von Funktionen als z_ref und nicht als z_val entgegen zu nehmen, so muss man deren Deklaration ebenfalls ein & vorhängen.

function modifyArray(&$z_ref)
{
    // Modifiziert die z_val hinter der gegebenen z_ref
    $z_ref[0] = "test";
}
 
$array = array();
 
// Übergibt die z_ref an die Funktion
modifyArray($array);
 
// Gibt "test" aus
echo $array[0];

Zum Schluss noch eine Liste mit DOs und DONTs:

  • DO:
    • Objekt-Instanzen über Funktionen transportieren, welche Referenzen zurückgeben:
      function &getObject()…
    • Kurze Referenzen für sonst (textlich) lange Abfragen erstellen:
      $authorVo =& Model_Book::getBook(42)->getAuthorVO();
    • Es ist generell sicher, Referenzen von Objekten (also auch Arrays) zwischen Methoden hin und her zu schieben, welche lediglich ausgelesen werden. Sobald mit diesen aber gearbeitet werden soll, empfiehlt es sich, innerhalb der jeweiligen Methode eine Kopie anzulegen, oder direkt die Referenzen weg zu lassen.
  • DON’T:
    • Getter-Funktionen eine Referenz zurückgeben lassen. Das zerstört den Sinn hinter einem Getter, da über die z_ref die Variable bearbeitet werden kann. Ausnahme hier sind die in der DO-Liste genannten Instanz-Getter, welche Instanzen transportieren.

Hoffentlich hat dieser Artikel mehr “aha”-Momente hervorgebracht, als der alte! :)
Über Kommentare freue ich mich wie immer.

The pain with VirtualBox 4.0…

Montag, 17. Januar 2011 - Keine Kommentare

…oder: “VirtualBox 4 und VRDP (Remote Desktop): Wie?!”

Ich möchte in Zukunft meinen Server virtualisieren, da größere Projekte anstehen, und ich die Sicherheit und Backupfähigkeit von virtuellen Servern nutzen möchte, um im Notfall besser reagieren zu können.
“Kein Problem”, was? Naja, für mich als Virtualisierungsanfänger war der Einstieg nicht wirklich toll – wie alles funktioniert ist mir durchaus klar, nur es zum Funktionieren zu bringen war die andere Seite :)

Nach einigen Benchmarks und Berichten auf verschiedenen Websites habe ich mich schließlich für VirtualBox entschieden. Scheinbar bietet es doch tatsächlich mächtig mehr Geschwindigkeit als Vmware Server oder XEN, wobei ich letzteres nicht nachvollziehen kann – aber okay. Mit VBox habe ich vorher schon gearbeitet, und ich mag es im Prinzip auch sehr.
Mein einzigstes Problem war nun: Wie kann ich etwas auf einer frischen VM auf meinem Server installieren? Natürlich habe ich keine Desktopumgebung auf meinem Server laufen, weswegen ich auf die Headless-Version von VBox angewiesen bin. Doch wie kann ich darüber mit den VMs interagieren? Kurz und knapp: gar nicht – wie auch?

Allerdings ist es mit der Oracle-Version von VBox (nicht die OSE-Version) möglich, über den Microsoft Remote Desktop auf beliebige virtuelle Maschinen zu kommen. “Toll!” dacht ich mir. Naja, nach zwei Tagen hab ich es endlich hinbekommen. Die Lösung:

Seit Version 4.0 ist die VRDP-Funktionalität ausgelagert – auch wenn das Konfigurationsmenü noch immer vorhanden ist, so bewirkt das Einstellen dort nichts mehr. Es muss erst das Extension Pack, das auf der VBox-Download-Seite (link) gefunden werden kann, nachinstalliert werden. Erst dann hört VirtualBox auch wirklich auf RDP-Anfragen und man kann sich mit der Maschine verbinden.

Vielen Dank, Oracle, für eine solch gelungene Aktion! Ich will nicht wissen, wie viele Leute das beschäftigt (hat).

HowTo: PHP References

Samstag, 21. August 2010 - Keine Kommentare

Es gibt eine überarbeitete Version dieses Artikels.


PHP ist wegen seiner teilweise komischen Art keine einfache Sprache was OOP angeht, leider :(
Nach Tagelangem rumforschen, nach tausend verschiedenen Antworten, bin ich glaube ich auf die Antwort gestoßen: Es gibt (leider) mehrere Wege :-|

Aber die gängiste Variante scheint diese zu sein:

class Test
{
    public $testVar = "Ein String";
    public function &get()
    {
        return $this->testVar;
    }
    public function set(&$testVar)
    {
        $this->testVar = $testVar;
    }
}
 
$test = new Test();
 
// Erzeugt Referenz: $testVar -> $test->testVar
$testVar = &$test->get();
 
// Ändert den Inhalt von $test->testVar
$var = "Ein neuer String";
$test->set($var);
// Oder:
$test->testVar = "Ein neuer String";
// Oder:
$testVar = "Ein neuer String";
 
// Erzeugt Referenz: $testVarZwei -> $testVar -> $test->testVar
$testVarZwei = &$testVar;
 
// Ausgabe: "Ein neuer String"
echo $testVarZwei;

Um also eine Referenz zu erzeugen, muss man einer Variable:

  • &foobar() zuweißen, wobei diese Funktion mit function &foobar() deklariert sein muss, oder
  • &$barfoo zuweißen, wobei $barfoo wiederum eine Referenz oder eine gewöhnliche Variable sein kann

Damit eine Funktion nicht eine Kopie, sondern eine Referenz auf eine Variable verwendet, muss man:

  • dem Parameter der Funktion in deren Deklaration & vorhängen, sprich: function foobar(&$param) {…

Hierbei sollte man allerdings darauf achten, dass man dem Parameter nicht direkt einen Wert übergeben darf!

// Geht:
$wert = "String";
foobar($wert);
 
// Geht nicht:
foobar("String");

Hoffe ich konnte jemandem helfen, mir auf jeden Fall ist es jetzt endlich klar geworden wie PHP seine Speicherbereiche handhabt :)

PHP kann schon komisch sein.

A small Globals class for PHP5

Mittwoch, 11. August 2010 - Keine Kommentare

Ohne viel zu Schreiben will ich das einfach mal posten :) Hab ich schon vor ein paar Monaten geschrieben… vielleicht ist es ja jemandem nützlich! (Falls ja, würde mich ein Kommentar freuen :P )
Beispiel ist mit dabei.

<?PHP
 
/**
 * @author Kevin Fischer
 * @copyright http://kevin-fischer.de
 * @version 2010/5/6
 * @description Globals class for PHP5
 * @example
 * <?PHP
 * include("./class.Globals.php");
 * 
 * // Get instance
 * $globals = &Globals::getInstance();
 * 
 * // Put some variables
 * $globals->testVar = "foo";
 * 
 * // Example use inside a function
 * function accessGlobals()
 * {
 *     // Local variable 
 *     $globalsLocal = &Globals::getInstance();
 *     
 *     // Will echo "foo"
 *     echo $globalsLocal->testVar;
 * }
 * ?>
 */
 
class Globals
{
	static private $instance = null;
	private $data = array();
 
	/**
	 * Since this class is a Singleton, this function returns the instance
	 */
	static public function &getInstance()
	{
		if(self::$instance == null)
		{
			self::$instance = new self();
		}
 
		return self::$instance;
	}
 
	/**
	 * This class is neither constructable nor clonable
	 */
	private function __construct()
	{}
	private function __clone()
	{}
 
	/**
	 * Sets a global variable
	 */
	public function __set($name, $value)
	{
		$this->data[$name] = $value;
	}
 
	/**
	 * Returns a global variable
	 */
	public function __get($name)
	{
		if (array_key_exists($name, $this->data))
		    return $this->data[$name];
		else
			return null;
	}
 
}
 
?>

mv /var/www/oldapache /var/www/newnginx

Dienstag, 3. August 2010 - Keine Kommentare

Es ist Serverumzugszeit! Passend zum Sysadmin-Day habe ich einen EQ4-Server bei Hetzner ergattert!

Schon einen Tag nach der Bestellung war das Baby von Seiten Hetzners fertig installiert und für meinen Zugriff bereit… los ging der Spaß!
Nach mittlerweile fünf Tagen alles hin und her ziehen, dies und das, “sell und jenes” einrichten, verschiedene Gamingserver ausprobieren, und so weiter und so fort, ist der Transfer in die Freiheit nun aber fast abgeschlossen. Auch wenn er es niemals lesen wird, und auch nicht könnte, weil er Amerikaner ist: Danke RX, fürs Hosten meiner Sachen über nun fast zwei Jahre! :-o

Auf dem neuen Server wartet die geballte Power eines i7 Prozessors in Verbindung mit 8GB RAM sowie nginx auf mich! Was schnelleres gibts garnich :P
Damit sind meine jetzigen, und auch meine zukünftigen Projekte bestens abgesichert :)

Firefox 4.0: A bad great design.

Donnerstag, 15. Juli 2010 - Keine Kommentare

Als ich vor ca. Zwei Wochen, gleich nach ihrem Erscheinen, mir die Beta 1 von Firefox 4.0 installiert hab, fiel mir sofort eins auf:
Das schöne Design von den Screenshots war grottenhässlich!

Nicht nur war die komplette Titelleiste abgeschnitten, es blieben auch die Window-Buttons nicht verschont, und das Fenster war alles andere als endlich Aero-Transparent: Grau!

Ich hab mich also kurz damit beschäftigt und die gerade genannten Probleme lösen können: Ich musste alle Themes entfernen, sodass Firefox auf das “Default 4.0b1″ Theme zurückfällt, welches laut seiner Anzeige nicht kompatibel zur aktuellen Version und somit nicht auswählbar war :D
Aber: Das Problem war gelöst, ich hatte endlich das neue Design!

Mich störte nun aber der Orangene Menübutton, und der verschwendete Platz in der Titelleiste, wo die Tabs wirklich sehr gut Platz hätten… also: Hand angelegt und die userChrome.css bearbeitet!
Das Resultat:

Ich find das sehr viel besser, und habe im Feedback-Dashboard auch schon sehr oft von dieser Idee gelesen, die hoffentlich von Mozilla zur fertigen Version aufgegriffen wird!

Wer mein Design kopieren möchte:
Dazu muss in die Datei %APPDATA%/Mozilla/Firefox/profiles/<FF Profil>/chrome/userChrome.css folgendes eingefügt werden:

#TabsToolbar {
    padding-left: 85px !important; /* Die Tabs links 82px einrücken, damit der Firefox-Button Platz hat */
    padding-top: 5px !important; /* Die Tabs 5px nach unten einrücken */
    padding-right: 110px !important; /* Die Tabs rechts 110px einrücken, sodass sie den Windowcontrols nicht im weg sind */
    margin-top: -20px !important;
}
 
#star-button {
    display: none !important; /* Kein Favoriten-Icon in der Locationbar anzeigen */
}
 
#appmenu-button {
    padding: 5px !important; /* Firefox-Button etwas mehr Luft geben */
    height: 24px !important; /* Button höher machen */
    width: 78px !important; /* Button größer machen */
    margin-top: 2px !important; /* Button am Aus-Dem-Fenster-Stehen hindern -> Bug */
 
    background-image: url(http://www.kevin-fischer.de/firefox_button.png) !important; /* Firefox Logo im Hintergrund */
    background-repeat: no-repeat !important; /* Hintergrund nicht kacheln */
}
#main-window[sizemode="maximized"] #appmenu-button {
    margin-top:0 !important; /* Im Maximierten Zustand tritt der Aus-Dem-Fenster-Stehen-Bug nicht auf -> Rückgängig machen */
    -moz-border-radius-bottomleft: 0px !important; /* Linke untere Ecke eckig statt rund machen */
}
 
#appmenu-button-container {
    position: fixed !important;
}

HTML5 vs Flash

Sonntag, 13. Juni 2010 - Ein Kommentar

(This is my first english article :D )

A friend found this cool website called ‘chromeexperiments.com’ yesterday, and he thought it was just awesome how fast it runs in Chrome. And indeed, it is pretty awesome!
But I said, that Flash could do better!

So I rewrote this script in Flash (it’s 80% copypasta… gotta love the similiarity of JS and AS):
http://www.chromeexperiments.com/detail/liquid-particles/

This is the outcome: (Big 1280×720 version here: http://www.kevin-fischer.de/stuff/LiquidParticles.swf)

(Please note that this was made in ~15 minutes from the original JS version! It’s not optimized in any way and I know there are some glitches :) I just wanted to compare the performance)

So, what are the results?
The Flash version runs four times as fast, at rougly the same CPU usage:

Original JS:
- 500 particles
- 30 frames per second (one frame every 33ms)
- 15-17% CPU usage in Chrome

Flash version:
- 1000 particles
- 60 frames per second (one frame every 17ms)
- 12-16% CPU usage with FP 10.0 in FF 3.6.4

I think this is a clear win for Flash :)