• Jeder User im Forum verpflichtet sich zur Akzeptanz und zur Einhaltung dieser Regeln:
    1. Umgangston
      Ein angemessener höflicher Umgangston, ohne Beleidigungen, Beschimpfungen und aggressive Postings ist für jedes Mitglied Pflicht.
    2. Beiträge
      Jedes Mitglied sollte sich bemühen nur sinnvolle Beiträge zum Thema zu posten. Dabei ist unbedingt vorher zu prüfen, ob das Thema vorher schon einmal diskutiert wurde und daher fortgesetzt werden kann
      • Suchfunktion benutzen!
      • offizielle Doku lesen!
    3. Haftung
      Jeder Beitragsersteller übernimmt die alleinige Verantwortung seiner Inhalte.
    4. Werbung
      Wir erlauben keine Beiträge, Signaturen, Private Nachrichten oder eMails an Benutzer, die Werbung enthalten. Ausgenommen
      sind Stellengesuche /-angebote, welche ausschließlich im Forum "Stellengesuche" veröffentlicht werden dürfen.
    5. Verstöße
      Regelwidrige Beiträge sollten dem Team gemeldet werden. Nach deren Überprüfung werden wir schnellstmöglich
      entsprechend handeln.
    6. Authorität
      Den Anweisungen der Team-Mitglieder (Administratoren und Moderatoren) sind in diesem Forum Folge zu leisten.
      Bei Fragen oder Beschwerden bitte an diese wenden.
    Wir möchten Euch darauf aufmerksam machen, dass es bei Verstößen gegen einen oder mehreren der oben genannten
    Punkte dem Team frei steht entsprechend zu handeln. Dies kann z.B. das Löschen eines Beitrags, das Ausschliessen bzw.
    Sperren von Mitgliedern oder aber lediglich eine Verwarnung sein.

    In diesem Zusammenhang sollte erwähnt werden, dass das Forum automatisch die IP-Adresse jedes Beitrag-Erstellers
    speichert. Bei schweren Vergehen, behalten wir es uns vor, die IP-Adresse zur Strafverfolgung weiterzugeben.
  • Willkommen im Zend Framework Forum

    ZF1 Zend Framework 1 + ZF2 Zend Framework 2

    Das Zend Framework Forum ist seit 2006 die erste Anlaufstelle für Zend Framework Entwickler in Deutschland. Mit über 70.000 Beiträgen und einer steigenden Nutzerzahl bietet das Forum hilfreiche Themen und ZF-Tutorials für professionelle Entwickler, fortgeschrittene Programmierer sowie Zend Framework Einsteiger.
    Wenn dies Dein erster Besuch in der Zend Framework Community ist, lies bitte zuerst die Hilfe - FAQ durch. Du musst Dich registrieren, bevor Du Beiträge verfassen kannst. Klicke oben auf 'Registrieren', um die Registrierung zu starten. Du kannst auch jetzt schon Beiträge lesen. Hier im Forum findest Du die Zend Framework Hilfe, die Du suchst!

    Grüße an alle Zend Framework Entwickler. Das Team vom Zend Framework Forum!

    Drupal Agentur

Problem mit Modulreihenfolge in 'modules' und der Datenbankverbindung

gulaschsuppe

New member
Hallo,

ich habe folgendes Problem ich habe zwei (bzw. drei) Module:
PHP:
// Filename: /config/application.config.php
    'modules' => array(
        'Application',
        'Album',
        'Blog'
    ),
da ich wamp 2.5 benutze und ein Skeleton-Application-Projekt mit composer erstellt habe befinden sich diese Module in:
Code:
www\firstApplication\module
Die Module haben im config Ordner folgende Datenbankangaben:
PHP:
// Filename: /module/Blog/config/module.config.php
 return array(
     'db' => array(
         'driver'         => 'Pdo',
         'username'       => 'root',  //edit this
         'password'       => '',  //edit this
         'dsn'            => 'mysql:dbname=blog;host=localhost',
         'driver_options' => array(
             \PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
         )
     ),
      'service_manager' => array(
         'factories' => array(
             'Blog\Mapper\PostMapperInterface'   => 'Blog\Factory\ZendDbSqlMapperFactory',
             'Blog\Service\PostServiceInterface' => 'Blog\Factory\PostServiceFactory',
             'Zend\Db\Adapter\Adapter' => 'Zend\Db\Adapter\AdapterServiceFactory'
         )
     ),
...
PHP:
 // Filename: /module/Album/config/module.config.php
return array(
     'db' => array(
         'driver'         => 'Pdo',
         'username'       => 'root',  //edit this
         'password'       => '',  //edit this
         'dsn'            => 'mysql:dbname=zf2tutorial;host=localhost',
         'driver_options' => array(
             PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
            )
         ),
      'service_manager' => array(
         'factories' => array(
            'Zend\Db\Adapter\Adapter' => 'Zend\Db\Adapter\AdapterServiceFactory',
         ),
     ),
...
Ich habe bewusst die service_manager-Einstellung mit gepostet. Vielleicht sind diese ja für das Problem verantwortlich:

Und zwar öffne ich die Module mit folgenden Links:
Album:
Code:
localhost/firstApplication/public/album
Blog:
Code:
localhost/firstApplication/public/blog
Wenn ich jetzt die Links einzelnt Aufrufe funktioniert public/blog wunderbar doch beim module Album kommt folgender Fehler:
Code:
[B]An error occurred[/B]

[B]Additional information:[/B]

 [B]Zend\Db\Adapter\Exception\InvalidQueryException[/B]

 File:         F:\Program Files\wamp\www\firstApplication\vendor\zendframework\zend-db\src\Adapter\Driver\Pdo\Statement.php:244     Message:         Statement could not be executed (42S02 - 1146 - Table 'blog.album' doesn't exist)
Das bedeutet, dass das framework eine Referenz auf die Datenbank des anderen Moduls hat. Wenn ich jetzt die Reihenfolge in der application.config.php ändere...
PHP:
    'modules' => array(
        'Application',
        'Blog',
        'Album'
    ),
...funktioniert das Modul Album und indem Modul Blog erscheint folgender Fehler:
Code:
[B]An error occurred[/B]

[B]Additional information:[/B]

 [B]Zend\Db\Adapter\Exception\InvalidQueryException[/B]

 File:         F:\Program Files\wamp\www\firstApplication\vendor\zendframework\zend-db\src\Adapter\Driver\Pdo\Statement.php:244     Message:         Statement could not be executed (42S02 - 1146 - Table 'zf2tutorial.posts' doesn't exist)
Ich habe absolut keine Ahnung wie die Reihenfolge hier darüber ausschlaggebend ist, welches Modul wie geladen wird und voreindingen, wie die einzelnen Module eine Referenz aufeinander haben. Mein einziger Ansatzpunkt sind die Module.php Dateien in den Modulen:
PHP:
     public function getAutoloaderConfig()
     {
         return array(
             'Zend\Loader\StandardAutoloader' => array(
                 'namespaces' => array(
                     __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
                 )
             )
         );
     }

     public function getConfig()
     {
         return include __DIR__ . '/config/module.config.php';
     }
Liegt es vielleicht an dem StandardAutoloader, sodass einer schneller geladen wird als der Andere?

Ich wäre wirklich dankbar für eure Hilfe
 
Zuletzt bearbeitet:

Kaiuwe

Super-Moderator
Willkommen im Forum! :)
Liegt es vielleicht an dem StandardAutoloader, sodass einer schneller geladen wird als der Andere?
Du gehst hier leider von einer falschen Annahme aus, denn es werden bei jedem Aufruf immer alle Modulkonfigurationen eingelesen und dabei zusammengeführt. (Siehe dazu auch in der Doku zum „Module Manager“ und im Tutorial „Advanced Configuration Tricks“)

Wenn du mehrere Datenbanken verwenden möchtest, dann könntest du eine abstrakte Fabrik erstellen.

Zwei Hinweise noch:
PHP:
'driver_options' => array(
    \PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
)
Weg damit und die Angabe „charset“ im DSN verwenden.

PHP:
'Blog\Mapper\PostMapperInterface'   => 'Blog\Factory\ZendDbSqlMapperFactory',
'Blog\Service\PostServiceInterface' => 'Blog\Factory\PostServiceFactory',
Wieso wird ein „Interface“ auf eine „Factory“ verwiesen? Was hat ein „Interface“ überhaupt in der Konfiguration verloren?
 
Zuletzt bearbeitet:

gulaschsuppe

New member
Vielen Dank für die Antwort.

Was ich unerwähnt gelassen habe ist, dass der Code aus den beiden Tutorials der ZendFramework-Doku stammen die als PDF und im Web zugänglich ist.

Wenn du mehrere Datenbanken verwenden möchtest, dann könntest du eine abstrakte Fabrik erstellen.
Laut ZendFramework-Doku gilt für Factories:
A factory is a class that creates instances of another class.
Daher versteh ich nicht ganz den Zusammenhang zur Datenbank. Im übrigen ging es mir im wesentlichen um den oben beschriebenen Konflikt. Gibt es denn keine klare Begründung warum die Reihenfolge der Angabe in der application.config.php entscheidend ist bzw. wie eine Datenbankreferenz auf ein anderes Modul entsteht ?

Weg damit und die Angabe „charset“ im DSN verwenden.
Hab ich notiert. Da scheint das Tut nicht auf dem neusten Stand:
framework.zend.com/manual/current/en/in-depth-guide/zend-db-sql-zend-stdlib-hydrator.html#quick-facts-zend-db-sql

Wieso wird ein „Interface“ auf eine „Factory“ verwiesen? Was hat ein „Interface“ überhaupt in der Konfiguration verloren?
Da Verweis ich ebenfalls auf das Tutorial:
framework.zend.com/manual/current/en/in-depth-guide/zend-db-sql-zend-stdlib-hydrator.html#writing-the-mapper-implementation

Ich arbeite derzeit noch mit den Tutorials. Eigentlich hatte ich nicht vor die großartig zu modifizieren. Ich möchte Grundlegend erstmal die Struktur und die Abhängigkeiten einzelner Dateien, sowie die zu den Frameworks verstehen. Falls jemand noch andere bzw. bessere Tutorials oder auch Literatur kennt die besser bzw. ergänzend zu den von der Website framework.zend.com kennt bin ich dafür gerne offen.
 

Kaiuwe

Super-Moderator
Was ich unerwähnt gelassen habe ist, dass der Code aus den beiden Tutorials der ZendFramework-Doku stammen die als PDF und im Web zugänglich ist.
Gut zu wissen.


Laut ZendFramework-Doku gilt für Factories:
Daher versteh ich nicht ganz den Zusammenhang zur Datenbank.
Schau dir mal die Klasse „Zend\Db\Adapter\AdapterServiceFactory“, denn diese erstellt dir einen Datenbankadapter. Mit einer abstrakten Fabrik kannst du zwei unterschiedliche Adapter erstellen lassen, die sich jeweils mit einer anderen Datenbank verbinden.

Im übrigen ging es mir im wesentlichen um den oben beschriebenen Konflikt. Gibt es denn keine klare Begründung warum die Reihenfolge der Angabe in der application.config.php entscheidend ist bzw. wie eine Datenbankreferenz auf ein anderes Modul entsteht ?
Nochmal: du verrennst dich hier. Da die Konfigurationen zusammengeführt werden, überschreiben sich die Angaben „db“ aus deinen beiden Modulen. Dabei ist es egal welches Modul aufgerufen wurde, denn es werden immer alle Konfigurationen eingelesen.
 

gulaschsuppe

New member
Wieso wird ein „Interface“ auf eine „Factory“ verwiesen? Was hat ein „Interface“ überhaupt in der Konfiguration verloren?
Das gesamte In-depth Tutorial ist auf diesem Prinzip aufgebaut. So wird zum Beispiel in der Klasse ListControllerFactory mit dem ServiceLocator dieses Interface genutzt:

PHP:
class ListControllerFactory implements FactoryInterface
 {
     /**
      * Create service
      *
      * [At]param ServiceLocatorInterface $serviceLocator
      *
      * [At]return mixed
      */
     public function createService(ServiceLocatorInterface $serviceLocator)
     {
         $realServiceLocator = $serviceLocator->getServiceLocator();
         $postService        = $realServiceLocator->get('Blog\Service\PostServiceInterface');

         return new ListController($postService);
     }
 }
Wenn ich das hier richtig verstehe wird hier mit $realServiceLocator->get die Klasse PostServiceFactory aufgerufen, die dann einen PostService zurück gibt:
PHP:
class PostServiceFactory implements FactoryInterface
 {
     /**
      * Create service
      *
      * [At]param ServiceLocatorInterface $serviceLocator
      * [At]return mixed
      */
     public function createService(ServiceLocatorInterface $serviceLocator)
     {
         return new PostService(
             $serviceLocator->get('Blog\Mapper\PostMapperInterface')
         );
     }
 }
Oder ist meine Annahme Falsch?

Denn dann müsste ich mit dem Verständnis des Ganzen wohl von vorn anfangen.


Was ist denn so falsch an dem Ansatz mit den Interfaces?

Letztendlich werden dadurch Komplikationen bei Entwicklung mit mehreren Personen vermieden, da jemand der in die module.config.php schaut sieht, dass hier auf ein Interface verwiesen wird. Er schaut ins Interface und weiß, was er erwartet, schaut dann noch in die Factory-Klasse und kann ohne die eigentliche Klasse trotzdem weiterarbeiten.

Oder habe ich hier etwas nicht verstanden ?
 

Kaiuwe

Super-Moderator
Was ist denn so falsch an dem Ansatz mit den Interfaces?
Der Vorgang ist schon klar und an Interfaces ist absolut nichts falsch, ganz im Gegenteil. Ich hätte nur im "Service Locator" nicht auf ein Interface verwiesen, denn das will hier keiner abrufen, sondern ein Objekt, welches dieses Interfaces implementiert.
Ich persönlich empfinde dies eher als Irreführung, denn ich möchte "Blog\Service\PostService" und nicht ein Interface. Könnte man aber in die Kiste für "Geschmackssachen" stecken. ;)

(Lass dich dadurch aber nicht ablenken. Ich selbst kenne die Doku und auch die Tutorials nicht auswendig und es war mir bisher auch nicht aufgefallen, dass hier auf Interfaces verwiesen wird. Hauptsache du hast die Sache verstanden, denn damit hast du schon mal eine Art Masterplan.)
 
Oben