<?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; Magento</title>
	<atom:link href="http://blog.ebene7.com/schlagwort/magento/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>Programm to an Interface, Dude!</title>
		<link>https://blog.ebene7.com/2011/07/11/programm-to-an-interface-dude/</link>
		<comments>https://blog.ebene7.com/2011/07/11/programm-to-an-interface-dude/#comments</comments>
		<pubDate>Mon, 11 Jul 2011 04:00:12 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Qualitätssicherung]]></category>
		<category><![CDATA[Data Mapper]]></category>
		<category><![CDATA[Implementierung]]></category>
		<category><![CDATA[Interface]]></category>
		<category><![CDATA[Magento]]></category>
		<category><![CDATA[Model]]></category>
		<category><![CDATA[OOP]]></category>

		<guid isPermaLink="false">http://blog.ebene7.com/?p=2891</guid>
		<description><![CDATA[Heute mag ich mal ein einfaches Thema aufgreifen, welches jedoch noch nicht wirklich seinen Weg in die PHP-Welt gefunden hat. Es geht um Interfaces. Seit Version 5 kann man in PHP viele der lange vermissten OOP-Features nutzen, aber leider machen &#8230; <a href="https://blog.ebene7.com/2011/07/11/programm-to-an-interface-dude/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Heute mag ich mal ein einfaches Thema aufgreifen, welches jedoch noch nicht wirklich seinen Weg in die PHP-Welt gefunden hat. Es geht um Interfaces. Seit Version 5 kann man in PHP viele der lange vermissten OOP-Features nutzen, aber leider machen viele Entwickler dennoch einen großen Bogen darum.</p>
<p><span id="more-2891"></span>Als ich mich vor ein paar Jahren auf meine Java-Zertifizierung vorbereitet habe, ist mir ein Satz immer wieder begegnet: &#8220;Programm to an interface, not to an implementation!&#8221;. Klingt einfach, ist es auch.</p>
<p>Im Prinzip sagt das nur aus, dass man sich beim Entwickeln nur darauf verlassen sollte, was die jeweilig implementierten Interfaces an Funktionalität anbieten. Wie das ganze dann im Hintergrund implementiert ist, interessiert dann nicht mehr.</p>
<p>Ein kleines Beispiel aus der Praxis: In einem Shop (in dem Fall Magento) werden Bestellungen (Orders) gespeichert. Nun soll ein <a href="http://de.wikipedia.org/wiki/Enterprise_Resource_Planning" target="_blank">ERP-System</a> angebunden werden. Für beide Systeme gibt es entsprechende Models, mit denen die Daten verarbeitet werden können.</p>
<p>Soweit, so gut. Jetzt kommt der unbequeme Teil der Aufgabe. Das Magento-Order-Model erbt einfach nur von verschiedenen anderen Klassen, aber es existiert kein Interface, das dem Entwickler bestimmte Methoden garantiert. An vielen Stellen werden zudem die Parameter mit Type-Hinting überprüft, ob sie eine Magento-Order enthalten.</p>
<p>Das Model für die Anbindung an das ERP-System hat unter Umständen andere Elternklassen und somit auch erstmal keine Gemeinsamkeiten. Das bedeutet, dass wir theoretisch die Objekte gleich behandeln könnten, aber wir sie für das Type-Hinting doch wieder in Wrapper verpacken oder auf Magento-Order-Objekte mappen müssen.</p>
<p>Diese Arbeit könnte man sich komplett sparen, wenn man sich von Anfang an auf ein Interface verlassen hätte. Leider existiert dieses meines Wissens nicht und es für eigene Projekte zu nutzen würde Änderungen in den Magento-Core-Dateien fordern.</p>
<pre>&lt;?php
interface Mage_Sales_Model_Order_Interface
{
  /**
   * Retrieve customer model
   *
   * @return Mage_Customer_Model_Customer_Interface
   */
  public function getCustomer();

  // ...
}</pre>
<p>Damit könnte man sich auf verschiedene Methoden verlassen die der Typ Mage_Sales_Model_Order_Interface (!) zusagt.</p>
<pre>&lt;?php
class Mage_Sales_Model_Order
  extends Mage_Sales_Model_Abstract
  implements Mage_Sales_Model_Order_Interface
{
  // ...
}</pre>
<p>Die Klasse Mage_Sales_Model_Order könnte sich an diesen &#8220;Vertrag&#8221; halten,</p>
<pre>&lt;?php
class Erp_Sales_Model_Order
  extends Erp_Was_Auch_Immer_Model_Abstract
  implements Mage_Sales_Model_Order_Interface
{
  // ...
}</pre>
<p>sowie auch jede andere Klasse.</p>
<pre>&lt;?php
// ...
public function getEmailFromOrder(Mage_Sales_Model_Order_Interface $order)
{
  return $order-&gt;getCustomer()-&gt;getEmail();
}
// ...</pre>
<p>So können wir jede beliebige Klasse mit bestehenden Code weiterhin verarbeiten, ohne dass uns das Type-Hinting dabei im Weg steht. Was die Methode getCustomer() nun intern macht, ist uns egal, solange ein Objekt vom Typ Mage_Customer_Model_Customer_Interface zurückgegeben wird.</p>
<p>Es ist vielleicht auf den ersten Blick etwas umständlicher, für jeden Typ ein Interface zu schreiben, aber das spart man danach wieder locker ein und bleibt dazu auch in der weiteren Entwicklung seiner Anwendung flexibel.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.ebene7.com/2011/07/11/programm-to-an-interface-dude/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Faule Models und große Datenmengen</title>
		<link>https://blog.ebene7.com/2010/12/13/faule-models-und-grosse-datenmengen/</link>
		<comments>https://blog.ebene7.com/2010/12/13/faule-models-und-grosse-datenmengen/#comments</comments>
		<pubDate>Mon, 13 Dec 2010 05:00:46 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[CustomLibrary]]></category>
		<category><![CDATA[Custom_Model]]></category>
		<category><![CDATA[Data Mapper]]></category>
		<category><![CDATA[Datenbank]]></category>
		<category><![CDATA[Entwurfsmuster]]></category>
		<category><![CDATA[Magento]]></category>
		<category><![CDATA[Model]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[OOP]]></category>

		<guid isPermaLink="false">http://blog.ebene7.com/?p=1536</guid>
		<description><![CDATA[Unter verschiedenen Umständen kann es vorteilhaft sein, wenn Models nicht vollständig geladen und mit Daten befüllt werden, weil das Lesen zu komplex ist (Stichwort EAV-Model) oder wir mit sehr vielen Datensätzen arbeiten und dabei Speicherplatz sparen wollen/müssen. Gleichzeitig wollen wir &#8230; <a href="https://blog.ebene7.com/2010/12/13/faule-models-und-grosse-datenmengen/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Unter verschiedenen Umständen kann es vorteilhaft sein, wenn Models nicht vollständig geladen und mit Daten befüllt werden, weil das Lesen zu komplex ist (Stichwort EAV-Model) oder wir mit sehr vielen Datensätzen arbeiten und dabei Speicherplatz sparen wollen/müssen.</p>
<p>Gleichzeitig wollen wir aber zu jeder Zeit sicherstellen, dass wir das Model wie gewohnt vollständig abfragen und verwenden können. An dieser Stelle kommt eine Technik namens LazyLoading (lazy = engl. faul, träge) zum Einsatz.</p>
<p><span id="more-1536"></span></p>
<p>Nun konstruiere ich einfach ein Beispiel, um den Ablauf besser erklären zu können. In unserer Anwendung brauchen wir ein Model &#8220;Person&#8221;, das Informationen wie Name, Geburtstag und diverse andere speichern kann. Den Namen und den Geburtstag brauchen wir immer (z.B. in der Listenansicht) und die restlichen Felder nur wenn wir eine Detailansicht erstellen.</p>
<p>Wie kommt unser Model nun an die Daten? In der Regel wird sicherlich load() auf dem Modelobjekt aufgerufen oder eine vergleichbare Methode auf der jeweiligen Collection, dann werden die Daten über ein Resourcemodel geladen und letztendlich komplett auf die einzelnen Modelobjekte kopiert.</p>
<p>Um unser Vorhaben umzusetzen müssen wir das etwas abändern. Die Methode load() des Models funktioniert wie gewohnt und lädt alle Daten und die Collection nur die Nötigsten. Um nun sicherzustellen, dass wir trotzdem immer alles abrufen können, muss das Model etwas intelligenter werden.</p>
<p>Die Entwicklung des <a href="http://blog.ebene7.com/schlagwort/custom_model/" target="_self">Custom_Model</a>s hat der eine oder andere ja vielleicht mitbekommen und kennt den grundlegenden Aufbau. Relativ neu ist die Klasse Custom_Model_Persistent, durch die eine weitere Unterscheidung zwischen einfachen Datencontainern und speicherbaren Models möglich wird.</p>
<p>Für das automatische Nachladen muss die Modelklasse nun erweitert werden.</p>
<pre>&lt;?php
class Custom_Model_Persistent extends Custom_Model
{
  private $_isLoaded;

  // ...

  public function load($value = null, $field = 'id')
  {
    if (null === $value &amp;&amp; $this-&gt;_isset($field)) {
      $value = $this-&gt;_get($field);
    }

    $this-&gt;getResource()
         -&gt;loadModel($this, $value, $this-&gt;_mapKey($field))
         -&gt;markLoaded();

    return $this;
  }

  public function isLoaded()
  {
    return $this-&gt;_isLoaded;
  }

  public function markLoaded()
  {
    $this-&gt;_isLoaded = true;
    return $this;
  }

  protected function _get($key, $default = null)
  {
    if (!$this-&gt;_isset($key) &amp;&amp; !$this-&gt;isLoaded()) {
      $this-&gt;load();
    }
    return parent::_get($key, $default);
  }
}</pre>
<p>Die entscheidenen Stellen sind hier der überschriebene zentrale Getter, der ein das &#8220;Default-Load()&#8221; auslöst, wenn der Wert nicht gesetzt ist und die Daten auch noch nicht vollständig geladen wurden und die Methode load() mit optionalen Parameter $value.</p>
<p>Im Beispiel verlasse ich mich darauf, dass das Standardfeld schon gesetzt ist. Eine ordentliche Fehlerbehandlung muss aber unbedingt her, wenn wir das ganze produktiv einsetzen wollen.</p>
<p>Die Methoden isLoaded() bzw markLoaded() sind absichtlich public, damit sie z.B. aus einer Collection aufgerufen werden können, wenn das Model komplett geladen wurde. Eine weitere Möglichkeit wäre ein Vergleich mit einer Liste die gesetzt sein sollten.</p>
<p>Im Moment ist das noch etwas im Entwurf und sogar ungetestet. Wenn euch nun noch was dazu einfällt, dann schreibt einen Kommentar. Wo seht ihr für euch die Vor- oder evtl. auch die Nachteile?</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.ebene7.com/2010/12/13/faule-models-und-grosse-datenmengen/feed/</wfw:commentRss>
		<slash:comments>4</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>Magento-Cheatsheet</title>
		<link>https://blog.ebene7.com/2010/05/19/magento-cheatsheet/</link>
		<comments>https://blog.ebene7.com/2010/05/19/magento-cheatsheet/#comments</comments>
		<pubDate>Wed, 19 May 2010 05:00:08 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Notiz an mich]]></category>
		<category><![CDATA[Snippets]]></category>
		<category><![CDATA[Cheatsheet]]></category>
		<category><![CDATA[Magento]]></category>
		<category><![CDATA[Model]]></category>
		<category><![CDATA[Shop]]></category>
		<category><![CDATA[Spickzettel]]></category>

		<guid isPermaLink="false">http://blog.ebene7.com/?p=794</guid>
		<description><![CDATA[Für diverse häufig gebrauchte Funktionen mit dem doch sehr umfangreichen Shopsystem hier eine kleine Übersicht (wird zukünftig noch erweitert): Diverse Werte &#60;?php $storeId = Mage::app()-&#62;getStore()-&#62;getId(); $storeName = Mage::app()-&#62;getStore()-&#62;getName(); $storeCode = Mage::app()-&#62;getStore()-&#62;getCode(); $groupId = Mage::app()-&#62;getStore()-&#62;getGroupID(); $groupName = Mage::app()-&#62;getStore()-&#62;getGroup()-&#62;getName(); $websiteName = Mage::app()-&#62;getWebsite()-&#62;getName(); &#8230; <a href="https://blog.ebene7.com/2010/05/19/magento-cheatsheet/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Für diverse häufig gebrauchte Funktionen mit dem doch sehr umfangreichen Shopsystem hier eine kleine Übersicht (wird zukünftig noch erweitert):<br />
<span id="more-794"></span></p>
<h3>Diverse Werte</h3>
<pre><code>&lt;?php $storeId = Mage::app()-&gt;getStore()-&gt;getId(); $storeName = Mage::app()-&gt;getStore()-&gt;getName(); $storeCode = Mage::app()-&gt;getStore()-&gt;getCode(); $groupId = Mage::app()-&gt;getStore()-&gt;getGroupID(); $groupName = Mage::app()-&gt;getStore()-&gt;getGroup()-&gt;getName(); $websiteName = Mage::app()-&gt;getWebsite()-&gt;getName();</code></pre>
<h3>Session</h3>
<pre>&lt;?php
$sessionId  = Mage::getModel('core/session')-&gt;getSessionId();
$customerId = Mage::getModel('customer/session')-&gt;getCustomerId();
$vistitorId = Mage::getModel('core/session')-&gt;getVisitorId();</pre>
<h3>Models</h3>
<pre><code>&lt;?php $customer = Mage::getModel('customer/customer'); $order = Mage::getModel('sales/order'); $product = Mage::getModel('catalog/product'); </code></pre>
<h4>Produkt-Model</h4>
<pre>$product    = Mage::getModel('catalog/product')-&gt;load($productId);
$categories = $product-&gt;getCategoryCollection();</pre>
<h3>Konfiguration</h3>
<p>auslesen</p>
<pre>$value = Mage::getStoreConfig('[MODULE]/[SECTION]/[FIELD]', $storeId);</pre>
<p>und wieder schreiben</p>
<pre>// Wert für Store 1 setzen
Mage::getConfig()-&gt;saveConfig('path/to/config/value', 12343, 'stores', 1);

// oder als Defaultwert
Mage::getConfig()-&gt;saveConfig('path/to/config/value', 12343);</pre>
<h3>Blocks</h3>
<pre><code>&lt;?php </code>$block = Mage::app()-&gt;getLayout()-&gt;createBlock('log/...');</pre>
<h3>Helpers</h3>
<pre>&lt;?php
$helper = Mage::helper('helper');</pre>
<h3>Logging</h3>
<pre><code>&lt;?php Mage::log('Schreibe das ins Logfile');</code></pre>
<h3>Sonstiges</h3>
<p>Store-Umgebung simulieren</p>
<pre><code>Mage::app()-&gt;getLocale()-&gt;emulate($storeId);</code></pre>
<p>Events auslösen</p>
<pre><code>Mage::dispatchEvent($eventName);</code></pre>
<p>Es geht weiter&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.ebene7.com/2010/05/19/magento-cheatsheet/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Event-Handling bei Magento</title>
		<link>https://blog.ebene7.com/2010/05/06/event-handling-bei-magento/</link>
		<comments>https://blog.ebene7.com/2010/05/06/event-handling-bei-magento/#comments</comments>
		<pubDate>Thu, 06 May 2010 05:00:20 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Notiz an mich]]></category>
		<category><![CDATA[Tipps und Tricks]]></category>
		<category><![CDATA[Eventhandling]]></category>
		<category><![CDATA[Konfiguration]]></category>
		<category><![CDATA[Listeners]]></category>
		<category><![CDATA[Magento]]></category>
		<category><![CDATA[Observer]]></category>
		<category><![CDATA[Shop]]></category>

		<guid isPermaLink="false">http://blog.ebene7.com/?p=744</guid>
		<description><![CDATA[Wie ich ja vor kurzem schon berichtet habe, bin ich dabei mich in die Shopsoftware Magento einzuarbeiten und dabei stolpere ich noch hin und wieder über das eine oder andere Feature. So zum Beispiel hatte ich den Fall, dass ich &#8230; <a href="https://blog.ebene7.com/2010/05/06/event-handling-bei-magento/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Wie ich ja vor kurzem schon berichtet habe, bin ich dabei mich in die Shopsoftware Magento einzuarbeiten und dabei stolpere ich noch hin und wieder über das eine oder andere Feature. So zum Beispiel hatte ich den Fall, dass ich einen eigenen Observer nach einer Speicheraktion verwendet habe, der aber nicht im Adminbereich reagierte.</p>
<p>Die Lösung ist deratig einfach, wenn man es weiß&#8230; Die Einstellung für das jeweilige Event muss natürlich im richtigen Scope in der config.xml gemacht werden.</p>
<p>Ist der Beobachter nun also global eingestellt, klappt es auch in allen Bereichen. Andersherum lässt sich so aber auch eine unterschiedliche Verarbeitung für das selbe Ereignis einstellen.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.ebene7.com/2010/05/06/event-handling-bei-magento/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Was tun gegen magische Zugriffsmethoden?</title>
		<link>https://blog.ebene7.com/2010/04/09/was-tun-gegen-magische-zugriffsmethode/</link>
		<comments>https://blog.ebene7.com/2010/04/09/was-tun-gegen-magische-zugriffsmethode/#comments</comments>
		<pubDate>Fri, 09 Apr 2010 20:30:22 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Grundlagen]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Snippets]]></category>
		<category><![CDATA[Tipps und Tricks]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[Magento]]></category>
		<category><![CDATA[Magic Methods]]></category>
		<category><![CDATA[NetBeans]]></category>
		<category><![CDATA[Reflection]]></category>
		<category><![CDATA[Shop]]></category>
		<category><![CDATA[Zugriffsmethode]]></category>

		<guid isPermaLink="false">http://blog.ebene7.com/?p=561</guid>
		<description><![CDATA[Im Moment bin ich mit voller Begeisterung dabei, mich in die Magento Shopsoftware einzuarbeiten. Dass die Entwickler jedoch nicht nur die Software, sondern auch den Programmcode sehr flexibel gestaltet haben, macht die Sache leider nicht einfacher. Viele Methoden sind mit &#8230; <a href="https://blog.ebene7.com/2010/04/09/was-tun-gegen-magische-zugriffsmethode/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Im Moment bin ich mit voller Begeisterung dabei, mich in die Magento Shopsoftware einzuarbeiten. Dass die Entwickler jedoch nicht nur die Software, sondern auch den Programmcode sehr flexibel gestaltet haben, macht die Sache leider nicht einfacher.</p>
<p>Viele Methoden sind mit <a href="http://de2.php.net/manual/de/language.oop5.overloading.php#language.oop5.overloading.methods" target="_blank"><code>__call()</code></a> implementiert und das hat die Nachteile, dass z.B. die <a href="http://de.wikipedia.org/wiki/Autovervollst%C3%A4ndigen" target="_blank">Codecompletion</a>, <a href="http://de.wikipedia.org/wiki/Reflection_%28Programmierung%29" target="_blank">Reflection</a>, automatische Dokumentation oder die Navigation in der IDE ausgehebelt werden.</p>
<p>Zum Glück können wir das ja zum Teil in vererbten Klassen wieder abfangen, ohne die ursprünglichen Klassen umschreiben zu müssen, z.B. weil wir die fremden Libraries zwecks späterer Updates nicht verändern wollen.</p>
<pre>&lt;?php

class A
{
  public function __call($method, $args)
  {
    echo __METHOD__ . ' ' . $method;
  }
}

class B extends A
{
  public function machWas()
  {
    parent::machWas();
  }
}

$b = new B();
$b-&gt;machWas();</pre>
<p>Die Methode <code>B::machWas()</code> delegiert den Aufruf an die magische Methode, wobei sich das Verhalten nach außen nicht verändert, jedoch alles andere wieder funktionieren wird.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.ebene7.com/2010/04/09/was-tun-gegen-magische-zugriffsmethode/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
