<?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>ebene7 &#187; Array</title>
	<atom:link href="http://blog.ebene7.com/schlagwort/array/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.ebene7.com</link>
	<description></description>
	<lastBuildDate>Tue, 04 Jun 2013 18:57:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>&#8220;Walkable&#8221; Iterator</title>
		<link>https://blog.ebene7.com/2012/07/31/walkable-iterator/</link>
		<comments>https://blog.ebene7.com/2012/07/31/walkable-iterator/#comments</comments>
		<pubDate>Tue, 31 Jul 2012 04:00:00 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Array]]></category>
		<category><![CDATA[Design Patterns]]></category>
		<category><![CDATA[each]]></category>
		<category><![CDATA[Foreach]]></category>
		<category><![CDATA[Iterator]]></category>
		<category><![CDATA[Schleife]]></category>
		<category><![CDATA[Visitor Pattern]]></category>
		<category><![CDATA[walk]]></category>

		<guid isPermaLink="false">http://blog.ebene7.com/?p=3499</guid>
		<description><![CDATA[In PHP haben Entwickler seit Version 5 die Möglichkeit, den Zugriff auf Datenstrukturen durch eigene oder bereits in der SPL vorhandene Iteratoren zu kontrollieren. Das ist einfach und hat sicherlich auch schon jeder einmal gemacht. Damit ist dann zumindest der &#8230; <a href="https://blog.ebene7.com/2012/07/31/walkable-iterator/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In PHP haben Entwickler seit Version 5 die Möglichkeit, den Zugriff auf Datenstrukturen durch eigene oder bereits in der <a href="http://www.php.net/~helly/php/ext/spl/" target="_blank">SPL</a> vorhandene <a href="http://blog.ebene7.com/schlagwort/iterator/">Iteratoren</a> zu kontrollieren. Das ist einfach und hat sicherlich auch schon jeder einmal gemacht.</p>
<p>Damit ist dann zumindest der eine Teil, die Datenstruktur, für sich gekapselt. Was ist aber mit dem Teil, den wir wahrscheinlich häufiger verwenden werden? Wir nutzen Iteratoren in Schleifen und machen irgendwas mit den Elementen.<span id="more-3499"></span></p>
<pre>&lt;?php
foreach($list as $key =&gt; $item) {
  $item-&gt;doSomething();
}

// oder
$values = array();
foreach($list as $key =&gt; $item) {
  $values[] = $item-&gt;getSomething();
}</pre>
<p>In verschiedenen anderen Sprachen, Java, JavaScript etc., sieht man häufig, dass dort auch die Scheifen gekapselt sind. Warum probieren wir das nicht auch mal in PHP?</p>
<p>Ich werde das Beipiel bewusst einfach halten und wie gewohnt auf einige Fehlerbehandlungen verzichten, um den Code übersichtlich zu halten.</p>
<p>Als erstes erstellen wir eine Klasse &#8220;WalkableIterator&#8221; und lassen diese von ArrayIterator erben. Die beiden Methoden &#8220;each&#8221; und &#8220;walk&#8221; bilden später unsere beiden Beispiele ab.</p>
<pre>&lt;?php
class WalkableIterator extends ArrayIterator {
  public function each($method) {}
  public function walk($callback) {}
}</pre>
<p>Mit each() können wir eine bestimmte Methode auf jedem Element in unserem Iterator aufrufen. Dafür müssten hier natürlich diverse Fehlerbehandlungen rein was passieren soll, wenn das Element kein Objekt ist oder die Methode nicht existiert oder diese gar eine Exception wirft.</p>
<pre>&lt;?php
class WalkableIterator extends ArrayIterator {
  public function each($method) {
    $args = func_get_args();
    $method = array_shift($args);
    foreach($this as $item) {
      call_user_func_array( array($item, $method), $args );
    }
  }
  // ...
}</pre>
<p>Das ganze ist denkbar einfach: Die Methode nimmt als ersten Pflichtparameter den Methodennamen entgegen, die auf allen Elementen aufgerufen werden soll und der Rest bleibt flexibel und wird einfach nur durchgereicht.</p>
<p>Die Implementierung von walk() wird sogar noch einfacher, da hier keine Parameter weitergegeben werden müssen. Im produktiven Einsatz müssten auch hier noch die üblichen Fehlerbehandlungen rein.</p>
<pre>&lt;?php
class WalkableIterator extends ArrayIterator {
  // ...
  public function walk($callback) {
    foreach($this as $item) {
      call_user_func( $callback, $item );
    }
  }
}</pre>
<p>Soweit, so einfach&#8230; Was können wir jetzt damit machen? Bauen wir ein kleines Beispiel.</p>
<pre>&lt;?php
// Testklasse
class Person {
  private $name;
  public function __construct($name = 'unnamed') {
    $this-&gt;setName($name);
  }
  public function getName() {
    return $this-&gt;name;
  }
  public function setName($name) {
    $this-&gt;name = $name;
  }
}

// Testarray mit Objekten befüllen
$a = array();
for($i=1; $i &lt;= 10; $i++) {
  $a[] = new Person('Person ' . $i);
}

// Iterator erstellen und Namen ausgeben
$it = new WalkableIterator($a);

foreach($it as $item) {
  echo $item-&gt;getName() . '&lt;br/&gt;';
}

// Person 1
// ...
// Person 10</pre>
<p>Wollten wir nun allen Personenobjekten einen Namen geben, so könnten wir dafür each() verwenden.</p>
<pre>&lt;?php
$it-&gt;each('setName', 'PHP-Nerd');

// PHP-Nerd
// ...
// PHP-Nerd</pre>
<p>Wollen wir unsere Personen dann vielleicht doch wieder individueller benennen, so könnten wird das mit walk() und einem <a href="http://blog.ebene7.com/schlagwort/callback/">Callback</a> machen.</p>
<pre>$callback = function(Person $person) {
  static $count = 1;
  $person-&gt;setName( $person-&gt;getName() . ' ' . $count++ );
};

$it-&gt;walk($callback);</pre>
<pre>// PHP-Nerd 1
// ...
// PHP-Nerd 10</pre>
<p>&#8220;Was bringt uns das und warum so kompliziert?&#8221;, ist in dem Zusammenhang eine oft gehörte Frage.</p>
<p>Zunächst ist die Implementierung, wie das Beispiel sicher beweist, nicht kompliziert.</p>
<p>Die Vorteile sind kürzere Aufrufe im Code, weil wir keine Schleifen mehr schreiben müssen und durch die Kapselung verbessert sich auch die Wart- und Testbarkeit. Der Code existiert nur an einer Stelle und funktioniert überall nach dem selben Muster.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.ebene7.com/2012/07/31/walkable-iterator/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>CSV-Datei sortieren ganz einfach</title>
		<link>https://blog.ebene7.com/2010/07/28/csv-datei-sortieren-ganz-einfach/</link>
		<comments>https://blog.ebene7.com/2010/07/28/csv-datei-sortieren-ganz-einfach/#comments</comments>
		<pubDate>Wed, 28 Jul 2010 18:15:32 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Grundlagen]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Snippets]]></category>
		<category><![CDATA[Array]]></category>
		<category><![CDATA[CSV]]></category>
		<category><![CDATA[Sortierung]]></category>

		<guid isPermaLink="false">http://blog.ebene7.com/?p=1160</guid>
		<description><![CDATA[Heute hatte ich im Büro ein lustiges Gespräch darüber, wie einfach es ist eine CSV-Datei alphabetisch zu sortieren und dass das passende Script als inline (also alles in einer Zeile) in unter zehn Minuten geschrieben ist. Zeitlich war das wie &#8230; <a href="https://blog.ebene7.com/2010/07/28/csv-datei-sortieren-ganz-einfach/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Heute hatte ich im Büro ein lustiges Gespräch darüber, wie einfach es ist eine CSV-Datei alphabetisch zu sortieren und dass das passende Script als inline (also alles in einer Zeile) in unter zehn Minuten geschrieben ist.<span id="more-1160"></span></p>
<p>Zeitlich war das wie erwartet locker drin, nur leider klappte das mit dem Inline aufgrund der Funktion sort() nicht, da diese das zu sortierende Array als Referenz verarbeitet.</p>
<p>Kleine Spielerei aber vielleicht braucht ja mal jemand den Schipsel.</p>
<pre><code>&lt;?php
$file = 'pfad/zur/datei.csv';
$lines = file($file);
sort($lines);
file_put_contents($file, implode('', $lines));</code></pre>
<p>Einmal ausgeführt und aus</p>
<pre><code>"test","test"
"bla","blubber"
"apfel","apfel"</code></pre>
<p>wird</p>
<pre><code>"apfel","apfel"
"bla","blubber"
"test","test"</code></pre>
]]></content:encoded>
			<wfw:commentRss>https://blog.ebene7.com/2010/07/28/csv-datei-sortieren-ganz-einfach/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>range() vs. array_push()</title>
		<link>https://blog.ebene7.com/2010/06/26/range-vs-array-push/</link>
		<comments>https://blog.ebene7.com/2010/06/26/range-vs-array-push/#comments</comments>
		<pubDate>Sat, 26 Jun 2010 12:00:09 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Qualitätssicherung]]></category>
		<category><![CDATA[Array]]></category>
		<category><![CDATA[Benchmark]]></category>
		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://blog.ebene7.com/?p=990</guid>
		<description><![CDATA[Gestern habe ich Saschas Artikel &#8220;Füllen von array-Werten in Reihenfolge: for vs range&#8221; entdeckt, in dem er die Performance der PHP eigenen Funktion range() mit der von array_push() in einer for-Schleife vergleicht. Die allgemeine Erwartung ist sicher, dass range() schneller &#8230; <a href="https://blog.ebene7.com/2010/06/26/range-vs-array-push/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Gestern habe ich Saschas Artikel &#8220;<a href="http://softwareentwickler.blogspot.com/2010/06/fullen-von-array-werten-in-reihenfolge.html" target="_blank">Füllen von array-Werten in Reihenfolge: for vs range</a>&#8221; entdeckt, in dem er die Performance der PHP eigenen Funktion range() mit der von array_push() in einer for-Schleife vergleicht.</p>
<p>Die allgemeine Erwartung ist sicher, dass range() schneller ist und umso mehr überraschte zumindest mich sein Ergebnis.</p>
<p>Also habe ich schnell einen kleinen Test dafür geschrieben und dabei eine weitere Überraschung erlebt.</p>
<p><span id="more-990"></span>Zunächst mein Test-Script, mit dem ich jede Möglichkeit 1000 Mal probiere, um vergleichbare Zahlen zu bekommen. Neben <code>range()</code> und <code>array_push()</code> habe ich auch noch den Operator [] getestet.</p>
<pre><code>&lt;?php
$numLoops = 1000;

$total = 0;
for ($i = 0; $i &lt; $numLoops; $i++) {
  $start = microtime(true);

  $range = range(1,20); 

  $total += microtime(true) - $start;
}

echo 'Gesamtzeit range() = ' . $total . '&lt;br/&gt;';

$total = 0;
for ($i = 0; $i &lt; $numLoops; $i++) {
  $start = microtime(true);

  $range = array();
  for ($j = 1; $j &lt;= 20; $j++) {
    array_push($range, $j);
  }

  $total += microtime(true) - $start;
}

echo 'Gesamtzeit Schleife/array_push() = ' . $total . '&lt;br/&gt;'; 

$total = 0;
for ($i = 0; $i &lt; $numLoops; $i++) {
  $start = microtime(true);

  $range = array();
  for ($j = 1; $j &lt;= 20; $j++) {
    $range[] = $j;
  }

  $total += (microtime(true) - $start);
}

echo 'Gesamtzeit Schleife/[] = ' . $total . '&lt;br/&gt;';</code></pre>
<p>Ein recht gutes Ergebnis sieht so aus und man kann schon sehr gut die Unterschiede sehen.</p>
<pre>Gesamtzeit range()               = 0.0055239200592041
Gesamtzeit Schleife/array_push() = 0.015237808227539
Gesamtzeit Schleife/[]           = 0.0075914859771729</pre>
<p>In diesem Test brauchte die Schleife mit <code>array_push()</code> doppelt so lange wie die mit dem  []-Oparator und sogar dreimal länger als <code>range()</code>.</p>
<p>Das zeigt, dass man sich doch auf die PHP-eigenen Funktionen verlassen kann und dass Faulheit manchmal auch belohnt wird, wenn man statt <code>array_push()</code> nur <code>[]</code> verwendet.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.ebene7.com/2010/06/26/range-vs-array-push/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Objekte und Arrays casten</title>
		<link>https://blog.ebene7.com/2010/05/18/objekte-und-arrays-casten/</link>
		<comments>https://blog.ebene7.com/2010/05/18/objekte-und-arrays-casten/#comments</comments>
		<pubDate>Tue, 18 May 2010 05:00:19 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Tipps und Tricks]]></category>
		<category><![CDATA[Array]]></category>
		<category><![CDATA[Datenstruktur]]></category>
		<category><![CDATA[Foreach]]></category>
		<category><![CDATA[Objekt]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Scheifen]]></category>
		<category><![CDATA[Type-Cast]]></category>

		<guid isPermaLink="false">http://blog.ebene7.com/?p=813</guid>
		<description><![CDATA[Letzte Woche fand ich den Artikel Objekte und Arrays auf phpmonkeys.de und war, ebenso wie der Autor auch, überrascht, wie einfach doch PHP zuweilen sein kann. In dem Artikel wird beschrieben, wie man Daten aus einem Array in ein Objekt &#8230; <a href="https://blog.ebene7.com/2010/05/18/objekte-und-arrays-casten/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Letzte Woche fand ich den Artikel <a href="http://www.phpmonkeys.de/2010/05/10/objekte-und-arrays/" target="_blank">Objekte und Arrays auf phpmonkeys.de</a> und war, ebenso wie der Autor auch, überrascht, wie einfach doch PHP zuweilen sein kann.</p>
<p>In dem Artikel wird beschrieben, wie man Daten aus einem Array in ein Objekt (oder auch umgekehrt) überführen kann, ohne jedesmal eine foreach-Schleife zum Kopieren herumzubauen. Der Trick ist einfach, wie auch genial: Einfach ein Typecast und gut ist.</p>
<p>Ähnliches habe ich ja schonmal in einem <a href="http://blog.ebene7.com/2010/01/08/foreach-mit-typecast/">Artikel</a> über den Umgang mit &#8220;Nicht-Arrays&#8221; und foreach-Schleifen beschrieben.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.ebene7.com/2010/05/18/objekte-und-arrays-casten/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
