<?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>CWD - Customized Web Development &#187; Blog</title>
	<atom:link href="http://www.cwd.at/category/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.cwd.at</link>
	<description></description>
	<lastBuildDate>Fri, 30 Oct 2009 00:27:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>Echte PHP Performance Tipps</title>
		<link>http://www.cwd.at/2009/07/20/echte-php-performance-tipps/</link>
		<comments>http://www.cwd.at/2009/07/20/echte-php-performance-tipps/#comments</comments>
		<pubDate>Mon, 20 Jul 2009 21:11:45 +0000</pubDate>
		<dc:creator>LudwigR</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Netzfundstück]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.cwd.at/?p=189</guid>
		<description><![CDATA[Anlässlich der Google I/O 2009 gab Eric Higgins einen Vortrag unter dem Titel: &#8220;Let&#8217;s make the Web faster &#8211; PHP performance tips&#8221; Leider waren viele seiner Tipps entweder Uralt und bringen bei aktuellen PHP Versionen wenig bis gar nichts, oder es waren wirklich nur blödsinn. (Sorry ist nicht meine Aussage) Stas Malyshev (Zend Angestellter und [...]]]></description>
			<content:encoded><![CDATA[<p>Anlässlich der Google I/O 2009 gab Eric Higgins einen Vortrag unter dem Titel: &#8220;<a href="http://code.google.com/intl/de-DE/speed/articles/optimizing-php.html" target="_blank">Let&#8217;s make the Web faster &#8211; PHP performance tips</a>&#8221; Leider waren viele seiner Tipps entweder Uralt und bringen bei aktuellen PHP Versionen wenig bis gar nichts, oder es waren wirklich nur blödsinn. (Sorry ist nicht meine Aussage)</p>
<p><span id="more-189"></span></p>
<p>Stas Malyshev (Zend Angestellter und PHP Core Entwickler) hat in seinem php100 Blog 2 Artikel in dem einen wird der Google Artikel unter die Lupe genommen. Im anderen werden echte Tipps gegeben. Die meisten davon sollte jeder PHP Programmierer schon gehört haben. Ein drüber lesen schadet auf keinen Fall.</p>
<ul>
<li><a href="http://php100.wordpress.com/2009/06/26/php-performance-google/" target="_blank">PHP performance tips from google by Stas Malyshev</a></li>
<li><a href="http://php100.wordpress.com/2009/07/13/php-performance/" target="_blank"> More on PHP performance by Stas Malyshev</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.cwd.at/2009/07/20/echte-php-performance-tipps/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zend Framework 1.9.0 Preview Release</title>
		<link>http://www.cwd.at/2009/07/18/zend-framework-1-9-0-preview-release/</link>
		<comments>http://www.cwd.at/2009/07/18/zend-framework-1-9-0-preview-release/#comments</comments>
		<pubDate>Sat, 18 Jul 2009 09:09:58 +0000</pubDate>
		<dc:creator>LudwigR</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://www.cwd.at/2009/07/18/zend-framework-1-9-0-preview-release/</guid>
		<description><![CDATA[Zend hat gestern Abend die Preview von Zend Framework 1.9 freigegeben. http://devzone.zend.com/article/4846]]></description>
			<content:encoded><![CDATA[<p>Zend hat gestern Abend die Preview von Zend Framework 1.9 freigegeben.<br />
<a href="http://devzone.zend.com/article/4846" target="_blank">http://devzone.zend.com/article/4846</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cwd.at/2009/07/18/zend-framework-1-9-0-preview-release/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP unbekannte Perlen</title>
		<link>http://www.cwd.at/2009/07/17/php-unbekannte-perlen/</link>
		<comments>http://www.cwd.at/2009/07/17/php-unbekannte-perlen/#comments</comments>
		<pubDate>Fri, 17 Jul 2009 10:19:04 +0000</pubDate>
		<dc:creator>LudwigR</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.cwd.at/?p=182</guid>
		<description><![CDATA[Jetzt arbeite ich schon seit über 10 Jahren in PHP, aber es gibt immer noch Befehle die ich noch nie verwendet habe. Eher zufällig stolperte ich heute über debug_backtrace und debug_print_backtrace. (Gruß an Matthias) Wenn man in PHP5 Coded und eifrig Exceptions verwendet kennt man sicher Exception::getTrace() bzw Exception::getTraceAsString() debug_[print_]backtrace macht im prinzip das selbe, [...]]]></description>
			<content:encoded><![CDATA[<p>Jetzt arbeite ich schon seit über 10 Jahren in PHP, aber es gibt immer noch Befehle die ich noch nie verwendet habe.</p>
<p>Eher zufällig stolperte ich heute über <a title="debug_backtrace @php.net" href="http://at2.php.net/manual/de/function.debug-backtrace.php" target="_blank">debug_backtrace</a> und <a title="debug_print_backtrace @php.net" href="http://at2.php.net/manual/de/function.debug-print-backtrace.php" target="_blank">debug_print_backtrace</a>. (Gruß an Matthias)</p>
<p><span id="more-182"></span>Wenn man in PHP5 Coded und eifrig Exceptions verwendet kennt man sicher Exception::getTrace() bzw Exception::getTraceAsString() debug_[print_]backtrace macht im prinzip das selbe, es liefert ein Array bzw String mit dem Backtrace der aktuellen Funktion.</p>
<p>Und warum hab ich das bislang nicht gebraucht, keine Ahnung.</p>
<p>Vorschläge für weitere Perlen gerne in den Kommentaren.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cwd.at/2009/07/17/php-unbekannte-perlen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zend Framework 1.8.2 erschienen</title>
		<link>http://www.cwd.at/2009/05/28/zend-framework-182-erschienen/</link>
		<comments>http://www.cwd.at/2009/05/28/zend-framework-182-erschienen/#comments</comments>
		<pubDate>Thu, 28 May 2009 07:07:01 +0000</pubDate>
		<dc:creator>LudwigR</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://www.cwd.at/?p=125</guid>
		<description><![CDATA[Gestern ist Zend Framework 1.8.2 erschienen. Changelog findet sich hier. Mein persönliches Highlight: Zend_Db_Table und Joins arbeiten endlich wie sie sollen.]]></description>
			<content:encoded><![CDATA[<p>Gestern ist Zend Framework 1.8.2 erschienen. <a href="http://framework.zend.com/changelog" target="_blank">Changelog findet sich hier.</a></p>
<p>Mein persönliches Highlight: Zend_Db_Table und Joins arbeiten endlich wie sie sollen.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cwd.at/2009/05/28/zend-framework-182-erschienen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Aufruf an die PHP Experten: ErrorHandling HowTo</title>
		<link>http://www.cwd.at/2009/05/25/aufruf-an-die-php-experten-errorhandling-howto/</link>
		<comments>http://www.cwd.at/2009/05/25/aufruf-an-die-php-experten-errorhandling-howto/#comments</comments>
		<pubDate>Mon, 25 May 2009 21:36:32 +0000</pubDate>
		<dc:creator>LudwigR</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://www.cwd.at/?p=121</guid>
		<description><![CDATA[Normalerweise, wenn ich ein Problem habe, mache ich was tausende Leute auch machen. Googeln. Leider habe ich diesmal nicht wirklich etwas gefunden. Problemstellung: Ich bin gerade dabei eine ziemlich große mehrteilige API zu schreiben. Diese API wird von anderen Programmieren verwendet. Mein Problem ist nun, wie handle ich das ErrorReporting. Klar, ich kann für jede [...]]]></description>
			<content:encoded><![CDATA[<p>Normalerweise, wenn ich ein Problem habe, mache ich was tausende Leute auch machen. Googeln. Leider habe ich diesmal nicht wirklich etwas gefunden.</p>
<p><span id="more-121"></span></p>
<p>Problemstellung:</p>
<p>Ich bin gerade dabei eine ziemlich große mehrteilige API zu schreiben. Diese API wird von anderen Programmieren verwendet. Mein Problem ist nun, wie handle ich das ErrorReporting.</p>
<p>Klar, ich kann für jede meiner Hauptklassen eigene Exception Klassen schreiben, die müssten aber wiederum eigene Exception Codes ausgeben damit die Programmierer welche die API verwenden wissen wie sie darauf reagieren sollen. Eigentlich wollte ich es vermeiden eine Liste mit Fehlercodes zu erstellen. (ob nun mit oder ohne Exceptions)</p>
<p>Ich wollte Exceptions eigentlich nur verwenden wenn &#8220;Unerwartetes&#8221; passiert. ZB. keine Datenbankconnection, File konnte nicht ins Filesystem geschrieben werden&#8230; solche Dinge. Darüber hat auch <a href="http://www.phphatesme.com/blog/softwaretechnik/wann-verwende-ich-exceptions/" target="_blank">Nils Langner in seinem Blog schon geschrieben.</a></p>
<p>Also liebe PHP-Bloggemeinde. Was ist die best Practice in so einem Fall ?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cwd.at/2009/05/25/aufruf-an-die-php-experten-errorhandling-howto/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Sketch the Web: Mockups mit Balsamiq Mockups</title>
		<link>http://www.cwd.at/2009/05/20/sketch-the-web-mockups-mit-balsamiq-mockups/</link>
		<comments>http://www.cwd.at/2009/05/20/sketch-the-web-mockups-mit-balsamiq-mockups/#comments</comments>
		<pubDate>Wed, 20 May 2009 20:05:58 +0000</pubDate>
		<dc:creator>LudwigR</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Netzfundstück]]></category>

		<guid isPermaLink="false">http://www.cwd.at/?p=113</guid>
		<description><![CDATA[Mockups oder Wireframes sind eine nette Sache. Sie zeigen schnell welche Elemente es in einer Applikation oder Website geben muss, und wo sie positioniert sind. Wenn sich Kunde und Konzeptionist darüber einig sind, bekommt es der Grafiker um ein endgültiges Layout zu machen. Bis vor nicht allzu langer Zeit &#8220;malte&#8221; ich die Mockups per Hand [...]]]></description>
			<content:encoded><![CDATA[<p>Mockups oder Wireframes sind eine nette Sache. Sie zeigen schnell welche Elemente es in einer Applikation oder Website geben muss, und wo sie positioniert sind. Wenn sich Kunde und Konzeptionist darüber einig sind, bekommt es der Grafiker um ein endgültiges Layout zu machen.</p>
<p><span id="more-113"></span>Bis vor nicht allzu langer Zeit &#8220;malte&#8221; ich die Mockups per Hand oder in <a href="http://live.gnome.org/Dia" target="_blank">DIA</a>, aber diese Zeiten sind vorbei. Habe endlich ein Mockup Tool gefunden mit dem ich schnell und ohne große Probleme die Sketches erstellen kann. (OK, das hört sich stark nach Werbung an, soll es aber gar nicht sein. Um ehrlich zu sein, noch nie habe ich so schnell UI&#8217;s entworfen wie mit diesem Tool).</p>
<p>Probiert es mal selber aus, auf der <a href="http://www.balsamiq.com/products/mockups/" target="_blank">Website von Balsamiq</a> gibts eine Web Version zum herumspielen.</p>

<a href='http://www.cwd.at/2009/05/20/sketch-the-web-mockups-mit-balsamiq-mockups/bahoomaps/' title='bahoomaps'><img width="150" height="150" src="http://www.cwd.at/wp-content/uploads/2009/05/bahoomaps-150x150.gif" class="attachment-thumbnail" alt="bahoomaps" title="bahoomaps" /></a>
<a href='http://www.cwd.at/2009/05/20/sketch-the-web-mockups-mit-balsamiq-mockups/mytube/' title='mytube'><img width="150" height="150" src="http://www.cwd.at/wp-content/uploads/2009/05/mytube-150x150.gif" class="attachment-thumbnail" alt="mytube" title="mytube" /></a>
<a href='http://www.cwd.at/2009/05/20/sketch-the-web-mockups-mit-balsamiq-mockups/wiki/' title='wiki'><img width="150" height="150" src="http://www.cwd.at/wp-content/uploads/2009/05/wiki-150x150.gif" class="attachment-thumbnail" alt="wiki" title="wiki" /></a>

<p><small>(Bilder Copyright by <a href="http://www.balsamiq.com" target="_blank">www.balsamiq.com</a>)</small></p>
<p>Es gibt natürlich immer jemanden dem es nicht gefällt. Warum auch nicht, wir haben ja immer noch den &#8220;Freedom of Choice&#8221;. Einer der einen <a href="http://www.andybudd.com/archives/2009/04/my_first_impres/" target="_blank">netten Artikel darüber geschrieben hat ist Andy Budd</a> (auch die Kommentare lesen ! <img src='http://www.cwd.at/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> . Man sollte dazusagen dass Andy in erster Linie Grafiker bzw. Designer ist, da ist der Zugang ein anderer. (zb. verwendet Balsamiq Comic Sans als default Font) Zurück zum Freedom of Choice, <a href="http://www.sitepoint.com/articlelist/547/" target="_blank">Garry Barber</a> hat auf <a href="http://www.sitepoint.com">Sitepoint</a> eine kleine <a href="http://www.sitepoint.com/article/tools-prototyping-wireframing/" target="_blank">Zusammenstellung von Mockup Applikationen.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cwd.at/2009/05/20/sketch-the-web-mockups-mit-balsamiq-mockups/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Caching Zend_Db_Table Models</title>
		<link>http://www.cwd.at/2009/05/18/caching-zend_db_table-models/</link>
		<comments>http://www.cwd.at/2009/05/18/caching-zend_db_table-models/#comments</comments>
		<pubDate>Mon, 18 May 2009 18:27:00 +0000</pubDate>
		<dc:creator>LudwigR</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://www.cwd.at/?p=100</guid>
		<description><![CDATA[(Dieser Artikel ist ausnahmsweise in Englisch) Have you ever felt the need to cache Databaseresults ? Of course you have. Do you also use Zend_Db_Table for the less complex queries ? Then this may be interesting for you. Of course, these simple queries would easily fit in MySQL (or any other DB) query cache. But [...]]]></description>
			<content:encoded><![CDATA[<p>(Dieser Artikel ist ausnahmsweise in Englisch)</p>
<p>Have you ever felt the need to cache Databaseresults ? Of course you have. Do you also use Zend_Db_Table for the less complex queries ? Then this may be interesting for you.</p>
<p><span id="more-100"></span>Of course, these simple queries would easily fit in MySQL (or any other DB) query cache. But maybe you want to save this for your complex queries building Tmp-Tables in MEMORY. Or for whatever reason, here is a solution.</p>
<p>You find the full <a href="http://svn.cwd.at/cwd/trunk/Cwd/" target="_blank">classes on my svn.</a></p>
<p>The basic idea is from <a href="http://www.contentwithstyle.co.uk/content/a-caching-pattern-for-models" target="_blank">Pascal Opitz</a> with contributions from <a href="http://www.contentwithstyle.co.uk/content/a-caching-pattern-for-models#comment-5876" target="_blank">Robert Kummer</a> and <a href="http://www.contentwithstyle.co.uk/content/a-caching-pattern-for-models#comment-5935" target="_blank">Sascha-Oliver Prolic</a>. Their version is great but does not work with Zend_Db_Table.</p>
<p>Let&#8217;s start with extending Zend_Db_Table_Abstract:</p>
<pre><code class="php">
abstract class Cwd_Db_Table extends Zend_Db_Table_Abstract {
	/**
	 * @var Cwd_Db_Cache
	 */
	public $cache;

	protected $_rowClass ='Cwd_Db_Table_Row';

	public function __construct($config=array()) {
		parent::__construct($config);
		/**
		 * @var Cwd_Db_Cache
		 */
		$this-&gt;cache = new Cwd_Db_Cache($this);
	}
}
</code></pre>
<p>We just add the cache to it and set the protected var $_rowClass, this is needed because we want the results to be of our own implementation of Zend_Db_Table_Row_Abstract.</p>
<p>Our implementation looks like this:</p>
<pre><code class="php">
class Cwd_Db_Table_Row extends Zend_Db_Table_Row_Abstract {
	/**
	 * @var Cwd_Db_Cache
	 */
	public $cache;

	public function __construct($config=array()) {
		parent::__construct($config);

		$this-&gt;cache = new Cwd_Db_Cache($this);
	}

	public function setTable(Zend_Db_Table_Abstract $table = null)
    {
        if ($table == null) {
            $this-&gt;_table = null;
            $this-&gt;_connected = false;
            return false;
        }

        $tableClass = get_class($table);

        /**
        // we lost $this-&gt;_tableClass, so this would throw always an exception
		// we have to ignore this for now.

        if (! $table instanceof $this-&gt;_tableClass) {
            require_once 'Zend/Db/Table/Row/Exception.php';
            throw new Zend_Db_Table_Row_Exception("The specified Table is of class $tableClass, expecting class to be instance of $this-&gt;_tableClass");
        }
		*/

        $this-&gt;_table = $table;
        $this-&gt;_tableClass = $tableClass;

        $info = $this-&gt;_table-&gt;info();

        if ($info['cols'] != array_keys($this-&gt;_data)) {
            require_once 'Zend/Db/Table/Row/Exception.php';
            throw new Zend_Db_Table_Row_Exception('The specified Table does not have the same columns as the Row');
        }

        if (! array_intersect((array) $this-&gt;_primary, $info['primary']) == (array) $this-&gt;_primary) {

            require_once 'Zend/Db/Table/Row/Exception.php';
            throw new Zend_Db_Table_Row_Exception("The specified Table '$tableClass' does not have the same primary key as the Row");
        }

        return true;
    }	

    /**
     * Set the table
     * this is necessary if the row lies in cache
     *
     * also we aresetting automatically a cache suffix
     *
     * @param $table Zend_Db_Table_Abstract A instance of a model.
     */
    public function prep($table){
    	$this-&gt;setTable($table);
        $table=$this-&gt;getTable()-&gt;info();
        $tablename=$table['name'];
        $primary=$table['primary'][1];

        $this-&gt;cache-&gt;setCacheSuffix($tablename.'__'.$this-&gt;$primary.'__');
    }
}
</code></pre>
<p>Ok, what did we do. We have our cache in it, and are overwriting the setTable method.  If the row is stored in the cache, we lose _tableClass, and the only way to set it right again is to use the setTable method, but unfortunatly this method is checking if the table object we give to it is the same as the object in _tableClass &#8230; you see the problem. So we have to overwrite this only to comment this part out.</p>
<p>At the bottom you see a new prep method. This method calls the setTable method and also sets a cache suffix. This is needed becouse the Zend_Cache_Frontend_Class generates the id only by method name and parameters, but not on contents of the object. So if you have a loop and for example use findParentRow() in it, you would get the same row for every  Query from the cache. This is not what we want. So we autoextend the cache suffix by the primary key column with the value of the primary key. (in the current version, there is no check if the primary key has more than one field. If you need this feel free to overwrite/extend my class)</p>
<p>To make use of these classes you just have to build your models by extending Cwd_Db_Table instead of Zend_Db_Table_Abstract.</p>
<p>If you have done so, you can use it like in the following example:</p>
<pre><code>

    	$m_event = new EventModel();
    	$m_act = new ActModel();
    	$events = $m_event-&gt;cache-&gt;fetchAll(array("status='1'","deleted='0'"),'createdate desc',10,0);
    	echo "&lt;ul&gt;";
    	foreach($events as $event){
    		echo "&lt;li&gt;".$event-&gt;event_id."&lt;/li&gt;";
			$event-&gt;prep($m_event);

    		$acts = $event-&gt;cache-&gt;findDependentRowset('ActModel');
    		echo "&lt;ul&gt;";
    		foreach($acts as $act){
    			$act-&gt;prep($m_act);
    			$foo = $act-&gt;cache-&gt;findParentRow('EventModel');
    			echo "&lt;li&gt;".$act-&gt;act_id." (".$foo-&gt;event_id.")&lt;/li&gt;";
    		}
    		echo "&lt;/ul&gt;";
    	}
    	echo "&lt;/ul&gt;";

</code></pre>
<p>Easy, isn&#8217;t it ? The caching is flexible, so it doesn&#8217;t matter if all rows are in the cache. All combinations are working. To bypass the cache you can use the model directly without the -&gt;cache-&gt;.</p>
<p>The cache class is using Zend_Config for some parameters, for reference here are the values:</p>
<pre>caching.cache_by_default	= true
caching.default_cache_id_prefix	= default_
caching.lifetime			= 300
caching.backendName			= Memcached</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.cwd.at/2009/05/18/caching-zend_db_table-models/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Konami Code &#8211; Easter Eggs auf Webseiten</title>
		<link>http://www.cwd.at/2009/05/15/konami-code-easter-eggs-auf-webseiten/</link>
		<comments>http://www.cwd.at/2009/05/15/konami-code-easter-eggs-auf-webseiten/#comments</comments>
		<pubDate>Thu, 14 May 2009 22:00:03 +0000</pubDate>
		<dc:creator>LudwigR</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Netzfundstück]]></category>

		<guid isPermaLink="false">http://blog.cwd.at/?p=83</guid>
		<description><![CDATA[Als ich noch jung war (OMG jetzt fang ich auch schon so an&#8230;) hatte ich eine NES Box. Und fast alle Spiele aus dem Hause Konami hatten ein Backdoor das immer nach dem selben Prinzip funktionierte. Rauf, Rauf, Runter, Runter, Links, Rechts, Links, Rechts, B, A Dieser &#8220;Cheat&#8221; führte je nach Spiel Unterschiedliches aus, mal [...]]]></description>
			<content:encoded><![CDATA[<p>Als ich noch jung war (OMG jetzt fang ich auch schon so an&#8230;) hatte ich eine <a href="http://de.wikipedia.org/wiki/Nintendo_Entertainment_System" target="_blank">NES</a> Box. Und fast alle Spiele aus dem Hause Konami hatten ein Backdoor das immer nach dem selben Prinzip funktionierte.</p>
<p><span id="more-83"></span></p>
<p><strong>Rauf, Rauf, Runter, Runter, Links, Rechts, Links, Rechts, B, A</strong></p>
<p>Dieser &#8220;Cheat&#8221; führte je nach Spiel Unterschiedliches aus, mal nur ein EasterEgg, mal ein Cheat (extra Leben, PowerUps&#8230; das übliche halt). Die Code Sequenz wurde so berühmt dass sie (teilweise in leichter Abwandlung) auch von anderen Herstellern verwendet wurde. Eine Liste findet sich zB. auf <a href="http://en.wikipedia.org/wiki/List_of_Konami_code_games" target="_blank">Wikipedia</a>.</p>
<p>Das alles wäre natürlich keinen Blogeintrag wert wenn es da nicht eine doch interessante Entwiklung gäbe. Immer mehr Websites verstecken EasterEggs hinter einem Konami Code. Beispiel gefällig ? Geht einfach mal auf <a href="http://jquery.com/" target="_blank">http://jquery.com</a> und gebt den Code ein.</p>
<p>JQuery ist aber nicht die einzige Seite die das macht. Es gibt mittlerweile viele Seiten die den Code verwenden. Eine Liste von Seiten ist zu finden auf <a href="http://konamicodesites.com" target="_blank">Konami Code Sites</a>, um Zugang zur Seite zu erhalten ist die Eingabe des Codes erforderlich.</p>
<p><a href="http://www.cwd.at" target="_blank">Probiert es aus</a>, ich habe es mir schon fast angewöhnt bei größeren Seiten auch den Code einzugeben.</p>
<p>Um einen Konami Code in die eigene Seite einzubinden kann zB. Jquery verwendet werden. <a href="http://plugins.jquery.com/files/jquery.konami.js.txt" target="_blank">Joe Mastey hat dazu eine kleines JQuery Plugin geschrieben</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cwd.at/2009/05/15/konami-code-easter-eggs-auf-webseiten/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>AW: Projektwerkstatt: WordPress Google Backup</title>
		<link>http://www.cwd.at/2009/05/14/aw-projektwerkstatt-wordpress-google-backup/</link>
		<comments>http://www.cwd.at/2009/05/14/aw-projektwerkstatt-wordpress-google-backup/#comments</comments>
		<pubDate>Thu, 14 May 2009 10:15:56 +0000</pubDate>
		<dc:creator>LudwigR</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Netzfundstück]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://cwd/?p=63</guid>
		<description><![CDATA[Eigentlich sollte das nur ein Kommentar auf einen Artikel von Nils im phphatesme.com Blog werden. Aber da er etwas lang geworden ist, wird&#8217;s gleich ein eigener Artikel. Only wimps use tape backup: _real_ men just upload their important stuff on ftp, and let the rest of the world mirror it. &#8221; &#8212; Linus Torvalds Aber [...]]]></description>
			<content:encoded><![CDATA[<p>Eigentlich sollte das nur ein Kommentar auf einen Artikel von Nils im <a title="phpHatesMe" href="http://www.phphatesme.com/" target="_blank">phphatesme.com</a> Blog werden. Aber da er etwas lang geworden ist, wird&#8217;s gleich ein eigener Artikel.</p>
<blockquote><p>Only wimps use tape backup: _real_ men just upload their important stuff on ftp, and let the rest of the world mirror it. &#8221;<br />
&#8212; Linus Torvalds</p></blockquote>
<p><span id="more-63"></span>Aber zu Deiner Idee, ich halte das für eine nette Gedankenspielerei, aber ich finde der Sinn eines Backups ist es auch in der schnellstmöglichen Zeit wieder online zu sein. Wenn der Hoster keine Cronjobs bietet (&#8230; schlechter Hoster btw.) wäre es wohl einfacher ein paar Zeilen Code zu schreiben welche in die Seite eingebunden werden, und periodisch (zB. jeden Tag oder alle paar Stunden, je nach Änderungshäufigkeit) die Datenbanken und wichtigen Files in ein Archiv zu packen und zu archivieren.</p>
<p>Dabei gibt es wieder zwei Varianten, entweder von einem Server der Cronjobs bietet eine bestimmte URL aufrufen, welche den Backup Prozess anstößt, oder wenn auch das nicht möglich ist, über Triggers die bei jedem Seitenaufruf ausgeführt werden.</p>
<p>Für letzteres eignet sich &#8220;selbst modifizierender Code&#8221; ganz gut. Bei jedem Seitenaufruf wird eine PHP Datei inkludiert die zB. nur folgendes enthält:</p>
<pre><code class="php">&lt;?php $lastrun = 123456789; # Timestamp of last run ?&gt;</code></pre>
<p>Dann wird einfach überprüft ob $lastrun länger als zB. 24h zurückliegt,  wenn ja wird das Backup angestossen. Jetzt muss nur noch die Datei aktualisiert werden, indem der aktuelle Timestamp in die Datei geschrieben wird.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cwd.at/2009/05/14/aw-projektwerkstatt-wordpress-google-backup/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Six Degrees of Separation (Friend of a Friend)</title>
		<link>http://www.cwd.at/2009/05/13/six-degrees-of-seperation-friend-of-a-friend/</link>
		<comments>http://www.cwd.at/2009/05/13/six-degrees-of-seperation-friend-of-a-friend/#comments</comments>
		<pubDate>Wed, 13 May 2009 20:28:11 +0000</pubDate>
		<dc:creator>LudwigR</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://cwd/?p=50</guid>
		<description><![CDATA[Nein, hier geht&#8217;s nicht um den Film-Remake mit Will Smith (Six Degrees of Separation) sondern um eine Funktion die man öfters auf Social-Web 2.0 Seiten sieht. Ich kenne diese Person über &#8230;. Kleine Geschichtsstunde. Ich bin so frei und übernehme den Text des Wikipedia Artikels: 1967 startete der Psychologe/Soziologe Stanley Milgram (übrigends der selbe welcher [...]]]></description>
			<content:encoded><![CDATA[<p>Nein, hier geht&#8217;s nicht um den Film-Remake mit Will Smith (<a href="http://www.imdb.com/title/tt0108149/" target="_blank">Six Degrees of Separation</a>) sondern um eine Funktion die man öfters auf Social-Web 2.0 Seiten sieht. Ich kenne diese Person über &#8230;. <span id="more-50"></span> Kleine Geschichtsstunde. Ich bin so frei und übernehme den Text des <a href="http://de.wikipedia.org/wiki/Kleine_Welt#Experiment" target="_blank">Wikipedia Artikels</a>:</p>
<blockquote><p>1967 startete der Psychologe/Soziologe Stanley Milgram (übrigends der selbe welcher das &#8220;<a href="http://de.wikipedia.org/wiki/Milgram-Experiment" target="_blank">Milgram Experiment</a>&#8221; durchführte) das &#8220;Small World&#8221; Experiment. Milgram erstellte eine Art Informationspaket, das 60 zufällig ausgewählte Teilnehmer an jeweils eine vorher festgelegte Person in Boston zu senden hatten. Als Startpunkte wählte er Personen aus den sozial und geografisch weit von der Zielstadt entfernten Städten Omaha und Wichita. Die Aufgabe der Teilnehmer bestand darin, das Paket nicht direkt an die Zielperson zu senden, sofern sie diese nicht persönlich kannten (bei ihrem Vornamen ansprachen), sondern an eine Person, die sie persönlich kannten und bei der die Wahrscheinlichkeit höher war, dass sie die Zielperson kannte. Gleichzeitig waren die Teilnehmer angehalten, grundlegende Daten über sich selbst in einer Tabelle zu vermerken und eine Postkarte an die Wissenschaftler zu senden, um die Kette nachvollziehbar zu machen. Insgesamt erreichten drei Pakete die Zielpersonen mit einer durchschnittlichen Pfadlänge von 5,5 oder aufgerundet sechs. Die Wissenschaftler schlossen daraus, dass jede Person der US-amerikanischen Bevölkerung von jeder anderen Person der USA durchschnittlich durch sechs Personen getrennt ist oder, andersherum formuliert, durch durchschnittlich sechs Personen erreicht werden kann. In einem zwei Jahre später durchgeführten Experiment mit 296 möglichen Ketten wurden 217 Pakete gestartet und 64 erreichten ihr Ziel.<sup class="reference">[1]</sup> Im Jahre 1970 folgte ein weiterer Versuch, der, neben der Entfernung der Menschen untereinander, auch mögliche Grenzen zwischen ethnisch unterschiedlichen Gruppen untersuchen sollte. Von 270 mit afroamerikanischen Personen als Ziel gestarteten Paketen erreichten 13 % diese Person, während 33 % von wiederum 270 an „weiße“ Personen adressierte Pakete ihr Ziel erreichten.</p></blockquote>
<p>Möchte man jetzt die Verbindung von Person A zu Person B darstellen, läuft man schnell in das &#8220;<a href="http://de.wikipedia.org/wiki/K%C3%BCrzester_Pfad" target="_blank">shortest path problem</a>&#8220;. Um dies zu lösen eignet sich der sogenannte &#8220;<a href="http://de.wikipedia.org/wiki/Algorithmus_von_Dijkstra" target="_blank">Dijkstra-Algorithmus</a>&#8220;. Wie sieht jetzt die Implementierung in PHP aus ? Wir nehmen an wir haben eine Tabelle mit unseren Usern, und eine zweite welche die Verbindungen der User untereinander darstellt (fromid =&gt; toid).</p>
<pre><code class="SQL">CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL auto_increment,
`firstnames` varchar(200) NOT NULL,
`lastname` varchar(200) NOT NULL,
PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=22 ;

CREATE TABLE IF NOT EXISTS `links` (
`link_id` int(11) NOT NULL auto_increment,
`fromid` int(11) NOT NULL,
`toid` int(11) NOT NULL,
PRIMARY KEY  (`link_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=11 ;

</code></pre>
<p>Als erstes brauchen wir den theoretisch längsten Pfad: Dies wäre die Anzahl der User +1. Nächster Schritt - das Basis array, welches die Schritte von Person x zu Person y festlegt, da wir dies aber noch nicht wissen inintialisieren wir das array mit -1 (unbekannter Pfad). Einen Pfad kennen wir jedoch, nämlich den Pfad von $fromid zu $fromid. Dieser hat die Distanz 0.</p>
<pre><code class="php">
	private function _fetchUser(){
		$m_user = new UserModel();
		$this-&gt;_users = $m_user-&gt;fetchAll();
		$this-&gt;_longestPath = $this-&gt;_users-&gt;count()+1;
	}

	private function _buildSkel($fromid){
		if(!$this-&gt;_users){
			$this-&gt;_fetchUser();
		}

		foreach($this-&gt;_users as $user){
			$this-&gt;_nodes[]=$user-&gt;id;
			$this-&gt;_dist[$user-&gt;id]=$this-&gt;_longestPath;
			$this-&gt;_previous[$user-&gt;id]=-1;
		}

		if($fromid&gt;0)
			$this-&gt;_dist[$fromid]=0;
	}
</code></pre>
<p>Jetzt beginnt der Spass, das Suchen des kürzesten Pfades von User A zu User B:</p>
<pre><code class="php">
	private function _findPath($toid){
		$Q = $this-&gt;_nodes;
		while(count($Q)&gt;0){
			$qsize=count($Q);
			$unode = $this-&gt;_findMin($Q);

			if($unode == $toid){
				break; // We have found ToId
			}

			$u = array_search($unode, $Q);
			$Q[$u]=false;

			$Q = array_filter($Q);

			if($qsize == count($Q)){
				throw new Exception("Qsize doesnt shrink!");
			}

			$m_link = new LinksModel();

			$invitees = $m_link-&gt;fetchAll("fromid='$unode'");
			$inviters = $m_link-&gt;fetchAll("toid='$unode'");

			if($invitees-&gt;count()&gt;0)
				$this-&gt;_relaxNeighbors($unode,$invitees,'toid');

			if($inviters-&gt;count()&gt;0)
				$this-&gt;_relaxNeighbors($unode,$inviters,'fromid');

		}
	}

	private function _relaxNeighbors($unode,$neighbors,$col){
		foreach($neighbors as $neighbor){
			$this-&gt;_relax($unode,$neighbor-&gt;$col);
		}
	}

	private function _relax($u,$v){
		if($this-&gt;_dist[$v] &gt; $this-&gt;_dist[$u]+1){
			$this-&gt;_dist[$v]=$this-&gt;_dist[$u]+1;
			$this-&gt;_previous[$v] = $u;
		}
	}

	private function _findMin($nodes){
		$keys = array_keys($nodes);
		$minid = $nodes[$keys[0]];
		$mindist = $this-&gt;_dist[$minid];

		foreach ($keys as $key){
			$tnode = $nodes[$key];
			if($this-&gt;_dist[$tnode] &lt; $mindist){
				$mindist = $this-&gt;_dist[$tnode];
				$minid=$tnode;
			}
		}

		return $minid;

	}
</code></pre>
<p>Wir laufen also unsere Knoten durch und berechnen die Kantenlängen für jeden Knoten. Dabei wird ein bereits bekannter kürzester Weg benutzt und um eine Kante (zu dem jeweils nächsten) Nachfolgeknoten ergänzt. Dadurch entsteht letztendlich eine Baumstruktur, welche die kürzesten Wege von einem Startknoten repräsentiert. Die gesamte Klasse findet sich auf <a title="http://www.cwd.at/shortestpath.phps" href="http://www.cwd.at/shortestpath.phps" target="_blank">http://www.cwd.at/shortestpath.phps</a> Raum für Optimierung gibt es genug. ZB. das Errechnen der Kantenlängen jedes Users zueinander und Speichern in einer Tabelle. Oder aber auch den gesamten <a title="Dijkstra’s shortest path algorithm" href="http://www.artfulsoftware.com/infotree/queries.php?&amp;bw=1680#766" target="_blank">Algorithmus in die Datenbank auszulagern</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cwd.at/2009/05/13/six-degrees-of-seperation-friend-of-a-friend/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
