<?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; Zend Framework</title>
	<atom:link href="http://blog.ebene7.com/schlagwort/zend-framework/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>Amazon S3 mit PHP-Stream Wrapper verwenden</title>
		<link>https://blog.ebene7.com/2011/01/21/amazon-s3-mit-php-stream-wrapper-verwenden/</link>
		<comments>https://blog.ebene7.com/2011/01/21/amazon-s3-mit-php-stream-wrapper-verwenden/#comments</comments>
		<pubDate>Fri, 21 Jan 2011 05:00:07 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Qualitätssicherung]]></category>
		<category><![CDATA[Amazon]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[S3]]></category>
		<category><![CDATA[Stream]]></category>
		<category><![CDATA[Wrapper]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[Zend_Cloud]]></category>
		<category><![CDATA[Zend_Service]]></category>

		<guid isPermaLink="false">http://blog.ebene7.com/?p=2645</guid>
		<description><![CDATA[In der letzten Woche habe ich ja bereits über die Komponente Zend_Cloud geschrieben und ungetestet behauptet, dass sie sicherlich leicht zu verwenden sei. Das Testen habe ich nun nachgeholt und habe erwartungsgemäß keine bösen Überraschungen erlebt. Ganz im Gegenteil, sogar! &#8230; <a href="https://blog.ebene7.com/2011/01/21/amazon-s3-mit-php-stream-wrapper-verwenden/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In der letzten Woche habe ich ja bereits über die Komponente <a href="http://blog.ebene7.com/2011/01/13/auf-wolke-sieben-mit-zend_cloud/" target="_self">Zend_Cloud</a> geschrieben und ungetestet behauptet, dass sie sicherlich leicht zu verwenden sei. Das Testen habe ich nun nachgeholt und habe erwartungsgemäß keine bösen Überraschungen erlebt.</p>
<p>Ganz im Gegenteil, sogar! Während meiner Arbeit mit Amazon S3 kam mir der Gedanke, dass es doch sehr bequem wäre, wenn es einen Stream Wrapper gäbe und man die PHP-eigenen File-Funktionen zum Lesen und Schreiben verwenden könnte.</p>
<p>Nach kurzem Suchen habe ich, wen wird es überraschen, eine noch einfachere Lösung gefunden. Zuerst aber mein Versuch mit Zend_Cloud Dateien nach Amazon S3 zu kopieren.<span id="more-2645"></span></p>
<h3>Zend_Cloud</h3>
<p>Einfach die <a href="http://framework.zend.com/manual/de/zend.cloud.storageservice.html" target="_blank">Storage-Factory</a> mit den nötigen Zugangsdaten füttern und schon kann es losgehen.</p>
<pre>&lt;?php
$adapter      = 'Zend_Cloud_StorageService_Adapter_S3';
$amazonKey    = '&lt;amazon-key&gt;';
$amazonSecret = '&lt;amazon-secret&gt;';
$bucketName   = 'mein-bucket';

$storage = Zend_Cloud_StorageService_Factory::getAdapter(array(
  Zend_Cloud_StorageService_Factory::STORAGE_ADAPTER_KEY =&gt; $adapter,
  Zend_Cloud_StorageService_Adapter_S3::AWS_ACCESS_KEY   =&gt; $amazonKey,
  Zend_Cloud_StorageService_Adapter_S3::AWS_SECRET_KEY   =&gt; $amazonSecret,
  Zend_Cloud_StorageService_Adapter_S3::BUCKET_NAME      =&gt; $bucketName,
));</pre>
<p>Die Factory liefert uns ein gebrauchsfertiges Objekt zurück, mit dem wir nun Dateien erzeugen können.</p>
<pre>&lt;?php
$filename = 'example.txt';
$data = file_get_contents($filename);
$storage-&gt;storeItem($filename, $data);</pre>
<p>Ebenso einfach wie das Erstellen ist auch das Lesen&#8230;</p>
<pre>&lt;?php
echo $storage-&gt;fetchItem($filename));</pre>
<p>&#8230;oder Löschen einer Datei.</p>
<pre>&lt;?php
$storage-&gt;deleteItem($filename);</pre>
<h3>Zend_Service</h3>
<p>Nun hatte ich ja versprochen, dass es noch einfacher geht. Die Komponente Zend_Service bietet ebenfalls eine Schnittstelle für <a href="http://framework.zend.com/manual/de/zend.service.amazon.s3.html" target="_blank">Amazon S3</a> an und auch gleich eine Methode, diese als Stream Wrapper zu registrieren.</p>
<p>Zuerst muss natürlich das Objekt mit den Zugangsdaten erzeugt werden.</p>
<pre>&lt;?php
$amazonKey    = '&lt;amazon-key&gt;';
$amazonSecret = '&lt;amazon-secret&gt;';

$s3 = new Zend_Service_Amazon_S3($amazonKey, $amazonSecret);
$s3-&gt;registerStreamWrapper('s3');</pre>
<p>Ab jetzt ist der Stream Wrapper mit dem Schema &#8216;s3://&#8217; im System bekannt und mit den gewohnten File-Funktionen verwendet werden. Dadurch bleibt der Code schlank und man muss sich nicht für jede Speicherart eine andere Schnittstelle merken.</p>
<p>Nicht zuletzt können wir unsere Dateien nun organisieren wie und wo wir wollen ohne dabei wieder den Code umschreiben zu müssen.</p>
<pre>&lt;?php
file_put_contents("s3://&lt;bucket-name&gt;/halloWelt", "Hallo Welt"); // einfach schreiben
echo file_get_contents("s3://&lt;bucket-name&gt;/halloWelt"); // und wieder lesen</pre>
<p>Nebenbei bemerkt ist es auch recht einfach, sich einen eigenen Stream Wrapper für spezielle Anwendungfälle selber zu schreiben, aber dazu vielleicht mehr in einem weiteren Artikel.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.ebene7.com/2011/01/21/amazon-s3-mit-php-stream-wrapper-verwenden/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Einfache UnitTests für Magento</title>
		<link>https://blog.ebene7.com/2010/08/24/einfache-unittests-fur-magento/</link>
		<comments>https://blog.ebene7.com/2010/08/24/einfache-unittests-fur-magento/#comments</comments>
		<pubDate>Tue, 24 Aug 2010 05:00:39 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Qualitätssicherung]]></category>
		<category><![CDATA[AutoLoader]]></category>
		<category><![CDATA[Factory]]></category>
		<category><![CDATA[Magento]]></category>
		<category><![CDATA[PHPUnit]]></category>
		<category><![CDATA[Reflection]]></category>
		<category><![CDATA[Shop]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[Zend_CodeGenerator]]></category>

		<guid isPermaLink="false">http://blog.ebene7.com/?p=1118</guid>
		<description><![CDATA[Seit nun knapp fünf Monaten stelle ich mich der Herausforderung saubere Softwareentwicklung und Magento in Einklang zu bringen. Ein kleiner Schritt in diese Richtung war der Einsatz von UnitTests, um mögliche Fehler während der Entwicklung schneller zu finden. Viele Fehler &#8230; <a href="https://blog.ebene7.com/2010/08/24/einfache-unittests-fur-magento/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Seit nun knapp fünf Monaten stelle ich mich der Herausforderung saubere Softwareentwicklung und Magento in Einklang zu bringen. Ein kleiner Schritt in diese Richtung war der Einsatz von UnitTests, um mögliche Fehler während der Entwicklung schneller zu finden.</p>
<p><span id="more-1118"></span>Viele Fehler treten bei Magento schon durch eine fehlerhafte Konfiguration auf, was zur Folge haben kann, dass wir keine Instanz unser lokalisierten Klasse bekommen, sondern ein standard Magento-Objekt oder einen Fehler, weil keine passende Klasse gefunden wird.</p>
<p>So habe ich also angefangen, die Existenz der zu prüfenden Klassen zu testen und ob die Mage-Factory das gewünschte Objekt zurück gibt. Bei einigen Klassen ist es zudem auch noch wichtig, dass sie von der richtigen Elternklasse abgeleitet sind.</p>
<p>Da sich diese Tests immer wiederholten, zeichnete sich schnell ein Muster ab. Ebenso erfolgt auch die Namesgebung der Magentoklassen nach einem gewissen Muster. Was wäre also naheliegender, als beides miteinander zu verbinden und so in Zukunft eine Menge unnützer Schreibarbeit zu sparen?</p>
<p>Als erstes habe ich dafür einen erweiteren TestCase vom PHPUnit-TestCase abgeleitet, der mir weitere vereinfachte Asserts zur Verfügung stellt und die Tests dadurch auch etwas lesbarer macht.</p>
<pre>$this-&gt;assertClassExists($classname);</pre>
<p>statt</p>
<pre>$this-&gt;assertTrue(class_exists($classname));</pre>
<p>Auf diesem Wege lassen sich dann auch z.B. Getter und Setter einfach auf das gewünschte Standardverhalten prüfen.</p>
<p>Im nächsten Schritt habe ich einen Entity-TestCase abgeleitet, der als Basis für alle weiteren TestCases für Models, Blocks und Helper dienen soll. Dieser ist in sich schon ein wenig intelligenter und erkennt anhand des Namens der Test-Klasse, welche Klasse getestet werden soll, welchen Typ diese hat und welche die Standard-Elternklasse ist.</p>
<p>Diese Informationen werden, nebenbei bemerkt, durch protected Methoden ermittelt und könnten zu jeder Zeit durch noch speziellere TestCases wieder überschrieben werden.</p>
<p>Mit den nun vorliegenden Informationen ist diese TestCase-Klasse mächtig genug, um alleine durch Vererbung die grundlegenden Tests durchzuführen.</p>
<p>Für die jeweiligen Typen, z.B. Model habe ich dann noch weitere TestCases abgeleitet, um dort noch spezielle Methoden implementieren zu können.</p>
<p>Ein sehr einfacher Test für die Model-Klasse &#8220;Mein_Customer_Model_Customer&#8221; sähe dann beispielsweise so aus:</p>
<pre>class Mein_Customer_Model_CustomerTest extends Mein_Model_TestCase
{
}</pre>
<p>Dadurch würde nun automatisch getestet werden, ob der Autoloader die Klasse &#8220;Mein_Customer_Model_Customer&#8221; finden kann, diese von der Magento-Model-Klasse erbt und ob die Factory aufgrund der Konfiguration auch das richtige Objekt liefert.</p>
<p>Ich denke, dass es viel einfacher nicht mehr geht und das Argument gegen Tests damit dann auch aus der Welt sein sollte.</p>
<p>Kleiner Tipp: Wenn man es nun noch etwas konfortabler mag, dann kann man sich seine Models auch mit dem Zend_CodeGenerator bauen lassen und die Tests gleich mit.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.ebene7.com/2010/08/24/einfache-unittests-fur-magento/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Stringumwandlung Underscore/CamelCase</title>
		<link>https://blog.ebene7.com/2010/07/23/stringumwandlung-underscore-camelcase/</link>
		<comments>https://blog.ebene7.com/2010/07/23/stringumwandlung-underscore-camelcase/#comments</comments>
		<pubDate>Fri, 23 Jul 2010 05:00:27 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Datenbank]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Tipps und Tricks]]></category>
		<category><![CDATA[CamelCase]]></category>
		<category><![CDATA[Custom_Model]]></category>
		<category><![CDATA[Model]]></category>
		<category><![CDATA[String]]></category>
		<category><![CDATA[Umwandlung]]></category>
		<category><![CDATA[Underscore]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://blog.ebene7.com/?p=1096</guid>
		<description><![CDATA[Häufig ist beim Umgang mit Datenquellen eine Stringumwandlung zwischen der Underscore- und CamelCase-Schreibweise erforderlich. Wo das sinnvoll ist und wie man es einfach anwendet, ist das Thema des heutigen Artikels. Die Underscore-Schreibart (z.B. &#8220;user_id&#8221;) findet man sehr oft als Spaltenbezeichner &#8230; <a href="https://blog.ebene7.com/2010/07/23/stringumwandlung-underscore-camelcase/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Häufig ist beim Umgang mit Datenquellen eine Stringumwandlung zwischen der Underscore- und CamelCase-Schreibweise erforderlich. Wo das sinnvoll ist und wie man es einfach anwendet, ist das Thema des heutigen Artikels.</p>
<p><span id="more-1096"></span>Die Underscore-Schreibart (z.B. &#8220;user_id&#8221;) findet man sehr oft als Spaltenbezeichner in Datenbanken oder auch in XML-Dateien, im PHP-Model (siehe auch mein <a href="http://blog.ebene7.com/2010/04/29/es-ist-ein-model-und-es-sieht-gut-aus/" target="_self">Artikel zum Custom_Model</a>) hingegen wird oft CamelCase (z.B. &#8220;userId&#8221;) verwendet.</p>
<p>Es wird also an der Schnittstelle zwischen dem Model und der Datenquelle eine Art Key-Mapping benötigt. Das lässt sich zwar recht einfach mit regulären Ausdrücken erschlagen, aber man kann sich auch der Zend_Filter-Klassen bedienen, wenn man in einem ZF-Umfeld arbeitet.</p>
<p>Die Anwendung ist wie so vieles beim Zend Framework recht einfach:</p>
<pre>&lt;?php
$toCamelCaseFilter = new Zend_Filter_Word_UnderscoreToCamelCase();
echo $toCamelCaseFilter-&gt;filter('user_id');

// Ausgabe: UserId</pre>
<p>Umgekehrt, wen wird es wundern, ist das natürlich genauso leicht:</p>
<pre>&lt;?php
$toUnderscoreFilter = new Zend_Filter_Word_CamelCaseToUnderscore();
echo $toUnderscoreFilter-&gt;filter('UserId');

// Ausgabe: User_Id</pre>
<p>Wenn man nicht extra eine Instanz erzeugen will, dann lassen sich die Zend Filter auch mit einem statischen Aufruf nutzen.</p>
<pre>&lt;?php
echo Zend_Filter::filterStatic('bitte_einmal_camel_case',
                               'Word_UnderscoreToCamelCase');

// Ausgabe: BitteEinmalCamelCase</pre>
<p>Das war es dann auch schon wieder für heute. Ich hoffe, dass euch der Artikel gefallen hat und ihr viele kreative Ideen zum Arbeiten mit den Filtern habt.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.ebene7.com/2010/07/23/stringumwandlung-underscore-camelcase/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
