<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ROAE-Blog &#187; code</title>
	<atom:link href="http://blog.root-of-all-evil.com/tag/code/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.root-of-all-evil.com</link>
	<description>Studium, Codeing und Gedachtes</description>
	<lastBuildDate>Mon, 30 Jan 2012 22:58:12 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Duration to execute code in Objectice-C</title>
		<link>http://blog.root-of-all-evil.com/2012/01/duration-to-execute-code-in-objectice-c/</link>
		<comments>http://blog.root-of-all-evil.com/2012/01/duration-to-execute-code-in-objectice-c/#comments</comments>
		<pubDate>Sat, 14 Jan 2012 19:45:35 +0000</pubDate>
		<dc:creator>Felix</dc:creator>
				<category><![CDATA[Codeschnipsel]]></category>
		<category><![CDATA[code]]></category>

		<guid isPermaLink="false">http://blog.root-of-all-evil.com/?p=915</guid>
		<description><![CDATA[<a href="http://blog.root-of-all-evil.com/2012/01/duration-to-execute-code-in-objectice-c/" title="Duration to execute code in Objectice-C"></a>This code snippet outputs the time which is needed to execute some code. - (void)someAction { // save current time CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent(); [self someAwesomeAlgorithm]; // print time difference to console // output Example: Took 0.000078 seconds. NSLog(@"Took %f &#8230;<p class="read-more"><a href="http://blog.root-of-all-evil.com/2012/01/duration-to-execute-code-in-objectice-c/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<a href="http://blog.root-of-all-evil.com/2012/01/duration-to-execute-code-in-objectice-c/" title="Duration to execute code in Objectice-C"></a><p>This code snippet outputs the time which is needed to execute some code.</p>
<pre class="c" title="code">- (void)someAction {

  // save current time
  CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent();

  [self someAwesomeAlgorithm];

  // print time difference to console
  // output Example: Took 0.000078 seconds.
  NSLog(@"Took %f seconds.", (CFAbsoluteTimeGetCurrent()-startTime));
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.root-of-all-evil.com/2012/01/duration-to-execute-code-in-objectice-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>fsockopen statt file_get_contents für HTTP-Requests</title>
		<link>http://blog.root-of-all-evil.com/2010/04/fsockopen-statt-file_get_contents-fur-http-requests/</link>
		<comments>http://blog.root-of-all-evil.com/2010/04/fsockopen-statt-file_get_contents-fur-http-requests/#comments</comments>
		<pubDate>Fri, 16 Apr 2010 13:00:05 +0000</pubDate>
		<dc:creator>Felix</dc:creator>
				<category><![CDATA[Codeschnipsel]]></category>
		<category><![CDATA[Erklärungen]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[post]]></category>

		<guid isPermaLink="false">http://blog.root-of-all-evil.com/?p=737</guid>
		<description><![CDATA[<a href="http://blog.root-of-all-evil.com/2010/04/fsockopen-statt-file_get_contents-fur-http-requests/" title="fsockopen statt file_get_contents für HTTP-Requests"></a>Bei zahlreichen Webspace-Providern ist die Funktionalität von file_get_contents für http deaktiviert. Es treten dann Fehlermeldungen wie Warning: file_get_contents() [function.file-get-contents]: URL file-access is disabled in the server configuration in [..] und Warning: file_get_contents([..]) [function.file-get-contents]: failed to open stream: no suitable wrapper &#8230;<p class="read-more"><a href="http://blog.root-of-all-evil.com/2010/04/fsockopen-statt-file_get_contents-fur-http-requests/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<a href="http://blog.root-of-all-evil.com/2010/04/fsockopen-statt-file_get_contents-fur-http-requests/" title="fsockopen statt file_get_contents für HTTP-Requests"></a><p>Bei zahlreichen Webspace-Providern ist die Funktionalität von file_get_contents für http deaktiviert. Es treten dann Fehlermeldungen wie</p>
<p><em>Warning: file_get_contents() [function.file-get-contents]: URL file-access is disabled in the server configuration in [..] </em>und<em></em></p>
<p><em>Warning: file_get_contents([..]) [function.file-get-contents]: failed to open stream: no suitable wrapper could be found in [..]</em></p>
<p>auf. Mit folgender Funktion kann man das Verhalten von file_get_contents jedoch emulieren.</p>
<p><span id="more-737"></span></p>
<p>Die Funktion <em>get_contents_by_uri</em> benutzt <em>fsockopen </em>um Inhalte zu laden:</p>
<pre class="php" title="code">/**
 * Gets contents of any webside by an URI.
 * @author http://blog.root-of-all-evil.com
 * @param String $uri
 */
function get_contents_by_uri($uri) {
	$uriElem = parse_url ( $uri );
	$fp = @fsockopen ( $uriElem ['host'], 80, $errno, $errstr, 10 );

	if (! $fp) {
		throw new Exception ( "Could not create socket: '" . $errnstr . "' (" . $errno . ")." );
	}

	$request = "GET " . $uriElem ['path'] . (isset ( $uriElem ['query'] ) ? "?" . $uriElem ['query'] : "") . " HTTP/1.1\r\n";
	$request .= "Host: " . $uriElem ['host'] . "\r\n";
	$request .= "Connection: Close\r\n\r\n";

	fwrite ( $fp, $request );
	$response = "";
	while ( ! feof ( $fp ) ) {
		$response .= fgets ( $fp, 128 );
	}
	fclose ( $fp );

	// split headers from data
	$responseSplit = explode ( "\r\n\r\n", $response, 2 );

	return $responseSplit [1];
}</pre>
<h1>Erklärung</h1>
<p><strong>Socket erstellen</strong></p>
<p>Die übergebene URI wird über die PHP-Funktion<em> parse_url</em> in ihre Teilmengen zerlegt. Anschließend wird ein Socket erstellt für den entsprechenden Host, auf Port 80 mit einem Timeout von 10 Sekunden. Fehlermeldungen unterdrücken wir durch das <em>@</em>, da wir explizit nach Erfolg abfragen und ggf. eine Ausnahme werfen.</p>
<p><strong>Anfrage schicken, Antwort lesen</strong></p>
<p>Danach wird über <em>fwrite </em>eine entsprechende GET-Anfrage geschickt, welche auch &#8211; falls vorhanden &#8211; die Parameter der URI und nicht nur den Pfad beachtet. Die darauffolgende Antwort wird in die Variable <em>response </em>gelesen.</p>
<p><strong>Antwort bearbeiten und zurückgeben</strong></p>
<p>Da diese neben dem eigentlichen Inhalt auch den Antwortheader enthält wird die Funktion <em>explode </em>benutzt um den Inhalt davon abzuschneiden. Durch den dritten Parameter bei <em>explode </em>mit dem Wert 2, stellen wir sicher, dass nur einmalig an Hand einer Leerzeile getrennt wird wie Sie sich zwischen Antwort-Header und HTML-Code befindet und nicht mehrmals, da natürlich auch Leerzeilen im HTML-Code selbst auftreten können.</p>
<p>Das zweite Element von <em>responseSplit </em>wird zurückgegeben, <em>responseSplit[0]</em> würde entsprechend den Antwort-Header liefern.</p>
<h1>Beispielaufrufe</h1>
<p>Der einfachste Aufruf:</p>
<pre class="php" title="code">echo get_contents_by_uri ( 'http://www.google.de/' );</pre>
<p>Aufruf mit Parametern:</p>
<pre class="php" title="code">echo get_contents_by_uri ( 'http://www.google.de/search?hl=de&amp;site=&amp;q=test' );</pre>
<p>Aufruf mit Ausnahmebehandlung:</p>
<pre class="php" title="code">try{
    echo get_contents_by_uri ( 'http://does_not_exist_.com/bogus.html' );
}
catch(Exception $e)
{
    echo "get_contents_by_uri: ".$e-&gt;getMessage();
}</pre>
<p>Weitere Links:</p>
<ul>
<li><a href="http://de2.php.net/parse_url">PHP &#8211; Funktion parse_url</a></li>
<li><a href="http://de2.php.net/fsockopen">PHP &#8211; Funktion file_get_contens</a></li>
<li><a href="http://de2.php.net/fsockopen">PHP &#8211; Funktion fsockopen</a></li>
<li><a href="http://de2.php.net/manual/en/function.explode.php">PHP &#8211; Funktion explode</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.root-of-all-evil.com/2010/04/fsockopen-statt-file_get_contents-fur-http-requests/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Thumbnails erzeugen und Durchschnittsfarbe in PHP ermitteln</title>
		<link>http://blog.root-of-all-evil.com/2010/02/thumbnails-erzeugen-und-durchschnittsfarbe-in-php-ermitteln/</link>
		<comments>http://blog.root-of-all-evil.com/2010/02/thumbnails-erzeugen-und-durchschnittsfarbe-in-php-ermitteln/#comments</comments>
		<pubDate>Thu, 18 Feb 2010 19:36:22 +0000</pubDate>
		<dc:creator>Philipp</dc:creator>
				<category><![CDATA[Codeschnipsel]]></category>
		<category><![CDATA[Guides]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Projekt]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[Durchschnittsfarbe]]></category>
		<category><![CDATA[Imagecolorat]]></category>
		<category><![CDATA[Imagecopyresampled]]></category>
		<category><![CDATA[Thumbnails generieren]]></category>

		<guid isPermaLink="false">http://blog.root-of-all-evil.com/?p=435</guid>
		<description><![CDATA[<a href="http://blog.root-of-all-evil.com/2010/02/thumbnails-erzeugen-und-durchschnittsfarbe-in-php-ermitteln/" title="Thumbnails erzeugen und Durchschnittsfarbe in PHP ermitteln"></a>Eines meiner etwas zurückliegenden Projekte zwang mich externe Bilder durch meinen Server zu laden, zu verkleinern und schließlich auch die Durchschnittsfarbe zu berechnen. Aus Gründen der Performancesteigerung war ich nie ein Fan davon die Durchschnittsfarbe Pixel für Pixel des Originalbildes &#8230;<p class="read-more"><a href="http://blog.root-of-all-evil.com/2010/02/thumbnails-erzeugen-und-durchschnittsfarbe-in-php-ermitteln/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<a href="http://blog.root-of-all-evil.com/2010/02/thumbnails-erzeugen-und-durchschnittsfarbe-in-php-ermitteln/" title="Thumbnails erzeugen und Durchschnittsfarbe in PHP ermitteln"></a><p>Eines meiner etwas <a title="qolors.net Visual Bookmarking" href="http://www.qolors.net" target="_blank">zurückliegenden Projekte</a> zwang mich externe Bilder durch meinen Server zu laden, zu verkleinern und schließlich auch die Durchschnittsfarbe zu berechnen. Aus Gründen der Performancesteigerung war ich nie ein Fan davon die Durchschnittsfarbe Pixel für Pixel des Originalbildes zu berechnen. <a href="http://blog.root-of-all-evil.com/2010/02/thumbnails-erzeugen-und-durchschnittsfarbe-in-php-ermitteln#durchschnittsfarbe" title="zum Berechnen der Durchschnittsfarbe springen">Es gibt eine viel elegantere und fast genauso exakte Lösung</a>:</p>
<p><span id="more-435"></span>Unser Ziel: Wir möchten ein Bild (jpg, gif, png) über einen HTTP-Stream laden,  dieses lokal auf dem Server speichern, ein entsprechendes Thumbnail  (eine verkleinerte Version) erzeugen, speichern und schlussendlich die  dominierende &#8211; oder auch durchschnittliche &#8211; Farbe im Bild berechnen und  abspeichern. Eventuell möchten wir zusätzlich alles in einer Datenbank  hinterlegen &#8211; das soll aber zunächst außerhalb unserer Betrachtung  liegen.</p>
<p>Für das Berechnen der Durchschnittsfarbe gibt es einen wunderbar  einfachen Trick. Doch dazu später mehr. Beginnen wir zunächst einmal mit  einer Konstante und einer Funktion, die wir später noch benötigen:</p>
<pre class="php" title="code">DEFINE('CTX', stream_context_create(array(
    'http' =&gt; array(
        'timeout' =&gt; 20,
        'method' =&gt; 'get',
        'header' =&gt; 'Referer: XYZ'
    )
)));</pre>
<p>Unsere Konstante CTX ist also ein array. Wir benötigen es für unsere  HTTP-Anfrage, mit der wir das gewünschte Bild auf unseren Server laden.  Für diese Anfrage verwenden wir die HTTP-GET-Methode, definieren einen  Timeout von maximal 20 Sekunden und senden einen Referer im Header, den  ich hier mal einfach nur &#8220;XYZ&#8221; genannt habe.</p>
<pre class="php" title="code">function randomstring_creator($len = 20) {
    $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    $string = '';
    mt_srand((double) microtime() * 1000000);
    for($i = 0; $i &lt; $len; $i++) {
        $string .= $chars{mt_rand(0, strlen($chars))};
    }
    return($string);
}</pre>
<p>Die Funktion randomstring_creator() generiert uns eine zufällige Zeichenfolge mit einer beliebigen Länge. Wir benötigen diese Funktion, da wir in diesem Beispiel die Bilder lokal unter einem zufälligem Namen speichern werden.</p>
<p>Weiter geht es mit unseren Klassen. Beginnen wir mit der Klasse <em>Image</em>:</p>
<pre class="php" title="code">class Image {
    var $img;
    var $source;
    var $local;
    var $dimX;
    var $dimY;
    var $avg_colour;
    function get($source, $quality = 90) {
// siehe unten
    }
    function calc_avg_colour() {
// siehe unten
    }
}</pre>
<p>Unsere Klasse besitzt also die Eigenschaften <em>source </em>(die Url,  von der das Bild stammt), <em>local </em>(den lokalen Speicherpfad), <em>dimX</em>,  <em>dimY </em>(die Abmessungen des Bildes in Pixel) und <em>avg_colour</em> (den farblichen Durchschnittswert als HEX-Code in der Form rrggbb). Die  Eigenschaft <em>img </em>ist eine Referenz auf das Image-Objekt, dass ich  aber später noch näher beleuchten werde.</p>
<p>Die beiden Funktionen <em>get()</em> und <em>calc_avg_colour()</em> der  Klasse sollten selbsterklärend sein. Mit der Funktion <em>get()</em>, die  gleichzeitig auch als Konstruktor dient, laden wir das Bild, dass unter <em>source </em>zu finden ist, auf unseren Server und speichern es in der  gewünschten JPEG-Qualität (90 als Standard) lokal.</p>
<p><em>calc_avg_colour()</em> berechnet &#8211; wie der Name schon sagt &#8211; die  Durchschnittsfarbe des in der Eigenschaft <em>img</em> gespeicherten  Bildes.</p>
<p>Wir wollen zusätzlich aber auch kleine Abbilder des Originalbildes  erstellen und erweitern dazu unsere <em>Image</em>-Klasse um die Klasse <em>Thumbnail</em>:</p>
<pre class="php" title="code">class Thumbnail extends Image {
    function create($parent, $X = 300, $Y = 300, $quality = 60) {
// siehe unten
    }
}</pre>
<p>Diese Erweiterung besitzt zunächst nur eine Funktion, mit der das  Thumbnail erstellt wird. Die übergebene Variable <em>parent </em>enthält  dabei eine bereits existierende <em>Image</em>-Klasse, die  herunterskaliert werden soll. Die maximale Breite und Höhe werden mit  den Variablen <em>X</em> und <em>Y</em> (standard bei 300 Pixel) übergeben.  Die JPEG-Qualität beträgt standardmäßig nur 60.</p>
<p>Das eigentliche Programm sieht dann nur noch so aus:</p>
<pre class="php" title="code">$imgurl = 'original.jpg';
// neues Objekt der Klasse Image erzeugen
$img = new Image;
// Bild aus der imgurl laden
if($img-&gt;get($imgurl)) {
    // ein Objekt der Klasse Thumbnail erzeugen
    $thumb = new Thumbnail;
    // und ein Thumbnail des oben definierten Objektes der Klasse Image generieren
    $thumb-&gt;create($img, 300, 300);
    // dann noch die Durschschnittsfarbe berechnen
    $thumb-&gt;calc_avg_colour();
    // und Daten ausgeben... fertig
    echo('Image: ' . $img-&gt;source . "\n");
    echo('Thumbnail: ' . $thumb-&gt;source . "\n");
    echo('Average colour: #' . $thumb-&gt;avg_colour . "\n");
} else {
    echo('Could not get the image.');
}</pre>
<p>So, dann sehen wir uns also mal unsere Funktionen der Klassen an.  Beginnen wir mit der Funktion <em>get()</em>:</p>
<pre class="php" title="code">function get($source, $quality = 90) {
    $this-&gt;source = $source;
    // wir laden das Bild von $source:
    if(($file = file_get_contents($this-&gt;source, false, CTX))) {
        // wenn erfolgreich, erzeugen wir mit den geladenen Daten
        // ein neues Bild und speichern dieses in der Eigenschaft img
        $this-&gt;img = imagecreatefromstring($file);
        // wir lesen die Höhe und Breite des Bildes aus
        $this-&gt;dimX = imagesx($this-&gt;img);
        $this-&gt;dimY = imagesy($this-&gt;img);
        // und speichern das Bild unter zufälligem Namen mit imagejpeg lokal im Ordner "raw"
        $this-&gt;local = 'raw/' . randomstring_creator() . '.jpg';
        imagejpeg($this-&gt;img, $this-&gt;local, $quality);
        // bei Erfolg true zurückgeben
        return(true);
    } else {
        // false, wenn das Bild nicht geladen werden konnte
        return(false);
    }
}</pre>
<p>Ein Thumbnail erzeugen wir mit dieser Funktion der Klasse <em>Thumbnail</em>:</p>
<pre class="php" title="code">function create($parent, $X = 300, $Y = 300, $quality = 60) {
    // zunächst die vorläufigen Abmessungen speichern
    $this-&gt;dimX = $X;
    $this-&gt;dimY = $Y;
    // die Abmessungen und deren Verhältnis des Originalbildes holen
    $origX = $parent-&gt;dimX;
    $origY = $parent-&gt;dimY;
    $ratio = $origX / $origY;
    // wenn das Originalbild breiter als hoch ist, kürzen wir die Höhe
    if($X / $Y &gt; $ratio) {
        $this-&gt;dimX = $Y * $ratio;
    } else {
    // wenn das Originalbild höher als breit ist, kürzen wir die Breite
        $this-&gt;dimY = $X / $ratio;
    }
    // hier erstellen wir ein neues Bild mit den oben berechneten Abmessungen
    $this-&gt;img = imagecreatetruecolor($this-&gt;dimX, $this-&gt;dimY);
    // und kopieren das Originalbild einfach in das eben erstellte kleinere, dabei wird es verkleinert
    imagecopyresampled($this-&gt;img, $parent-&gt;img, 0, 0, 0, 0, $this-&gt;dimX, $this-&gt;dimY, $origX, $origY);
    // jetzt speichern wir das neue Thumbnail noch unter zufälligem Namen im Ordner "thumb"
    $this-&gt;source = $parent-&gt;local;
    $this-&gt;local = 'thumb/' . randomstring_creator() . '.jpg';
    imagejpeg($this-&gt;img, $this-&gt;local, $quality);
}</pre>
<p>Das Herzstück: Wir wollen die  Durchschnittsfarbe ermitteln. Dazu könnten wir einfach alle Farbwerte  aller Pixel zusammen addieren und dann durch die Anzahl der Pixel  teilen. Bei einem Thumbnail von der Größe 300 x 300 Pixel, würden wir  aber eine Schleife mit 90.000 Durchläufen benötigen. Es gibt einen  besseren Weg &#8211; einen ganz logischen Trick.<br />
<a name="durchschnittsfarbe"></a><br />
<h3>Durchschnittsfarbe berechnen</h3>
<p>Wir haben oben beim Erstellen des Thumbnails die Funktion <em>imagecopyresampled()</em> verwendet. Was wenn wir unser Thumbnail einfach auf eine Größe von 1&#215;1  Pixel skalieren? Genau: Es bleibt ein Pixel mit der Durschnittsfarbe  übrig. Dessen Farbe auszulesen ist mit <em>imagecolorat()</em> dann nur  noch eine Kleinigkeit. Los gehts:</p>
<pre class="php" title="code">function calc_avg_colour() {
    // ein temporäres Bild mit den Abmessungen 1x1 Pixel erstellen
    $avrg = imagecreatetruecolor(1, 1);
    // Das Thumbnail einfach reinkopieren, dabei auf 1x1 Pixel skalieren
    imagecopyresampled($avrg, $this-&gt;img, 0, 0, 0, 0, 1, 1, $this-&gt;dimX, $this-&gt;dimY);
    // Die Farbe des verbleibenden Pixels auslesen
    $rgb = imagecolorat($avrg, 0, 0);
    // Das temporäre Bild wieder löschen
    imagedestroy($avrg);
    // Und die Farbe in HEX umwandeln
    $r = dechex($rgb &gt;&gt; 16);
    $g = dechex($rgb &gt;&gt; 8 &amp; 255);
    $b = dechex($rgb &amp; 255);
    if(strlen($r) &lt; 2) $r = 0 . $r;
    if(strlen($g) &lt; 2) $g = 0 . $g;
    if(strlen($b) &lt; 2) $b = 0 . $b;
    // tataaaa... da ist unsere Durchschnittsfarbe:
    $this-&gt;avg_colour = $r . $g . $b;
}</pre>
<p>Super. Das wäre es. Ende und aus.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.root-of-all-evil.com/2010/02/thumbnails-erzeugen-und-durchschnittsfarbe-in-php-ermitteln/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Serverseitig den Webseitenaufbau mit DNS CNAMES und mehr parallele HTTP-Verbindungen beschleunigen</title>
		<link>http://blog.root-of-all-evil.com/2010/02/serverseitig-den-webseitenaufbau-mit-dns-cnames-und-mehr-parallele-http-verbindungen-beschleunigen/</link>
		<comments>http://blog.root-of-all-evil.com/2010/02/serverseitig-den-webseitenaufbau-mit-dns-cnames-und-mehr-parallele-http-verbindungen-beschleunigen/#comments</comments>
		<pubDate>Sat, 06 Feb 2010 13:44:43 +0000</pubDate>
		<dc:creator>Philipp</dc:creator>
				<category><![CDATA[Codeschnipsel]]></category>
		<category><![CDATA[Guides]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Projekt]]></category>
		<category><![CDATA[beschleunigen]]></category>
		<category><![CDATA[bilder]]></category>
		<category><![CDATA[browser]]></category>
		<category><![CDATA[cnames]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[dns]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[media]]></category>

		<guid isPermaLink="false">http://blog.root-of-all-evil.com/?p=380</guid>
		<description><![CDATA[Man stelle sich folgendes Szenario vor: Es existiert eine Webseite, die eine Vielzahl von Grafiken, die auf dem gleichem Server hinterlegt sind, einbindet. Diese Webseite wird erfahrungsgemäß eine überdurchschnittlich lange Ladezeit haben. Aber nicht nur aufgrund der zu übertragenen Datenmengen, sondern auch aufgrund der maximalen Anzahl von Verbindungen, die ein Browser auf ein und denselben Server erlaubt. Hier werde ich etwas über die Beschleunigung vom Aufbau von Webseiten schreiben. Dabei verwende ich gewisse DNS Einstellungen, so genannte CNAME-Records mit denen ich serverseitig mehrere parallele HTTP-Verbindungen erlauben kann und so das Laden der Webseite durch den Browser des Nutzers beschleunige.<p class="read-more"><a href="http://blog.root-of-all-evil.com/2010/02/serverseitig-den-webseitenaufbau-mit-dns-cnames-und-mehr-parallele-http-verbindungen-beschleunigen/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<a href="http://blog.root-of-all-evil.com/2010/02/serverseitig-den-webseitenaufbau-mit-dns-cnames-und-mehr-parallele-http-verbindungen-beschleunigen/" title="Serverseitig den Webseitenaufbau mit DNS CNAMES und mehr parallele HTTP-Verbindungen beschleunigen"></a><p>Man stelle sich folgendes Szenario vor: Es existiert eine Webseite, die eine Vielzahl von Grafiken, die auf dem gleichem Server hinterlegt sind, einbindet. Diese Webseite wird erfahrungsgemäß eine überdurchschnittlich lange Ladezeit haben. Aber nicht nur aufgrund der zu übertragenen Datenmengen, sondern auch aufgrund der maximalen Anzahl von Verbindungen, die ein Browser auf ein und denselben Server erlaubt. Hier werde ich etwas über die Beschleunigung vom Aufbau von Webseiten schreiben. Dabei verwende ich gewisse DNS Einstellungen, so genannte CNAME-Records mit denen ich serverseitig mehrere parallele HTTP-Verbindungen erlauben kann und so das Laden der Webseite durch den Browser des Nutzers beschleunige.<br />
<span id="more-380"></span></p>
<p>Standardmäßig sind moderne Browser mit maximalen Anzahl von <a href="http://stevesouders.com/ua/report.php?v=top&amp;nosparse=1" target="_blank">sechs Verbindungen (IE 6 und IE 7 maximal zwei Verbindungen)</a> zu ein und demselben Host begrenzt. Das führt dazu, dass das Laden von Dateien (Bilder, HTML-Seiten, JavaScripts oder Stylesheets) von einer Webseite in Blöcken unterteilt wird. Dabei würde es um einiges schneller gehen können, wenn ich die zu ladenden Dateien auf verschiedene Hostnamen verteile. So können für jeden Hostnamen mehr Verbindungen gleichzeitig ermöglicht werden.</p>
<p>Man betrachte zum Beispiel Google Maps. Die angezeigte Karte besteht aus einer vielzahl von so genannten Tiles. Tiles sind einfach Kacheln. Jede Kachel stellt einen Kartenausschnitt dar:</p>
<p><img class="aligncenter size-full wp-image-383" title="2009-08-13_1515-526x395" src="http://blog.root-of-all-evil.com/wp-content/uploads/2010/02/2009-08-13_1515-526x395.png" alt="" width="526" height="395" /></p>
<p>Damit die Karte schnellstmöglich trotz der Browserbegrenzung von sechs Verbindungen geladen werden kann, verteilt Google Maps die zu ladenden Kacheln auf verschiedene Hostnamen (Subdomains). Google verwendet vier Subdomains: mt0, mt1, mt2 und mt3.google.de:</p>
<p><img class="aligncenter size-full wp-image-384" title="2009-08-13_1520-526x326" src="http://blog.root-of-all-evil.com/wp-content/uploads/2010/02/2009-08-13_1520-526x326.png" alt="" width="526" height="326" /></p>
<p>Grundsätzlich ist es kein großes Problem verschiedene Subdomains anzulegen und die Dateien einer Webseite auf diese Subdomains zu verteilen. Allerdings besteht so recht schnell die Gefahr, dass man als Administrator den Überblick verliert, wo welche Dateien abgespeichert sind. Einfacher wäre es, zB. alle Mediendateien (zB. Bilder, Videos) unter einer Subdomain abzuspeichern. Um das Laden der Startseite erheblich zu beschleunigen, aber ohne zahlreiche Subdomains zu arbeiten kann man wie folgt vorgehen:</p>
<ol>
<li> Ich lege unter der Hauptdomain eine einzige subdomain namens  media.domain an. Hier speichere ich alle Bilder ab.</li>
<li>Ich lege so genannte CNAMES Einträge in meinen DNS Einstellungen an.  Ein CNAME ist &#8211; einfach erklärt &#8211; ein Domain-Alias. In meinem Fall  wähle ich zwei CNAME-Einträge namens &#8220;media0.domain.de&#8221; und  &#8220;media1.domain.de&#8221; an. Am einfachsten geht es über die Adminoberfläche  Plesk und sieht folgendermaße aus:<img class="aligncenter size-full wp-image-385" title="2009-08-13_1601" src="http://blog.root-of-all-evil.com/wp-content/uploads/2010/02/2009-08-13_1601.png" alt="" width="520" height="209" /></li>
<li>Diese beiden Einträge bewirken, dass media0.domain.de und  media1.domain.de auf die gleiche subdomain media.domain.de umleiten. Ich  habe jetzt also eine Subdomain, die auf drei unterschiedliche Weisen  erreicht werden kann. Der Browser des Nutzers interpretiert die drei  Domains als drei unterschiedliche Adressen, die aber auf den gleichen  Speicherort verweisen. So sind drei mal so viele Verbindungen zum eigentlich  gleichen Host möglich. Der Browser wird einfach ausgetrickst.</li>
<li>Bei der Einbindung der Bilder in die Webseite muss ich jetzt nur die  zwei verschiedenen &#8220;subdomains&#8221; media0 und media1 verteilen. Ich löse  das über einen Zufallsgenerator in meinem PHP Script, dass den HTML-Code  generiert. Dieser könnte zB. so aussehen:</li>
</ol>
<pre class="php" title="code">$media_domains = array('media0', 'media1');
foreach($bilder as $bild) {
  shuffle($media_domains);
  echo('&lt;img src="' . $media_domains[0] . '.domain.tld/img/'. $bild . '" /&gt;');
}</pre>
<p>Und fertig. Kommentare, Verbesserungsvorschlage? Dazu sind die Kommentare da.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.root-of-all-evil.com/2010/02/serverseitig-den-webseitenaufbau-mit-dns-cnames-und-mehr-parallele-http-verbindungen-beschleunigen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

