symfony

Dependency Injection in PHP (IoC Pattern)

Kurze Recherche zu Dependency Injection in PHP (Inversion of Control Pattern)

Erläuterungen zu DI und IoC http://martinfowler.com/articles/injection.html

Seit einiger Zeit ist das Thema DI in PHP recht aktuell mittlerweile gibt es einige selbständige Dependency Injection Container und einige DI Container welche aus einem Framework entstanden sind oder zu diesem gehören.

Folgende DI Lösungen in PHP habe ich auf die schnelle gefunden und kurz angesehen:

Wirklich getestet habe ich nur den Symfony DI Container, um das mal ein bisschen zu verdeutlichen hier eine Beispiel Konfiguration und ein bisschen Beispiel Code:

Als Konfigurationsformat habe ich XML ausgewählt die Konfiguration meines DI Containers für ein Beispiel Projekt sieht bei mir so aus

XML:
  1. <?xml version="1.0" encoding="UTF-8"?>
  2.  
  3. <container xmlns="http://symfony-project.org/2.0/container">
  4.   <services>
  5.  
  6.     <!-- PageCache -->
  7.     <service id="pagecache" class="Zend_Cache" shared="true" constructor="factory">
  8.       <file>Zend/Cache.php</file>
  9.       <argument>Page</argument>
  10.       <argument>File</argument>
  11.       <argument type="collection">
  12.         <argument key="lifetime">3600</argument>
  13.         <argument key="default_options" type="collection">
  14.           <argument key="make_id_with_get_variables">true</argument>
  15.           <argument key="make_id_with_cookie_variables">false</argument>
  16.           <argument key="specific_lifetime">3600</argument>
  17.           <argument key="cache_with_session_variables">true</argument>
  18.           <argument key="cache_with_post_variables">true</argument>
  19.           <argument key="cache_with_get_variables">true</argument>
  20.           <argument key="tags" type="collection">
  21.             <argument>page</argument>
  22.           </argument>
  23.         </argument>
  24.         <argument key="lifedebug_header">false</argument>
  25.       </argument>
  26.       <argument type="collection">
  27.         <argument key="cache_dir">../tmp/</argument>
  28.       </argument>
  29.       <call method="start">
  30.       </call>
  31.     </service>
  32.   <!-- ENDE PageCache -->
  33.  
  34.  
  35.     <!-- Loggging -->
  36.     <service id="log" class="Logger" shared="true">
  37.       <argument type="service">
  38.         <service class="Zend_Log" shared="true">
  39.           <argument type="service">
  40.             <service class="Zend_Log_Writer_Stream" shared="true">
  41.               <argument>../log/debug.log</argument>
  42.               <call method="setFormatter">
  43.                 <argument type="service">
  44.                   <service class="Zend_Log_Formatter_Simple" shared="true">
  45.                     <argument>%%timestamp%%|%%sessionId%%|%%priorityName%%|%%fkn%%.%%line%%|%%message%%
  46.                     </argument>
  47.                   </service>
  48.                 </argument>
  49.               </call>
  50.             </service>
  51.           </argument>
  52.         </service>
  53.       </argument>
  54.       <call method="setLevel">
  55.         <argument>7</argument>
  56.       </call>
  57.     </service>
  58.     <!-- ENDE Loggging -->
  59.  
  60.   <!-- Cache -->
  61.     <service id="cache" class="Zend_Cache" shared="true" constructor="factory">
  62.       <file>Zend/Cache.php</file>
  63.       <argument>Core</argument>
  64.       <argument>File</argument>
  65.       <argument type="collection">
  66.         <argument key="automatic_serialization">true</argument>
  67.       </argument>
  68.       <argument type="collection">
  69.         <argument key="cache_dir">../tmp/</argument>
  70.       </argument>
  71.     </service>
  72.  
  73.   <!-- END Cache -->
  74.  
  75.   </services>
  76. </container>

Die Konfiguration bewirkt das ich in der Anwendung nachher einen PageCache, einen Logger und einen normalen Cache einsatzbereit zur Verfügung habe sobald ich diese benötig.

Ein Hinweis noch zu den möglichen Attributen der Service Node besonders praktisch sind hier die Attribute "shared" und "constructor" mit dem shared Attribut kann angegeben werden ob nur eine Instanz dieses Service erstellt wird und bei jedem Zugriff darauf die selbe Instanz zurück gegeben wird, oder ob immer eine neue Instanz zurück gegeben wird. Über die "constructor" Attribut kann angebeben werden ob es sich um einen statischen oder nicht statischen Aufruf handelt. Für Zend_Cache wird der Aufruf Zend_Cache::factory(Core, File,...) verwendet. An der Klasse Logger wird der Konstruktor mit den angegebenen Parametern aufgerufen.
Im PageCache Beispiel wird direkt nach der Erstellung des Objekts noch die Methode start() aufgerufen.

Innerhalb der Anwendung wird der Container folgendermaßen initialisiert und Verwendet:

PHP:
  1. require_once $basePath.'/lib/sf/sfServiceContainerAutoloader.php';
  2.  
  3. // Symfony Autoloader registrieren
  4. sfServiceContainerAutoloader::register();
  5.  
  6. // haben wir schon einen Fertigen DI Container?
  7. if (file_exists($configPath.'/di.container.conf.xml.php'))
  8. {
  9. require_once $configPath.'/di.container.conf.xml.php';
  10. $sc = new SampleServiceContainer();
  11. }
  12. else
  13. {
  14. // noch kein DI Container vorhanden, also aus XML erstellen
  15. $sc = new sfServiceContainerBuilder();
  16. $loader = new sfServiceContainerLoaderFileXml($sc);
  17. $loader->load($configPath.'/di.container.conf.xml');
  18. $dumper = new sfServiceContainerDumperPhp($sc);
  19. file_put_contents($file, $dumper->dump(array('class' => 'SampleServiceContainer')));
  20. }
  21.  
  22. // Folgende Aufrufe können dann innerhalb der Anwendung verwendet werden
  23. // Zugriff auf den Cache
  24. $cache = $sc->cache;
  25.  
  26. // Zugriff auf den Logger
  27. $log = $sc->log

noch Fragen? Doku anschauen ;-)

SymfonyDay in Köln

Am 04.09.2009 gibt es den ersten SymfonyDay in Deutschland (genauer gesagt in Köln).

Die Registrierung ist bereits offen und der Schedule steht auch schon.

Geboten werden Talks und Workshops.

Das ganze ist mit 80€ incl Drinks und Essen auch ziemlich günstig.

Gesponsert wird der SymfonyDay09 von der in Köln ansässigen Interlutions GmbH welche auch gleich noch alle Teilnehmer zu Ihrer 10 Jahres Feier am Anschluss zum Symfony Day einlädt.

Also anmelden und in Köln einen bestimmt interessanten Tag erleben.

Symfony Admin Generator auf Deutsch

Grade gefunden, D-Down bietet auf seiner Seite die Übersetungen für den Admin Generator von Symfony an. http://coding.d-down.de/blog/archives/47-Die-deutsche-UEbersetzung-der-Admin-Generator-Begriffe-von-Symfony.html

Hab die obere Datei nocheinmal erweitert und auch bereits in das richtige XLIFF Format gebracht. Runterladen _hier_ .
Da ich auch erst mal rumsuchen musste wie man es verwendet hier noch einmal alle Schritte.

- in der apps/backend/config/settings.yml den auskommentierten i18n Eintrag unter .settings auf "on" stellen.
- obige Datei unter apps/backend/i18n/messages.de_DE.xml speichern. dabei Format so anpassen wie es unter ( http://www.symfony-project.com/book/1_0/13-I18n-and-L10n#Using Dictionary%20Files ) in figure 13-14 steht... <xml><body... am anfang und ende ergänzen. (bei meiner Datei schon geschehen)
- unter backend/config/i18n.yml:
all:
default_culture: de_DE
source: XLIFF
debug: off
untranslated_prefix: "[t]"
untranslated_suffix: "[/t]"

eintragen.
- symfony cc
- browser neu starten oder cookies löschen

Wird der Admin Generator erneut aufgerufen sollten die meisten Texte eingedeutscht sein. Stellt man in der i18n.yml das debugging auf on, kann man auch sehr schnell erkennen welche nicht übersetzt wurden und diese gegebenenfalls in der eigenen messages.de_DE.xml nachpflegen.