<?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>Fri, 02 Mar 2012 20:57:07 +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>PHP 5.4 &#8211; Neuerungen für Schreibfaule</title>
		<link>http://www.codenaschereien.de/php/php-5-4-neuerungen-fuer-schreibfaul/</link>
		<comments>http://www.codenaschereien.de/php/php-5-4-neuerungen-fuer-schreibfaul/#comments</comments>
		<pubDate>Fri, 02 Mar 2012 20:57:07 +0000</pubDate>
		<dc:creator>flash</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.codenaschereien.de/?p=288</guid>
		<description><![CDATA[Nachdem PHP 5.4 nun offiziell erschienen ist, möchte ich dieses Ereignis zum Anlass nehmen, ein paar neue Features zu beleuchten. Sicher, PHP 5.4 macht zwar nicht einen so gewaltigen Satz wie es damals von Version 5.2 auf 5.3 gelang. Dennoch &#8230; <a href="http://www.codenaschereien.de/php/php-5-4-neuerungen-fuer-schreibfaul/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Nachdem PHP 5.4 nun offiziell erschienen ist, möchte ich dieses Ereignis zum Anlass nehmen, ein paar neue Features zu beleuchten. Sicher, PHP 5.4 macht zwar nicht einen so gewaltigen Satz wie es damals von Version 5.2 auf 5.3 gelang. Dennoch gibt es viele interessante Neuerungen. Dabei stehen oft Traits im Vordergrund, die ich heute aber nicht behandeln möchte (siehe dazu: <a title="PHP 5.4 - Traits" href="http://www.codenaschereien.de/php/traits-was-soll-das-alles/" target="_blank">http://www.codenaschereien.de/php/traits-was-soll-das-alles/</a>). Werfen wir also einen Blick auf die Kleinigkeiten, die uns als PHP-Programmierer zukünftig das Leben nicht nur in Sonderfällen, sondern im täglichen Doing, erleichtern sollen.<br />
<span id="more-288"></span><br />
<strong>Zugriff auf Klassenmember während der Instantiierung</strong></p>
<p>Schreibfaule kamen bisher einfach nicht auf Ihre Kosten:</p>
<pre class="brush:php">$o = new Obj();
$o-&gt;doSomething(); //two lines needed</pre>
<p>Damit ist nun glücklicherweise Schluss. PHP 5.4 räumt mit diesen Eigenheiten auf und erlaubt das folgende Konstrukt:</p>
<pre class="brush:php">(new Obj())-&gt;doSomething();</pre>
<p>Super! Das spart Codezeilen und wirkt auch nicht mehr so angestaubt. Sicherlich ist es auch ein wenig Geschmackssache &#8211; mich überzeugt es aber.</p>
<p><strong>Änderungen bei Arrays:</strong></p>
<p>Auch bei Arrays ist ab sofort weniger Tipparbeit nötig. Dies macht sich vor allem bei Funktionen bemerkbar, die Arrays zurückgeben. Gegeben sei folgende Funktion:</p>
<pre class="brush:php">function getArray() {
  return array(1,2,3);
}</pre>
<p>Bisher musste man Folgendes schreiben, um auf den ersten Wert des Rückgabearrays zugreifen zu können:</p>
<pre class="brush:php">$arr = getArray();
echo $arr[0]</pre>
<p>PHP 5.4 räumt auch hier auf und bietet die folgende Möglichkeit an:</p>
<pre class="brush:php">echo getArray()[0];</pre>
<p>Außerdem gibt es eine Kurzschreibweise für die Initialisierung von Arrays:</p>
<pre class="brush:php">$arr = [1,2,3,4];</pre>
<p>getArray() könnte damit also auch so aussehen:</p>
<pre class="brush:php">function getArray() {
  return [1,2,3,4];
}</pre>
<p><strong>Typehints</strong></p>
<p>Leider zog nicht das Feature ein, auch skalare Typen als Typehints benutzen zu können. Zwischenzeitlich wurde zwar viel darüber diskutiert &#8211; letztendlich wurde es aber wieder verworfen. Dennoch gibt es auch hier eine sinnvolle Ergänzung namens &#8220;callable&#8221;. Damit kann eine Funktion vorraussetzen, dass ein übergebener Parameter aufrufbar ist. Jetzt kann man behaupten: Das hat vorher doch auch schon mit dem Closure-Typehint funktioniert:</p>
<pre class="brush:php">function callme(Closure $c) {
  $c();
}</pre>
<p>Richtig, es gibt nur ein Problem mit built-in-Funktionen. Diese müssen nämlich in einem Closure &#8220;gewrapped&#8221; werden &#8211; denn Strings akzeptiert der Closure-Typehint nicht:</p>
<pre class="brush:php">callme(function() { flush(); });</pre>
<p>Nun geht das auch einfacher:</p>
<pre class="brush:php">function callme(callable $c) {
  c();
}

callme('flush');</pre>
<p><strong>Closures</strong></p>
<p>Bleiben wir bei Closures, denn hier gibt es eine weitere, interessante Neuerung. Man kann nun $this in Closures verwenden, wenn man PHP mitteilt, was das aktuelle Objekt ist:</p>
<pre class="brush:php">class T {
  public function init() {
    $obj = $this;
    $c = function() use ($obj) {
      $this-&gt;doSomething();
    };
    $c();
  }

  private function doSomething() {
    echo __METHOD__;
  }
}

$t = new T();
$t-&gt;init();</pre>
<p>Interessant dabei ist vor allem der Zugriff auf objektinterne Methoden, was wir im obigen Beispiel am Schlüsselwort <em>private</em> erkennen können.</p>
<p><strong>Callbacks</strong></p>
<p>Von Closures zu Callbacks. Diese können nun endlich auch ohne call_user_func() aufgerufen werden:</p>
<pre class="brush:php">class T {
  public function doSomething() {
    echo __METHOD__;
  }
}

$t = new T();
$callback = array($t, 'doSomething');
$callback();</pre>
<p><strong>Fazit:</strong></p>
<p>In diesem Artikel habe ich versucht vor allem jene Features herauszustellen, die einem vor allem Schreibarbeit ersparen oder die Lesbarkeit des Codes erhöhen. Sicherlich wird man davon nicht alle im täglichen Gebrauch verwenden können. Als nützlich erscheinen die Neuerungen für mich aber allemal und ich werde sie mir im Hinterkopf behalten.</p>
<p><strong>Links</strong></p>
<p>https://wiki.php.net/rfc/instance-method-call</p>
<p>https://wiki.php.net/rfc/callable</p>
<p>https://wiki.php.net/rfc/shortsyntaxforarrays</p>
]]></content:encoded>
			<wfw:commentRss>http://www.codenaschereien.de/php/php-5-4-neuerungen-fuer-schreibfaul/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<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>
	</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 353/382 objects using apc

Served from: www.codenaschereien.de @ 2012-05-19 13:07:03 -->
