PHPGangsta - Der praktische PHP Blog

PHP Blog von PHPGangsta


Zend_Config_Ini, Arrays und die Vererbung

with 8 comments

Ich mag .ini Konfigurationsdateien, und deshalb nutze ich auch bei Zend Framework Projekten immer die application.ini . Damals habe ich gelernt dass man Arrays so definiert:

[production]
...
server.0 = 192.168.0.1
server.1 = 192.168.0.2

[development : production]
…
server.0 = 10.0.0.1
server.1 = 10.0.0.2

Im ZendFramework Code kann ich dann das server-Array so nutzen:

$serverArray = $applicationIni->server->toArray();

Funktioniert wunderbar, es werden alle Einstellungen der production Sektion geerbt und ich habe in der Entwicklungsumgebung andere Server als in der Produktionsumgebung. Ein Problem tritt erst auf wenn ich in der Entwicklungsumgebung weniger Server habe als in der Produktionsumgebung:

[production]
…
server.0 = 192.168.0.1
server.1 = 192.168.0.2

[development : production]
…
server.0 = 10.0.0.1

Durch die Vererbungsregeln überschreibe ich also server.0, aber server.1 wird aus der production Sektion übernommen, das will ich aber nicht!
Meine bisherige Lösung sah so aus:

[production]
…
server.0 = 192.168.0.1
server.1 = 192.168.0.2

[development : production]
…
server.0 = 10.0.0.1
server.1 =

Und im PHP Code habe ich dann das Array auf leere Elemente untersucht, die ich dann übersprungen habe. Problem gelöst.

Nun bin ich durch Zufall auf eine bessere Lösung gestossen. In einem Kommentar der parse_ini_file() Funkion wurde sie 2007 erwähnt, worauf sie dann später auch im Manual aufgenommen wurde:

[production]
…
server[] = 192.168.0.1
server[] = 192.168.0.2

[development : production]
…
server[] = 10.0.0.1

Diese Lösung ist deutlich schöner und effektiver, ich brauche im PHP-Code nicht mehr auf leere Array-Elemente testen, ich bekomme direkt das Array das ich erwarte. Leider weiß ich nicht ab welcher PHP-Version diese eckigen Klammern nutzbar sind, es ist ein schönes Feature, das einem etwas Mehrarbeit und unschöne ini-Dateien ersparen kann. Ich wußte das jedenfalls noch nicht, und es ist gut möglich dass es für euch ein alter Hut ist.

Written by Michael Kliewe

August 29th, 2011 at 9:41 am

8 Responses to 'Zend_Config_Ini, Arrays und die Vererbung'

Subscribe to comments with RSS or TrackBack to 'Zend_Config_Ini, Arrays und die Vererbung'.

  1. M.E. eine sehr unschöne Lösung. Da Sie nicht das tut, was man guten Gewissens Annehmen darf – nämlich das die beiden Einträge aus „production“ vererbt werden und in „development“ noch einen weiteren Server hinzubekommt.

    Das Ausnutzen dieses nicht dokumentierten Verhaltens (Bruch der Vererbung) ist m.E. ein schlechter Stil.

    Christian Weiss

    29 Aug 11 at 13:59

  2. Da das Thema Vererbung vom Zend Framework hinzugefügt wurde solltest Du bei Zend zur gebrochenen Vererbung mal ein Ticket aufmachen (Ehre wem Ehre gebührt).

    Christian Weiss

    29 Aug 11 at 14:07

  3. @Christian: Vielleicht wird es ja in ZF 2.0 anders gelöst, wer weiß, ich habe noch nicht nachgeschaut. In der 1.x Version werden sie das Verhalten sicher nicht mehr ändern. Von daher ist die [] Notation bei mir aktuell die bessere Lösung.
    Ich finde es auch nicht so schlimm dass die Einträge aus „development“ nicht an die „production“ Einträge angehängt werden. Einträge in development, die auch in production vorhanden sind, werden überschrieben, so arbeitet diese Art von Vererbung nunmal. Dass hier ein Array mit einem anderen Array überschrieben wird ist ja meistens so gewollt.

    Aber du hast Recht, normalerweise steht [] für anhängen und nicht überschreiben, evtl. ist es etwas verwirrend, trotzdem aktuell die bessere Lösung (es sei denn du kennst noch eine dritte Möglichkeit).

    Michael Kliewe

    29 Aug 11 at 15:03

  4. >> Durch die Vererbungsregeln überschreibe ich also server.0, aber server.1 wird aus der production Sektion übernommen, das will ich aber nicht!

    Genau dieses Verhalten ist aber nachvollziehbar. Du erbst von [production] und überschreibst lediglich den ersten Eintrag. Der zweite wird daher natürlich unangetastet bleiben. Alles andere widerspricht dem Prinzip der Vererbung.

    Daniel S

    30 Aug 11 at 11:29

  5. @Daniel S: Das macht schon Sinn so wie es ist, das habe ich nicht bestritten, es ist so gesehen kein Bug. Aber in der Praxis kann man es so nicht gut nutzen wie oben zu sehen, man müßte auch server.1 überschreiben und dann im PHP-Code dieses leere Array-Element überspringen, das ist sehr unschön.
    Bei PHP-Vererbung würde man das ganze Array, das man erbt und ersetzen möchte, überschreiben können, hier geht das nicht so ohne weiteres, außer mit der [] Notation.

    Michael Kliewe

    30 Aug 11 at 11:59

  6. wenn du für development und production verschiedene Server hast, dann lass doch einfach die Vererbung und trage sie jeweils zu production ODER development ein. Wenn du natürlich im production noch zusätzliche Server zum Development brauchst, dann ist in der Tat nur die Version mit den Klammern sinnvoll. Alternativ könntest du auch server_dev und server_prod einzeln definieren und später bei bedarf mergen – oder eben nicht.

    Domi

    31 Aug 11 at 16:51

  7. Da ich noch nicht so der Zend-Kenner bin mal eine dumme Frage: Wie kommst du an $applicationIni bzw. was ist das für ein Objekt?

    Sascha Presnac

    4 Sep 11 at 22:20

  8. @Sascha: Die $applicationIni ist ein Zend_Config_Ini Objekt, das man bei einem Standard Zend Framework Projekt nutzt. Weitere Details hier:

    http://framework.zend.com/manual/en/zend.config.adapters.ini.html

    Michael Kliewe

    5 Sep 11 at 00:13

Leave a Reply

You can add images to your comment by clicking here.