Contao-Camp 2024
Ergebnis 1 bis 20 von 20

Thema: Datenbank in Controller verwenden

  1. #1
    Contao-Nutzer
    Registriert seit
    07.12.2019.
    Beiträge
    147

    Standard Datenbank in Controller verwenden

    Hallo Community,

    ich würde gerne in einem Controller auf die Datenbank zugreifen.

    Normalerweise mache ich das in Templates über $this->import('Database').

    Ich habe nun in meinem Controller schon sämtliches versucht. Habe Services angelegt die \System extenden, aber finde keinen Weg, wie ich in einem Controller Zugriff auf die Datenbank-Klassen erhalte.

    Folgende Umsetzung wirft einen Fehler:
    PHP-Code:
    $result = \Database::getInstance()->prepare("SELECT * FROM tl_log")->execute(); 
    Fehler:
    Code:
    Attempted to load class "Database" from the global namespace.
    Did you forget a "use" statement?
    Wenn ich ein use-Statement verwende, bekomme ich folgenden Fehler:
    Code:
    Call to a member function get() on null
    Hättet ihr einen Tipp für mich?

  2. #2
    Contao-Urgestein Avatar von fiedsch
    Registriert seit
    09.07.2009.
    Ort
    München
    Beiträge
    2.935

    Standard

    Du verwendest use Contao\Database ?
    Contao-Community-Treff Bayern: http://www.contao-bayern.de

  3. #3
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    33.896
    Partner-ID
    10107

    Standard

    PHP-Code:
    // src/Controller/MyController.php
    namespace App\Controller;

    use 
    Doctrine\DBAL\Connection;
    use 
    Symfony\Component\HttpFoundation\Request;
    use 
    Symfony\Component\HttpFoundation\Response;

    class 
    MyController
    {
        private 
    $db;

        public function 
    __construct(Connection $db)
        {
            
    $this->db $db;
        }

        public function 
    myAction(Request $request): Response
        
    {
            
    $dbResult $this->db->executeQuery(/* … */)->fetchAll();

            
    // …
        
    }


  4. #4
    Contao-Nutzer
    Registriert seit
    07.12.2019.
    Beiträge
    147

    Standard

    Top, wie immer Spooky. Besten Dank!

  5. #5
    Contao-Nutzer Avatar von lleitner
    Registriert seit
    24.07.2020.
    Beiträge
    16

    Standard

    Zitat Zitat von Spooky Beitrag anzeigen
    PHP-Code:
    // src/Controller/MyController.php
    namespace App\Controller;

    use 
    Doctrine\DBAL\Connection;
    use 
    Symfony\Component\HttpFoundation\Request;
    use 
    Symfony\Component\HttpFoundation\Response;

    class 
    MyController
    {
        private 
    $db;

        public function 
    __construct(Connection $db)
        {
            
    $this->db $db;
        }

        public function 
    myAction(Request $request): Response
        
    {
            
    $dbResult $this->db->executeQuery(/* … */)->fetchAll();

            
    // …
        
    }

    Hey Spooky mein allwissendes Orakel
    Ich bräuchte ihr auch Hilfe:

    Will eine REST-API Extension für private Zwecke machen.
    Habe die Extension schon mal so weit inkludiert, dass die Route <URL>/compare funktioniert und auf meinen Controller springt.
    Ich will jetzt eine einfach DB abfrage machen, einfach wegen Lernzwecke, über:

    PHP-Code:
    use Contao\Database;
    use 
    Contao\Model;
    class 
    IsotopeProductModel extends Model
    {
        protected static 
    $strTable 'tl_iso_product';

        public static function 
    getAllProducts(){
            return 
    Database::getInstance()->prepare("SELECT * FROM tl_iso_product")->execute();
            
    #return static::findAll();
        
    }


    Ich bekomm hier immer im Debug-Modus dann folgenden Fehler:
    Call to a member function get() on null.

    Bei deiner Variante werd ich nicht ganz schlau (sorry, bin noch ein Junior-Entwickler). Dort hast du im Kontruktor ein Connection Objekt.
    Woher bekomme ich das Objekt? Falls das, das Database::getInstance() sein soll, bekomme ich den gleichen Fehler wie oben erwähnt.

  6. #6
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    33.896
    Partner-ID
    10107

    Standard

    In Contao Models kannst du nicht Dependency Injection verwenden. Da müsstest du, wenn du die Datenbank Verbindung holen willst, mit System::getContainer()->get() arbeiten.

  7. #7
    Contao-Nutzer Avatar von lleitner
    Registriert seit
    24.07.2020.
    Beiträge
    16

    Standard

    PHP-Code:
     $db System::getContainer()->get('database_connection');
    return 
    $db->prepare("SELECT * FROM tl_iso_product")->execute(); 
    Meinst du so ca.?
    (gleicher Fehler)

  8. #8
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    33.896
    Partner-ID
    10107

    Standard

    Poste den gesamten Code.

  9. #9
    Contao-Nutzer Avatar von lleitner
    Registriert seit
    24.07.2020.
    Beiträge
    16

    Standard

    PHP-Code:
    <?php


    namespace marklweb\IsotopeRestApi\Models;
    use 
    Contao\Database;
    use 
    Contao\Model;
    use 
    Contao\System;
    class 
    IsotopeProductModel extends Model
    {
        protected static 
    $strTable 'tl_iso_product';

        public static function 
    getAllProducts(){
            
    #$db = System::getContainer()->get('database_connection');
            #$db = \Contao\System::getContainer()->get('database_connection');
            #$db = Database::getInstance();
            #return static::findAll();
        
    }

    }
    Keiner der Kommentare hat geklappt.
    Also die Database::getInstance() oder System::getContainer() ist null. Soweit ich die Fehlermeldung verstanden habe:

    Resources/contao/library/Contao/Database.php (line 91) : Call to a member function get() on null
    PHP-Code:
    else
            {
                
    $this->resConnection System::getContainer()->get('database_connection');
            } 
    Ich würde nämlich gerne die Tabelle tl_iso_product komplett auslesen. Um einfach einmal eine DB Verbindung zu sehen.

  10. #10
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    33.896
    Partner-ID
    10107

    Standard

    Hast du in deinem Controller das Contao Framework initialisiert?

  11. #11
    Contao-Nutzer Avatar von lleitner
    Registriert seit
    24.07.2020.
    Beiträge
    16

    Standard

    PHP-Code:
    <?php


    namespace marklweb\IsotopeRestApi\Controller;

    use 
    Contao\Database;
    use 
    Symfony\Bundle\FrameworkBundle\Controller\Controller;
    use 
    Symfony\Component\HttpFoundation\Response;
    use 
    Symfony\Component\HttpFoundation\Request;

    use 
    marklweb\IsotopeRestApi\Models\IsotopeProductModel;

    class 
    RouteController extends Controller
     
    {
      public function 
    init(){
            
    $products IsotopeProductModel::getAllProducts();
         
     }
    }
    routing.yml
    PHP-Code:
    compareproducts:
      
    path: /compareproducts
      defaults
    :
        
    _controllermarklweb\IsotopeRestApi\Controller\RouteController:init
        _scope
    frontend
        _token_check
    false 
    explizit nicht ._. Hab ich was übersehen? Hätte bei den ganzen Dokus, Skeleton-Bundles und sonst welche Beispiele nichts was arg anders ist gefunden.

  12. #12
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    33.896
    Partner-ID
    10107

    Standard

    Wenn du Legacy Funktionalität aus Contao benutzt (darunter fallen auch Models), musst du das Contao Framework initialisieren (außerhalb des reinen Contao Contexts): https://docs.contao.org/dev/referenc...ontaoframework

  13. #13
    Contao-Nutzer Avatar von lleitner
    Registriert seit
    24.07.2020.
    Beiträge
    16

    Standard

    Aha, interessant, dass die Models als legacy eingestuft worden sind.

    Das macht dann natürlich Sinn. Aber wo genau initialisiere ich das Framework dann?
    Und das ContaoFramework Objekt verlangt doch beim init diverse Parameter.
    Gibt es wo eine gutes Beispiel für eine Art von Anwendung.

    Oder noch besser. Wenn man Models nicht mehr verwendet, wie würdet ihr dann so eine simple REST-API aufbauen?
    - paar Routen wo jeweils DB-Abfragen durchgeführt werden und JSON zurückgesendet werden.
    Wir wollen gar nicht mehr.

  14. #14
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    33.896
    Partner-ID
    10107

    Standard

    Zitat Zitat von lleitner Beitrag anzeigen
    Aha, interessant, dass die Models als legacy eingestuft worden sind.
    Grundsätzlich sind alle Klassen aus Contao 3 "Legacy" . Für vieles gibt es halt noch keinen modernen Ersatz. Mit jeder Minor Version kommen da neue Dinge hinzu. Die Models zu ersetzen ist ein größerer Brocken.


    Zitat Zitat von lleitner Beitrag anzeigen
    Das macht dann natürlich Sinn. Aber wo genau initialisiere ich das Framework dann?
    Irgendwann, bevor du Dinge aus dem Legacy Framework brauchst. Also bspw. direkt vor deinem Model Aufruf.


    Zitat Zitat von lleitner Beitrag anzeigen
    Und das ContaoFramework Objekt verlangt doch beim init diverse Parameter.
    Nein, was genau meinst du hier? $this->framework->initialize(); reicht.


    Zitat Zitat von lleitner Beitrag anzeigen
    Gibt es wo eine gutes Beispiel für eine Art von Anwendung.
    In meinem Link siehst du ein Beispiel.


    Zitat Zitat von lleitner Beitrag anzeigen
    Oder noch besser. Wenn man Models nicht mehr verwendet, wie würdet ihr dann so eine simple REST-API aufbauen?
    Der moderne Symfony Weg wären Entities und Repositories as Services. In diesen Repository Services kannst du dann beliebige Hilfsfunktionen einbauen (also genau die Hilfsfunktionen, die aktuell in den Models verbaut sind). Und da es Services sind, kannst du ganz normal Dependency Injection benutzen.


    Zitat Zitat von lleitner Beitrag anzeigen
    - paar Routen wo jeweils DB-Abfragen durchgeführt werden und JSON zurückgesendet werden.
    Wir wollen gar nicht mehr.
    Bau dir halt ansonsten einen Sevice, der direkte Datenbank Abfragen macht. Brauchst du unbedingt die Models dazu? Eventuell ja nicht, wenn am Schluss dann eh nur ein JSON rauskommen soll.

  15. #15
    Contao-Nutzer Avatar von lleitner
    Registriert seit
    24.07.2020.
    Beiträge
    16

    Standard

    Okey, vieeelen Dank für deine Bemühungen Spookey!

  16. #16
    Contao-Nutzer Avatar von lleitner
    Registriert seit
    24.07.2020.
    Beiträge
    16

    Standard

    Falls es wem interessiert, der entscheidende Fehler war, dass ich den Service nicht richtig geladen habe.

    service.yml richtig:
    PHP-Code:
    company\IsotopeRestApi\Controller\RouteController:
        
    arguments:
          - 
    '@contao.framework'
        
    public: true 
    Nach wirklich aufmerksamen durchlesen von der Symfony/Contao Doku verstehe ich nun, dass die DI automatisch regelt wird.
    Jetzt kann im Kontruktor das Framework und nun alles andere initialisiert oder verwendet werden.

  17. #17
    Contao-Nutzer Avatar von Kahru
    Registriert seit
    20.06.2009.
    Ort
    Nordschwarzwald
    Beiträge
    200
    Partner-ID
    2067

    Standard Controller und Zugriff auf die DB

    Hallo,

    hänge an der gleichen Stelle. Normales Ajax geht, aber ich bekomme in der 4.9 keinen Zugriff auf die DB. Auch mit dem Code unten nicht. Es kommt Error 500 sobald ich den __construct (auch ohne Inhalt) einbinde. In der 4.4 funktioniert derselbe Code seit Monaten problemlos. Könnte mir da jemand mal einen Tipp geben bitte.

    Bernard

    Zitat Zitat von Spooky Beitrag anzeigen
    PHP-Code:
    // src/Controller/MyController.php
    namespace App\Controller;

    use 
    Doctrine\DBAL\Connection;
    use 
    Symfony\Component\HttpFoundation\Request;
    use 
    Symfony\Component\HttpFoundation\Response;

    class 
    MyController
    {
        private 
    $db;

        public function 
    __construct(Connection $db)
        {
            
    $this->db $db;
        }

        public function 
    myAction(Request $request): Response
        
    {
            
    $dbResult $this->db->executeQuery(/* … */)->fetchAll();

            
    // …
        
    }


  18. #18
    Contao-Nutzer Avatar von alexgr
    Registriert seit
    01.10.2012.
    Beiträge
    69

    Standard

    Zitat Zitat von Kahru Beitrag anzeigen
    Es kommt Error 500 sobald ich den __construct (auch ohne Inhalt) einbinde.
    Schalte im Backend den Debug-Modus ein (Schaltfläche in der Leiste ganz oben), damit Du eine Fehlermeldung bekommst; vielleicht hilft deren Inhalt dann schon weiter.

  19. #19
    Contao-Nutzer Avatar von Kahru
    Registriert seit
    20.06.2009.
    Ort
    Nordschwarzwald
    Beiträge
    200
    Partner-ID
    2067

    Standard

    Hallo,

    danke für die Antwort. Da wird nix konkretes angezeigt. Ich vermute mal die Klasse wird in 4.9 nicht mehr automatisch korrekt geladen. Hinzufügen meiner Klasse in die services.yml ist wohl das Stichwort?! Was trage ich da konkret ein? Die Contao-Hilfe hat mich leider nicht schlauer gemacht ...

    Bernard

  20. #20
    Contao-Nutzer Avatar von Kahru
    Registriert seit
    20.06.2009.
    Ort
    Nordschwarzwald
    Beiträge
    200
    Partner-ID
    2067

    Standard

    Hallo am Sonntag,

    falls beim Registrieren der services.yml auch nochmals jemand seine Zeit verplempert. Meine Lösung war hier zu finden

    https://community.contao.org/de/show...ency-Injection

    Ich hatte auch den Vendornamen mit drin. Den weggelassen und der Service ist korrekt registriert

    Bernard

Aktive Benutzer

Aktive Benutzer

Aktive Benutzer in diesem Thema: 3 (Registrierte Benutzer: 0, Gäste: 3)

Lesezeichen

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •