<?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>codenaschereien.de</title>
	<atom:link href="http://www.codenaschereien.de/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.codenaschereien.de</link>
	<description>flash&#039;s PHP Blog</description>
	<lastBuildDate>Wed, 18 Jan 2012 21:23:15 +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>Operatoren und Vergleiche</title>
		<link>http://www.codenaschereien.de/php/operatoren-und-vergleiche/</link>
		<comments>http://www.codenaschereien.de/php/operatoren-und-vergleiche/#comments</comments>
		<pubDate>Tue, 10 Jan 2012 21:59:07 +0000</pubDate>
		<dc:creator>flash</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.codenaschereien.de/?p=351</guid>
		<description><![CDATA[Ein Artikel über Operatoren und Vergleiche? &#8211; Die meisten von uns kennen wohl den Unterschied zwischen == und ===. Und dennoch sieht man selbst bei erfahrenen PHP-Programmierern immer wieder der Situation unangemessene Implementierungen. Schauen wir uns daher ein paar Sonderfälle &#8230; <a href="http://www.codenaschereien.de/php/operatoren-und-vergleiche/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Ein Artikel über Operatoren und Vergleiche? &#8211; Die meisten von uns kennen wohl den Unterschied zwischen == und ===. Und dennoch sieht man selbst bei erfahrenen PHP-Programmierern immer wieder der Situation unangemessene Implementierungen. Schauen wir uns daher ein paar Sonderfälle an.<br />
<span id="more-351"></span><br />
<strong>Äquivalenzrelation</strong></p>
<p>Eventuell erinnert sich mancher Leser noch an sein Informatik-Grundstudium. Dort wurde dann ggfs. gelehrt, was man unter einer Äquivalenzrelation zu verstehen hat. Der Vergleichsoperator == erfüllt in PHP die Bedingungen einer solchen nicht (im Gegensatz zu ===). Diese drei Bedingungen lauten wie folgt:</p>
<ul>
<li>Reflexivität (z.B. a ist gleich zu sich selbst)</li>
<li>Symmetrie (z.B. a ist gleich b und umgekehrt)</li>
<li>Transitivität (z.B. a = b und b = c, dann ist a = c)</li>
</ul>
<p>Schlagen wir den Bogen zu PHP. Dazu ein zunächst funktionierendes, kleines Beispiel für die einfache Gleichheitsrelation:</p>
<pre class="brush:php">//Initialisierungen
$a = $b = $c = 5;

//Aequivalenzrelation?
var_dump($a == $a); //=&gt; true =&gt;Reflexivitaet
var_dump($a == $b &amp;&amp; $b == $a); //=&gt; true =&gt; Symmetrie
var_dump($a == $b &amp;&amp; $b == $c &amp;&amp; $a == $c);
//=&gt;true =&gt; Transitivitaet</pre>
<p>Das sieht doch soweit eigentlich ganz gut aus, aber:</p>
<pre class="brush:php">//Initialisierungen
$a = false;
$b = '0';
$c = '';

//Aequivalenzrelation?
var_dump($a == $a); //=&gt; true =&gt; Reflexivitaet
var_dump($a == $b &amp;&amp; $b == $a); //=&gt; true =&gt; Symmetrie
var_dump($a == $b &amp;&amp; $b == $c &amp;&amp; $a == $c);
//=&gt; false =&gt; keine Transitivitaet!</pre>
<p>Der letzte var_dump() liefert ein false, aufgrund von $a == $c. Denn in PHP ist der Leerstring &#8221; unter Benutzung des einfachen Gleichheitsoperators ==, nicht gleich &#8217;0&#8242;. Prüft man auf leere Strings, sollte man sich dieses Verhalten immer vor Augen führen. Für mich ist nämlich auch &#8217;0&#8242; ein korrekter String. Dies birgt so manche Gefahr. Ein&#8230;</p>
<pre class="brush:php">if($str) { /* some code */ }</pre>
<p>&#8230;sollte für Strings daher grundsätzlich tabu sein, wenn man ermitteln möchte, ob der jeweilige String einen Wert enthält &#8211; soweit man nicht explizit mit dem oben genannten Verhalten rechnet.</p>
<p>Aber wie richtig prüfen? Viele werden nun an isset() oder empty() denken. Nein, meine Lösung sieht so aus:</p>
<pre>$mystring = ???;
if('' != $mystring) {
  /* some code here */
}</pre>
<p>Diese Bedingung erfüllt meiner Meinung nach alles, was benötigt wird:</p>
<ul>
<li>einfacher Code, der niemanden verwirrt</li>
<li>null wird korrekt behandelt</li>
<li>Der Leerstring &#8221; wird korrekt behandelt</li>
<li>&#8217;0&#8242; wird als true interpretiert</li>
</ul>
<p>Da $mystring bereits vorher gesetzt wurde, ist auch kein isset() nötig (dazu später noch mehr).</p>
<p><strong>Implizite Typkonversion</strong></p>
<p>Der Vorteil des obigen Codes ist die impliziete Typconversion &#8211; erzielt durch zwei, statt drei Gleichheitszeichen. Für den Vergleich müssen beide Seiten auf den selben Typ gebracht werden. D.h. die rechte Seite wird in diesem speziellen Fall (dazu später mehr) auf den Typ der linken, einen String gebracht. Das kann man mit einem kleinen Beispiel schnell nachvollziehen:</p>
<pre class="brush:php">class T {
  public function __toString() {
    echo 'Konvertierung!';
    return 'test';
  }
}

$t = new T();
if('' != $t) {
  /* do something */
}

//Ausgabe: Konvertierung!</pre>
<p>Demnach wird die Vergleichsvariable durch die Konvertierung zum String. Bei Nutzung von === wird die Typkonversion hingegen übergangen. Ist der Typ nicht der gleiche, wird der Rest der Prüfung nicht mehr durchgeführt.</p>
<p>Weiter oben hatte ich von einem &#8220;speziellen Fall&#8221; geschrieben. Denn die Konvertierungsvorschrift hängt von den Typen der Operanden ab:</p>
<ul>
<li>Sind beide Operanden Strings oder null, wird ein String-Vergleich durchgeführt.</li>
<li>Ist einer der beiden Operanden ein boolscher Wert, wird der andere auf den Typ bool gebracht.</li>
<li>In den anderen Fällen, werden die Operanden in Zahlen umgewandelt.</li>
</ul>
<p>Zugegebenermaßen muss man sich nun noch über Arrays und wie in unserem obigen Fall über Objekte unterhalten. Letzere kann man aber eh nur nach bool oder String casten. Demnach macht eine Konvertierung zu String in unserem Beispiel den größten Sinn und widerspricht auch den obigen Regeln nicht. Denn keiner der Operanden ist vom Typ bool und in einen int/double/float kann das Objekt nicht umgewandelt werden &#8211; es bleibt nur der Typ string übrig.</p>
<p>Nun zu Arrays. Hier ist die Sache deutlich undurchsichtiger, nachdem Arrays in alle skalaren Typen gecastet werden können. Den String-Vergleich kann man aber schon mal ausschließen:</p>
<pre class="brush:php">var_dump('Array' == array()); //=&gt; false</pre>
<p>Arrays sind bei Vergleichen aber sowieso eine Besonderheit. Auf ein true im Vergleich kann man nur kommen, wenn&#8230;</p>
<ul>
<li>&#8230;einer der Operanden ein bool ist.</li>
<li>&#8230;man das Arrays mit null vergleicht, soweit es keine Werte enthält.</li>
<li>&#8230;man das Array mit sich selbst vergleicht.</li>
</ul>
<p>Wer sich die Sache nun noch genauer ansehen möchte, sieht sich am Besten mal die &#8220;Type Conversion Tables&#8221; an: http://php.net/manual/de/types.comparisons.php<br />
Die dortige Auflistung kann man auf jeden Fall immer benutzen, wenn man sich unsicher ist. Objekt-Vergleiche werden hier allerdings nicht aufgelistet.</p>
<p><strong>empty()</strong></p>
<p>Ich weiß ja nicht wie es Euch so geht, aber ich finde empty() evil. Es hat das gleiche Problem wie ein if($str). Hier waren die PHP-Entwickler konsequent und haben auch &#8217;0&#8242; eingeschlossen. Beispiel:</p>
<pre class="brush:php">$a = '0';
if(!empty($a)) { /* some code */ }</pre>
<p>Leider landet man damit auch nicht in &#8220;some code&#8221;. Vielleicht reite ich ja ein wenig darauf herum, aber &#8217;0&#8242; ist für mich nunmal auch ein gültiger String und oftmals eine valide Benutzereingabe. empty() ist außerdem immer so eine Art blackbox. Was ist nochmal genau &#8220;empty&#8221;? &#8211; Wer muss da nicht des öfteren nachschauen? Das macht den Code somit weniger leser-/wartungsfreundlich.</p>
<p>Darüber hinaus ist empty ein Sprachkonstrukt und keine richtige Funktion. Es kann nur Variablen verarbeiten. Konstanten (hierbei spielt es keine Rolle, ob diese per &#8220;const&#8221; oder &#8220;define&#8221; deklariert wurden) können deshalb nicht an empty übergeben werden.</p>
<p><strong>isset()</strong></p>
<p>Dann wäre da noch isset(). Hierbei ist das Problem nicht &#8217;0&#8242;, sondern der Leerstring &#8221;. Scheinbar glauben noch immer viele Entwickler daran, isset() prüfe auf diesen. Das ist nicht der Fall. Ein&#8230;</p>
<pre class="brush:php">if(isset($a)) { /* some code */ }</pre>
<p>ist bei skalaren Werten und Arrays absolut identisch zu&#8230;</p>
<pre class="brush:php">if(null !== $a) { /* some code */ }</pre>
<p>und daher nicht mit einem String-Vergleich auf den Leerstring zu verwechseln (man beachte die 2 Gleichheitszeichen). Der Vergleich zwischen den beiden Codeschnipseln hinkt jedoch an zwei Stellen:</p>
<ul>
<li>isset() erzeugt im Gegensatz zu null !== $a keine Warnung &#8211; falls $a vorher im Code noch nie schreibend genutzt wurde.</li>
<li>isset() kann mehere Parameter auf einmal berücksichtigen</li>
<li>(isset() kann innerhalb von Objekten __isset() nutzen &#8211; daher habe ich &#8220;skalaren Werten und Arrays&#8221; geschrieben)</li>
</ul>
<p>Der Vorteil der nicht ausgegebenen Warnung relativiert sich in einem Spezialfall aber wieder, wenn man sich folgendes Beispiel vor Augen hält:</p>
<pre>$a = null;
var_dump($a);
var_dump(isset($a));
var_dump($b);
var_dump(isset($b));</pre>
<p>Interessanterweise erzeugt der Zugriff auf $a keine Warnung, der auf $b schon. Gesetzt sind laut isset() dennoch beide Variablen nicht. Das muss wohl daran liegen, dass Variablen ab dem Zeitpunkt der ersten Zuweisung im Code in die Symboltabelle aufgenommen werden &#8211; selbst wenn deren Wert gleich null ist.</p>
<p>Ein weiterer Mythos besteht wohl durch den Namen der Funktion:</p>
<pre>$a = null;
$b = $a;
var_dump(isset($b)); //-&gt;liefert false</pre>
<p>Obwohl man laut dem Funktionsnamen von isset() eigentlich davon ausgehen möchte, dass $b gesetzt ist, wird false zurückgegeben. Für $b wurde doch eine Zuweisung durchgeführt!? $b ist jedoch laut isset() auch nach dieser nicht gesetzt. Wer es nicht glaubt, kann es gerne mal ausprobieren <img src='http://www.codenaschereien.de/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>Denke ich nun noch einmal an den String-Vergleich von oben, müsste aufgrund der neu erungenen Erkentnisse der Code also doch so lauten:</p>
<pre>if(isset($mystring) &amp;&amp; '' != $mystring) {
  /* some code here */
}</pre>
<p>Ich vermeide diese Schreibweise dennoch. Das isset gehört für mich nur einfach an eine andere Stelle im Code. Wenn wir speziell $_POST/$_GET/$_REQUEST betrachten, können wir schlichtweg einfach nicht sicher sein, ob die Variable auch wirklich gesetzt ist. I.d.R. arbeite ich aber auch nicht mit $_POST[‘xyz'], sondern einer zentralen Methode, die diese Variable dann zurückgibt (z.B. im Zend-Framework). Dann benötigt man automatisch eine weitere Variable wie beispielsweise $xyz = $abc-&gt;getPost(&#8216;xyz&#8217;), wodurch eine Warnung verhindert wird. Die Idealversion ohne Framework sieht für Strings daher für mich so aus:</p>
<pre>//somewhere on top
$mystring = isset($_POST['mystring'])
            ? $_POST['mystring'] : '';
...
//somewhere else
if('' != $mystring) {
  /* some code */
}</pre>
<p>Die korrekte Initialisierung von Variablen gehört irgendwo an den Anfang und sollte nicht durch einen isset()-Aufruf in jeder if-Abfrage erneut geprüft werden.</p>
<p><strong>XOR</strong></p>
<p>Das &#8220;Entweder oder&#8221; benutzt man doch häufiger als man denkt. Oft sieht es so im Code aus:</p>
<pre class="brush:php">$input = 'einstring';

if (
  ( strpos($input, 'ein') !== false &amp;&amp;
    strpos($input, 'string') === false
  )
  ||
  ( strpos($input, 'string') !== false &amp;&amp;
    strpos($input, 'ein') === false
  ) ) {
  /* some code here*/
}</pre>
<p>Das man die Stringprüfung ggfs. anders lösen kann, sei hier mal dahingestellt. Wichtig ist mir eigentlich nur, dass durch die Verwendung des XOR-Operators alles viel einfacher aussieht und man diese Lösungsmöglichkeit oft vergisst:</p>
<pre>if( strpos($input, 'ein') !== false XOR
    strpos($input, 'string') !== false {

  /* some code */
}</pre>
<p><strong>Fazit</strong></p>
<p>Vergleiche können so einfach sein <img src='http://www.codenaschereien.de/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  Es gibt jedoch einige Fallstricke wie die angesprochenen &#8217;0&#8242;-Werte in Strings, die man nicht außer Acht lassen sollte. Der === ist manchmal sogar kontraproduktiv. Zudem ist schöner Code oft unkompliziert! &#8211; PHP bietet hierfür viele Implementierungsvarianten.</p>
<p><strong>Links</strong></p>
<p>http://de.wikipedia.org/wiki/%C3%84quivalenzrelation</p>
<p>http://de.php.net/isset</p>
<p>http://de.php.net/__isset</p>
<p>http://de.php.net/empty</p>
]]></content:encoded>
			<wfw:commentRss>http://www.codenaschereien.de/php/operatoren-und-vergleiche/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Das fehlende Synchronize</title>
		<link>http://www.codenaschereien.de/php/das-fehlende-synchronize/</link>
		<comments>http://www.codenaschereien.de/php/das-fehlende-synchronize/#comments</comments>
		<pubDate>Sun, 11 Dec 2011 16:46:01 +0000</pubDate>
		<dc:creator>flash</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.codenaschereien.de/?p=299</guid>
		<description><![CDATA[PHP bietet von Haus aus leider nur wenig Features für parallele Datenverarbeitung an. Nebenläufigkeit ist oftmals kein Thema, da sie häufig vom Webserver übernommen wird. Natürlich gibt es auch das Modul PCNTL (siehe http://de3.php.net/manual/en/ref.pcntl.php, das es erlaubt per pcntl_fork() Kind-Prozesse &#8230; <a href="http://www.codenaschereien.de/php/das-fehlende-synchronize/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>PHP bietet von Haus aus leider nur wenig Features für parallele Datenverarbeitung an. Nebenläufigkeit ist oftmals kein Thema, da sie häufig vom Webserver übernommen wird. Natürlich gibt es auch das Modul PCNTL (siehe <a title="pcntl" href="http://de3.php.net/manual/en/ref.pcntl.php">http://de3.php.net/manual/en/ref.pcntl.php</a>, das es erlaubt per <em>pcntl_fork()</em> Kind-Prozesse zu erstellen. Jedoch muss man auch hier schauen, wie man die Nebenläufigkeit synchronisiert bekommt. Stellt man sich z.B. einen Webservice vor, der eine kritische Funktion für einen Benutzer nur nacheinander ausführen darf, muss man zugegebenermaßen als PHP-Programmierer neidisch in die Java-Ecke blicken, in der Entwickler das Problem mit dem Schlüsselwort <em>synchronize</em> leicht lösen können. Zusätzlich hält die Java-Welt seit Version 5.0 mit dem Paket java.util.concurrent einen ganzen Sack weiterer Tools bereit, die einem das Leben erleichtern.<br />
<span id="more-299"></span><br />
<strong>Datei-Locks</strong></p>
<p>PHP ist hier leider etwas mager bestückt. Oft helfen sich Programmierer daher mit flock() und generieren ein exklusives Lock per Datei. Das funktioniert oft auch ganz gut. Flock garantiert allerdings keineswegs, das es das Locking auch sicher durchführen kann. Wer sich allein die Warnings in den Notes ansieht (siehe <a title="flock" href="http://de.php.net/manual/en/function.flock.php">http://de.php.net/manual/en/function.flock.php</a>), stellt schnell fest, dass es hier einige Fallstricke gibt. Man ist vor allem abhängig vom Dateisystem. Hat man beispielsweise mehrere Webserver, die ein NFS-Share nutzen, wird es komplizierter. Exklusive Locks funktionieren auf NFS-Shares nicht. Es gibt zwar speziell für NFS einen Workaround mit statischen Links. Eine wirkliche Unabhängigkeit vom Dateisystem hat man damit aber nicht geschaffen.</p>
<p><strong>APC</strong></p>
<p>Ein Locking mit dem APC-Cache ist grundsätzlich möglich. Folgendes, rundimentäres Beispiel zeigt, wie es aussehen könnte:</p>
<pre class="brush:php">&lt;?php
  define('MYLOCK', 'mylock');

  echo 'acquire lock...';
  ob_flush();
  flush();
  $i = 0;
  while(false === apc_add(MYLOCK, 1)) {
    usleep(100);
  }

  echo "done\n";
  ob_flush();
  flush();
  sleep(5); //something else can be done here
  echo 'release lock...';
  apc_delete(MYLOCK);
  echo "done\n";</pre>
<p>Über den Webserver ausgeliefert, funktioniert das auch soweit. Man kann das Skript mehrmals starten und dann kann man verfolgen, ab wann das Lock vergeben wird. Dabei darf man nicht vergessen, dass die meisten Browser den Output puffern. Am einfachsten testet man es daher mit telnet:</p>
<pre class="brush:shell">telnet servername 80
Trying 1.2.3.4...
Connected to servername.
Escape character is '^]'.
GET /test.php
acquire lock...done
release lock...done
Connection closed by foreign host.</pre>
<p>ob_flush() und flush() sorgen dabei noch zusätzlich dafür, dass der Output nicht auf der Server-Seite gepuffert wird. Geht das auch auf der Kommandozeile? &#8211; Nein! Zwar kann man hier mit dem Setting <em>&#8220;apc.enable_cli = 1&#8243; </em>für die PHPCLI-Ini APC einschalten. Das Lock wird dann jedoch nicht funktionieren. Anders als bei Apache, läuft jedes Kommandozeilenskript für sich und ohne gemeinsam verwendeten Speicher ab. Das trifft auch für APC zu. Deshalb ist diese Methode für Konsolenskripte ungeeignet. Außerdem funktioniert sie auch nicht, wenn man mehrere Webserver im Einsatz hat. Denn jede Apache-Instanz hat ihren eigenen APC.</p>
<p><strong>Semaphore</strong></p>
<p>Auch wenn die Funktionen etwas rar gesäht sind, hält PHP jedoch auch das ein oder andere (fast) von Haus aus mitgebrachte Feature bereit (Modulinstallation ist wieder nötig). Semaphore sind beispielsweise eine aus der Betriebssystemwelt stammende Begrifflichkeit. Diese gibt es auch in PHP: <a title="PHP Semaphore" href="http://de.php.net/manual/en/book.sem.php">http://de.php.net/manual/en/book.sem.php</a>. Ein simples Beispiel:</p>
<pre class="brush:php">&lt;?php

  define('MYSEMAPHORE', 1);

  $semaphore = sem_get(MYSEMAPHORE);
  echo 'sem_acquire...';
  sem_acquire($semaphore);
  echo "done\n";
  sleep(5); //something else can be done here
  echo 'sem_release...';
  sem_release($semaphore);
  echo "done\n";</pre>
<p>Die &#8220;flushes&#8221; habe ich mir hier gespart. Leider lösen Semaphore auch nicht das Problem, wenn man mehrere Webserver im Einsatz hat.</p>
<p><strong>Memcache</strong></p>
<p>Die letzte und mir am sinnvollsten erscheinende Lösung ist die Memcache-Lösung. Sie funktioniert genau wie der APC-Ansatz, nur mit dem Unterschied, dass der Memcache-Server auch über die Konsole und mehrere Webserver hinweg funktioniert. Dabei muss man sich klar machen: Memcached ist single-threaded. D.h. erfolgt ein Hinzufügen eines Keys, kann das nicht parallel stattfinden. Die Anfragen werden sozusagen serialisiert. Dies kann man sich für ein Lock zu Nutze machen:</p>
<pre class="brush:php">&lt;?php

  define('MYLOCK', 'mylock');

  echo 'acquire lock...';
  $memcache = memcache_connect("localhost", 11211);
  while(false === $memcache-&gt;add(MYLOCK, 1)) {
    usleep(100);
  }
  echo "done\n";
  sleep(5); //something else can be done here
  echo 'release lock...';
  $memcache-&gt;delete(MYLOCK);
  echo "done\n";</pre>
<p>Genau wie bei dem APC-Vorschlag muss man sich auch hier Gedanken über mögliche Endlosschleifen und Deadlocks machen. Erstere könnte man mit einem Timeout in der While-Schleife, oder auch einfach mit einer Max-Life-Time des jeweiligen Keys verhindern. Dabei muss man die maximale Laufzeit des Skripts zwischen dem Akquirieren und dem Freigeben des Locks berücksichtigen &#8211; sonst hat man genau die gleichen Probleme wie ohne Locks. Zudem können beispielsweise Verbindungsprobleme zum Memcache-Server auftreten. Dann kann das Hinzufügen eines Keys länger dauern als erwartet und somit die Ausführungsdauer steigern. Mit vernünftigen Max-Lifetimes hat man aber ein gutes Steuerungsinstrument in der Hand. Benötigt ein einfaches DB-Update beispielsweise mehr als 5 Minuten, hat man eh ganz andere Probleme.</p>
<p>Weiterhin kann man sich überlegen, die Werte der Keys mit etwas sinnvollem zu füllen: Welcher/Welches Webserver/Prozess/Skript hat das Log geschrieben? Darf es nur derjenige Prozess freigeben, der es auch erstellt hat? Es gibt sicherlich noch viele Optimierungsmöglichkeiten bei der Memcache-Version&#8230; Ideen als Kommentar sind daher sehr willkommen.</p>
<p><strong>Zend-Framework</strong></p>
<p>Auch im Zend-Framework kann man das Memcache-Lock nutzen. Allerdings ist der Einbau nicht ganz trivial. Denn <em>Zend_Cache_Backend_Memcached</em> benutzt leider statt der add()-  die save()-Methode. Das hat zur Folge, dass kein Fehler auftritt, wenn der zu speichernde Key bereits vorhanden ist &#8211; das ist unbrauchbar für Locks.</p>
<p>Abhilfe schafft nur das Hinzufügen einer add()-Methode in einer von Zend_Cache_Backend_Memcached abgeleiteten Klasse. Je nachdem, wo man sein Backend initialisiert muss die Factory-Methode von Zend_Cache dann neue Parameter erhalten (nachfolgend der Prototyp der factory-Methode):</p>
<pre class="brush:php">factory(
  mixed $frontend,
  mixed $backend,
  array $frontendOptions = array,
  array $backendOptions = array,
  boolean $customFrontendNaming = false,
  boolean $customBackendNaming = false,
  boolean $autoload = false
)</pre>
<p>$backend muss dann auf den neuen Backendnamen verweisen und $customBackendNaming muss auf true gesetzt werden. Damit nicht genug. Auch das Frontend will angepasst werden &#8211; denn hier existiert die neue add()-Methode auch nicht. Die Anpassung kann aber analog zum Backend erfolgen. Wer sich die Tortur angetan hat, kann sich immerhin über exklusive Locks per Memcached freuen, die Zend-Framework-kompatibel sind <img src='http://www.codenaschereien.de/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p><strong>Fazit:</strong></p>
<p>Auch in PHP können exklusive, verlässliche Locks mit ein wenig Handarbeit nachgerüstet werden. Ein wenig Gehirnschmalz muss man in die Implementierung aber stecken, um für Deadlocks und Co. gewappnet zu sein. Ich würde mir wünschen, dass solch grundlegende Funktionen zumindest ins Zend-Framework einzug halten und man keine komplizierten Implementierungen dafür benötigt.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.codenaschereien.de/php/das-fehlende-synchronize/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using apc
Page Caching using apc
Database Caching using apc
Object Caching 268/384 objects using apc

Served from: www.codenaschereien.de @ 2012-02-23 01:55:11 -->
