• 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

[Zend Studio 10] Autovervollständigung fehlt

cSteusloff

New member
Hallo zusammen,


ich arbeite mich gerade durch die Tutorials von ZF2 und durch das Buch Zend Framework 2 von Ralf Eggert. Für die Entwicklung habe ich mir Zend Studio 10 besorgt, weil ich mir eine clevere Autovervollständigung für diese, mir fremde Welt erhofft habe.


Entweder liegt es an der IDE oder an meiner falschen Umsetzung, daher würde ich mich über Aussage von Erfahrenen Usern freuen.


Ich nehme einmal das Starter-Beispiel mit dem Album, dort wird für den Zugriff auf die Datenbank-Tabellen eine Factory genutzt. (siehe: framework.zend.com/manual/2.0/en/user-guide/database-and-models.html#using-servicemanager-to-configure-the-table-gateway-and-inject-into-the-albumtable)


Nun würde ich gern einen SQL-Befehl in der Datei: module/Album/src/Album/Model/AlbumTable.php ausführen. Dieser greift auf den Datenbank-Adapter zurück, welcher in der /config/autoload/global.php definiert ist.
PHP:
        //VarianteA:
        $resultSet = $this->tableGateway->select(array('status' => 1));
        
        //VarianteB:
        $select = $adapter = $this->tableGateway->getSql()->select();
        $select->where(array('status' => 1)); // keine Autovervollständigung
        $resultSet = $this->tableGateway->selectWith($select);
        
        
        //VarianteC:
        $adapter = $this->tableGateway->getSql()->getAdapter();
        $adapter->createStatement('SELECT * FROM album WHERE status = 1;')->execute(); // keine Autovervollständigung

Bei VarianteA fühle ich mich sehr eingeschränkt, was die Befehle angeht - oder ich habe etwas nicht verstanden.
Am sinnvollsten finde ich VarianteB, aber da ich dann keine Autovervollständigung habe finde ich es schwierig, fehlte diese einfach in Zend Studio 10 oder gehe ich den falschen Weg?


Ich hoffe jemand kann mich aufklären, gerade wenn es sich oft verschachtelt und man den Gedanken des Zend Framework 2 strikt folgt, verlässt einen die Autovervollständigung, was gerade mich als Anfänger oft verunsichert.


Vielen Dank im Voraus
 

Kaiuwe

Super-Moderator
Willkommen im Forum! :)
Für die Entwicklung habe ich mir Zend Studio 10 besorgt, weil ich mir eine clevere Autovervollständigung für diese, mir fremde Welt erhofft habe.
Das können auch andere IDEs, da ist man nicht auf ZS festgenagelt.

PHP:
        //VarianteA:
        $resultSet = $this->tableGateway->select(array('status' => 1));
        
        //VarianteB:
        $select = $adapter = $this->tableGateway->getSql()->select();
        $select->where(array('status' => 1)); // keine Autovervollständigung
        $resultSet = $this->tableGateway->selectWith($select);
        
        
        //VarianteC:
        $adapter = $this->tableGateway->getSql()->getAdapter();
        $adapter->createStatement('SELECT * FROM album WHERE status = 1;')->execute(); // keine Autovervollständigung
Bei VarianteA fühle ich mich sehr eingeschränkt, was die Befehle angeht - oder ich habe etwas nicht verstanden.
Hier fehlt dir eindeutig die automatische Codevervollständigung, denn als Parameter kannst du etwas mehr angeben. Die Methode selbst ist für schnelle „Select“-Abfragen, mit möglicher „Where“-Klausel, gedacht.

Am sinnvollsten finde ich VarianteB, aber da ich dann keine Autovervollständigung habe finde ich es schwierig
Hier fehlt dir wieder eindeutig die automatische Codevervollständigung, denn einen Adapter bekommst du hier nicht zurück!

Bei Variante C würde ich sagen, dass man eher selten den Adapter vom „TableGateway“-Objekt benötigt, denn mit „TableGateway“ hat man das Objekt schon auf eine Tabelle in der Datenbank festgelegt und da sollten (i.d.R.) auch die vorhanden Methoden dieser Klasse ausreichen. (den Adapter bekommst du auch einfach - automatische Codevervollständigung lässt grüßen! ;))

…fehlte diese einfach in Zend Studio 10 oder gehe ich den falschen Weg?
Ich kenne Zend Studio in den neueren Versionen nicht mehr, aber eine automatische Codevervollständigung ist auf jeden Fall vorhanden. Und diese beschränkt sich auch nicht nur auf bestimmte Frameworks wie ZF2, sondern ist immer vorhanden. Liegt also an irgendeiner Einstellung. Entweder ZS findet das Zend Framework nicht oder du hast dein Projekt nicht explizit als ZF-Projekt angelegt.

Ich hoffe jemand kann mich aufklären, gerade wenn es sich oft verschachtelt und man den Gedanken des Zend Framework 2 strikt folgt, verlässt einen die Autovervollständigung, was gerade mich als Anfänger oft verunsichert.
Du liegst schon ganz richtig, denn ohne automatische Codevervollständigung ist bei keinem Framework ein sinnvolles Programmieren möglich. (Ich würde nicht mal bei meinem eigenen Code darauf verzichten wollen.)
 
Zuletzt bearbeitet:

cSteusloff

New member
Danke für die schnelle Antwort, aber ich muss zum Verständnis noch mal nachfragen.

Der Weg über den Adapter ist also falsch, da "tableGateway" arbeit erspart und es einfacher gestaltet? Die Tabelle wird innerhalb der Module.php mit der AlbumTable verschmolzen, d.h. innerhalb AlbumTable kennt er die Datenbank-Tabelle und Abfragen werden strikt wie folgt ausgeführt:
PHP:
$this->tableGateway->select();
$this->tableGateway->update():
// usw.
Nur was erwartet diese Methode genau? Aus der Referenz (framework.zend.com/apidoc/2.1/classes/Zend.Db.TableGateway.TableGateway.html) werde ich nicht schlau.

Kannst du mir sagen, wie ich beispielsweise ein korrektes Update über TableGateway ausführe?

Bei folgendem Beispiel habe ich sogar eine Autovervollständigung, jedoch klappt es nicht - Fehler ist mir unbekannt:
PHP:
$this->tableGateway->update(function (Update $update){            
  $update->set(array('status' => 3));             
  $update->where->equalTo('id', $id);         
});
Meine Variante B klappt leider wieder nicht (zudem bekomme ich keine Vorschläge von der IDE):
PHP:
$update = $this->tableGateway->getSql()->update();
Debug::dump($update);
//$update->update(array('status' => 3));
//$update->where->equalTo('id', $id);
Ich würde mich freuen, wenn mir jemand zeigt, wie man dieses "tableGateway" korrekt nutzt, damit ich auch einsehe, dass es eine Erleichterung ist.
Was schön wäre, wenn man auch noch komplexe SQL-Befehle dort als SQL String schreiben kann. Geht das?
 
Zuletzt bearbeitet:

av3nger

New member
Zum tableGateway selbst kann ich jetzt nichts sagen, da ich Doctrine 2 verwende. Aber hinsichtlich der Autovervollständigung, die auch an anderen Stellen noch das Problem werden könnte: Wie wäre es mit einem Type Hint-Kommentar (oder wie die korrekte Bezeichnung dafür ist)? Also Beispielsweise folgendermaßen:

PHP:
/* @var $select Zend\Db\Sql\Select */
 $select = $adapter = $this->tableGateway->getSql()->select();
Denn dass hin und wieder keine Autovervollständigung möglich ist, kenne ich allzu gut. Zumindest NetBeans IDE weiß aufgrund des Kommentars dann, welche Methoden für diese Variable angeboten werden können. Müsste bei den anderen IDEs eigentlich auch funktionieren. Bei NetBeans wird mit Eingabe von vdoc sogar der Großteil der Schreibarbeit übernommen, sodass nur noch die Klasse eingetragen werden muss.
 

Kaiuwe

Super-Moderator
Der Weg über den Adapter ist also falsch, da "tableGateway" arbeit erspart und es einfacher gestaltet?
Genau!
Hier liegt ein Entwurfsmuster zu Grunde: „Table data gateway
Kurz gesagt, regelt ein „TableGateway“-Objekt den Zugriff (select, insert, update, …) auf eine Datenbanktabelle.

Die Tabelle wird innerhalb der Module.php mit der AlbumTable verschmolzen, d.h. innerhalb AlbumTable kennt er die Datenbank-Tabelle…
Mir persönlich gefällt dies nicht so ganz, aber das ist ein anderes Thema.

…und Abfragen werden strikt wie folgt ausgeführt:
PHP:
$this->tableGateway->select();
$this->tableGateway->update():
// usw.
Von „strikt“ kann nicht die Rede sein. Es gib keine festen Vorgaben und genau das ist deine Freiheit und zugleich dein Vorteil.

Nur was erwartet diese Methode genau? Aus der Referenz (framework.zend.com/apidoc/2.1/classes/Zend.Db.TableGateway.TableGateway.html) werde ich nicht schlau.

Kannst du mir sagen, wie ich beispielsweise ein korrektes Update über TableGateway ausführe?
So wie es in der API-Doku steht: (Beispiel für „array $set“ und „array $where“):
PHP:
$tableGateway->update(array('status' => 3), array('id' => $id));
Ich würde mich freuen, wenn mir jemand zeigt, wie man dieses "tableGateway" korrekt nutzt, damit ich auch einsehe, dass es eine Erleichterung ist.
Schau dir das Entwurfsmuster dazu an und versuche dies zu verstehen, dann kennst du auch den Einsatzzweck der Klasse.

Was schön wäre, wenn man auch noch komplexe SQL-Befehle dort als SQL String schreiben kann. Geht das?
Was verstehst du unter komplexen SQL-Befehle?

Bevor du aber weitergehst, bring zuerst die automatische Codevervollständigung zum Laufen! Ansonsten bringt das hier alles nichts! (Zwei Ansatzpunkte hatte ich bereits genannt. Hast du diese geprüft?)
 

Kaiuwe

Super-Moderator
Zum tableGateway selbst kann ich jetzt nichts sagen, da ich Doctrine 2 verwende. Aber hinsichtlich der Autovervollständigung, die auch an anderen Stellen noch das Problem werden könnte: Wie wäre es mit einem Type Hint-Kommentar (oder wie die korrekte Bezeichnung dafür ist)? Also Beispielsweise folgendermaßen:

PHP:
/* @var $select Zend\Db\Sql\Select */
 $select = $adapter = $this->tableGateway->getSql()->select();
Eher ist hier ein Kommentar zu ergänzen:
PHP:
<?php
namespace Album\Model;

use Zend\Db\TableGateway\TableGateway;

class AlbumTable
{
    /**
     * @var TableGateway
     */
    protected $tableGateway;
}
Database and models — Zend Framework 2 2.2.4 documentation - Zend Framework

@cSteusloff
Löst dies vielleicht schon dein Problem mit der automatischen Codevervollständigung?
 
Zuletzt bearbeitet:

cSteusloff

New member
Hallo,

Eher ist hier ein Kommentar zu ergänzen:
PHP:
<?php
namespace Album\Model;

use Zend\Db\TableGateway\TableGateway;

class AlbumTable
{
    /**
     * @var TableGateway
     */
    protected $tableGateway;
}
also ich habe mir deine Hinweise angesehen und die vdoc's helfen damit die Autovervollständigung vorhanden ist. - Danke

Aber "tableGateway" verwirrt mich, ich verstehe zwar den Nutzen - aber die Umsetzung innerhalb Module.php verstehe ich nicht. Da ich diese Factories nicht richtig verstanden haben, somit könnte ich sie für mehrere Datenbank-Tabelllen nicht erweitern.

Es wäre einfacher für mich, ich würde an den DB-Adapter kommen, welchen ich in /config/autoload/global.php definiert habe.

Ich finde dazu überall folgenden Code (welcher abgewandelt ja auch im Controller für AlbumTable zu finden ist)
PHP:
public function getAdapter()    {       
  if (!$this->adapter) {            
    $sm = $this->getServiceLocator();           
    $this->adapter = $sm->get('Zend\Db\Adapter\Adapter');        
  }       
  return $this->adapter;    
}
Nur wo kommt getServiceLocator() her? Wo muss ich diese Methode verwenden?

Wenn ich mit dem Controller eine Klasse aufrufe, welche Methoden bietet wie jetzt auch, nur das ich darin nicht das "tableGateway" nutze, wäre es ideal. Damit ich so etwas schreibe, wo ich alle Datenbank-Tabellen ansprechen kann:
PHP:
$sql = new Sql($adapter);
$select = $sql->select();
$select->join( // usw.
Natürlich kann ich über tableGateway mit selectWith($select) auch zu diesem Ziel kommen, aber dafür würde ich gern genau verstehen - wie es alles mit einander verschmolzen ist. Das fehlt mir momentan und ich finde keine gute Erklärung oder mir fehlt Vorwissen zu Zend an einer Stelle.

Wenn Ihr sagt tableGateway ist schon der bessere Weg nehme ich dies natürlich, schließlich möchte ich ja meine Horizont erweitern. Folgendes sollte ja auch gehen:
PHP:
$select = $this->tableGateway->getSql()->select()->join('join_table', 'gateway_table.id=join_table.link_id',array('viewfieldname'=>'joinfieldname'));
$resultSet = $this->tableGateway->selectWith($select);
Ich habe einfach das Problem, dass ich Jahrelang SQL-Befehle im Schlaf niedergeschrieben haben und ich bei dieser Syntax immer an meine Grenzen stoße. :( Am liebsten würde ich es einfach weiter alles per Hand schreiben, was die Befehle an geht.
 
Zuletzt bearbeitet:

Kaiuwe

Super-Moderator
Aber "tableGateway" verwirrt mich, ich verstehe zwar den Nutzen - aber die Umsetzung innerhalb Module.php verstehe ich nicht. Da ich diese Factories nicht richtig verstanden haben, somit könnte ich sie für mehrere Datenbank-Tabelllen nicht erweitern.
Da rennst du leider in eine falsche Richtung, denn ein TableGateway-Objekt regelt den Zugriff auf eine Datenbanktabelle oder -sicht.

Wenn ich mit dem Controller eine Klasse aufrufe, welche Methoden bietet wie jetzt auch, nur das ich darin nicht das "tableGateway" nutze, wäre es ideal. Damit ich so etwas schreibe, wo ich alle Datenbank-Tabellen ansprechen kann:
PHP:
$sql = new Sql($adapter);
$select = $sql->select();
$select->join( // usw.
Damit verfällst du wieder in alte Gewohnheiten und verheiratest zusätzlich die Datenbankabfragen mit deinem Kontroller. Vor allem wenn du ein und dieselbe Abfrage in verschiedenen Kontrollern ausführst, endest du beim Kopieren von Code.
Daher lagere die Datenbankabfragen aus. Eine (!) Variante ist dabei der Ansatz von „Table Data Gateway“.

Ich sehe noch ein anderes Problem in deiner Herangehensweise: du unterschlägst den entscheidenden Teil der Anwendung – das „Domain Model“. Es würde bei dir das gesamte „M“ einer MVC-Anwendung fehlen. Und du würdest bei deinen Datenbankabfragen über den Adapter immer nur allgemeine Objekte (z.B. „ArrayObject“, „ResultSet“) als Ergebnis erhalten. Ein definiertes Objekt wie „Album“ im „User Guide“ wäre damit nicht vorhanden.

Ich habe einfach das Problem, dass ich Jahrelang SQL-Befehle im Schlaf niedergeschrieben haben und ich bei dieser Syntax immer an meine Grenzen stoße. :( Am liebsten würde ich es einfach weiter alles per Hand schreiben, was die Befehle an geht.
Es will dich niemand von SQL abbringen, denn mit SQL sind feine und mächtige Sachen möglich. Es geht nur um eine saubere Struktur deiner Anwendung und die Vereinfachung bei Erweiterung dieser Anwendung. Nicht zu vergessen, das Arbeiten mit einem „Domain Model“.
Und wenn du SQL so gerne schreibst und dann öfter bei komplexen Abfragen landest, dann speichere diese einfach in der Datenbank und greife von PHP auf diese gespeicherte Abfrage – aka Sicht – zu. In PHP bleibt es schön übersichtlich und du musst SQL nicht den Rücken kehren. :D

Du merkst schon, ein Framework bringt viel Neues und scheinbar drängt es dich in eine bestimmte, dir unbekannte, Ecke. Aber keine Angst, die Richtungen stimmen.
Es soll auch hier noch mal gesagt sein: da es sich um ein echtes Framework handelt, musst du es nicht so umsetzen wie es im „User Guide“ oder irgendwo sonst steht. Verwende es wie du es möchtest und wenn du im Kontroller deine Datenbankabfragen über den Adapter abschießt und es funktioniert, dann freue dich. Lass dich aber auch vom Framework inspirieren, denn es wird versucht dir ein Werkzeug an die Hand zu geben, dass du strukturierte und saubere Anwendungen ermöglicht. Damit sind dann auch zukünftige Änderungen einfach zu integrieren, ohne Code zu kopieren oder gar ganze Teile umschreiben zu müssen.
 
Zuletzt bearbeitet:
Oben