Ergebnis 1 bis 8 von 8

Thema: DB Abfrage ohne Escapen?

  1. #1
    Contao-Nutzer
    Registriert seit
    18.11.2009.
    Ort
    Köln
    Beiträge
    77

    Standard DB Abfrage ohne Escapen?

    Ich habe wieder ein für mich bisher unlösbares Problem.

    PHP-Code:
    $dsatz $this->Database->prepare("SELECT pid, alias, headline, stichzeile, teaser, singleSRC, alt FROM tl_news WHERE `date` > UNIX_TIMESTAMP(DATE_ADD(CURDATE(),INTERVAL -180 DAY)) AND keywort != '' AND `id` != '".$this->id."' AND `published` = '1' ? ORDER BY `date` DESC LIMIT 6")->execute($sql2); 
    die $sql2 sieht in etwas so aus
    PHP-Code:
    AND (KEYWORT like '%Corporate%' OR KEYWORT like '%Fix%' OR KEYWORT like '%Fox%'
    diese wird Dynamisch generiert!

    Grundsäzlich funktioniert diese Konstruct. Jedoch wird der $sql2 String am Anfang/Ende Escaped. Somit funktioniert meine Abfrage nicht mehr.

    Baue ich das ganze nicht in einem Database->prepare sondern in einem Database->execute bekomme ich zum Teil einen Error, weshalb ich es jetzt mit der "prepare" Methode versuchen möchte.

    Kann mir jemand sagen wie ich das Escapen verhindern kann.
    php 7.2, mySQL 5.7, 4.4.12

  2. #2
    Contao-Urgestein Avatar von cliffparnitzky
    Registriert seit
    08.10.2010.
    Ort
    Lüneburg
    Beiträge
    2.452
    User beschenken
    Wunschliste
    Contao-Projekt unterstützen

    Support Contao

    Standard

    Moin,

    das "escapen" sollte man nicht verhindern ... das ist da drin und das ist auch gut so.

    Das prüft den Datentyp der Übergabeparameter und sorgt dann dafür, dass der richtig in die Query eingebaut wird. Damit vermeidet man z.B. "sql injection".

    Also, nicht die Sicherheit rausbauen ... sondern deine Query umbauen.

    Du kannst dir ja auch nen String dynamisch zusammenbauen und den dann in die prepare-Methode übergeben.

    Gruß, Cliff

  3. #3
    Contao-Nutzer
    Registriert seit
    18.11.2009.
    Ort
    Köln
    Beiträge
    77

    Standard

    Ich möchte das Escapten ja nur in diesem einen Fall auslassen.

    Aber dann hier der gesamte Code:
    PHP-Code:
        $teil explode(",",$this->keywort);
        
    $teilcount count($teil)-1;
            foreach (
    $teil as $key => $wert) {
                if (
    $key == 0)            { $sql2  "AND (KEYWORT like '%".trim($wert)."%'";}
                if (
    $key >= 1)            { $sql2 .= " OR KEYWORT like '%".trim($wert)."%'";}
                if (
    $key == $teilcount)    { $sql2 .= ") ";}

    PHP-Code:
    $dsatz $this->Database->prepare("SELECT pid, alias, headline, stichzeile, teaser, singleSRC, alt FROM tl_news WHERE `date` > UNIX_TIMESTAMP(DATE_ADD(CURDATE(),INTERVAL -180 DAY)) AND keywort != '' AND `id` != '".$this->id."' AND `published` = '1' ? ORDER BY `date` DESC LIMIT 6")->execute($sql2); 
    Baue ich $sql2 anstelle des ? sofort ein, bekomme ich meist einen Contao-Error. (Nicht immer)

    Mir fehlt jedoch zur Zeit die Phantasie wie ich es anders aufbauen könnte.
    php 7.2, mySQL 5.7, 4.4.12

  4. #4
    Contao-Urgestein Avatar von cliffparnitzky
    Registriert seit
    08.10.2010.
    Ort
    Lüneburg
    Beiträge
    2.452
    User beschenken
    Wunschliste
    Contao-Projekt unterstützen

    Support Contao

    Standard

    Hmm, den Error wirst du dann wohl bekommen, weil die Query manchmal nicht korrekt zusammengesetzt ist.

    Also, meine Empfehlung: nimm dir die halbe Stunde Zeit für die richtige Query !!!

    Gruß, Cliff

  5. #5
    Contao-Nutzer
    Registriert seit
    18.11.2009.
    Ort
    Köln
    Beiträge
    77

    Standard

    Den Query lasse ich mir immer separat ausgeben. Der stimmt (scheinbar/leider) immer.
    Ich kann es mir nur so erklären das Contao da irgendwie was fitert oder verlangt.

    Ich bin jetzt wirklich schon Stunden am probieren. Wie gesagt als Execute bekomme ich in seltenen Fällen eine Error-Meldung mir Prepare bekomme ich nie eine Fehlermeldung aber die (' ') stören.

    Code:
    Fatal error: Uncaught exception Exception with message Too few arguments to build the query string thrown in /var/www/system/libraries/Database.php on line 717
    php 7.2, mySQL 5.7, 4.4.12

  6. #6
    Contao-Nutzer
    Registriert seit
    03.09.2009.
    Ort
    Baunatal
    Beiträge
    122
    Partner-ID
    6087

    Standard

    PHP-Code:
    $this->Database->query() 
    sollte die Abfrage direkt an die DB senden.

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

    Standard

    Zitat Zitat von Swiper Beitrag anzeigen
    Ich möchte das Escapten ja nur in diesem einen Fall auslassen.

    Aber dann hier der gesamte Code:
    PHP-Code:
        $teil explode(",",$this->keywort);
        
    $teilcount count($teil)-1;
            foreach (
    $teil as $key => $wert) {
                if (
    $key == 0)            { $sql2  "AND (KEYWORT like '%".trim($wert)."%'";}
                if (
    $key >= 1)            { $sql2 .= " OR KEYWORT like '%".trim($wert)."%'";}
                if (
    $key == $teilcount)    { $sql2 .= ") ";}

    PHP-Code:
    $dsatz $this->Database->prepare("SELECT pid, alias, headline, stichzeile, teaser, singleSRC, alt FROM tl_news WHERE `date` > UNIX_TIMESTAMP(DATE_ADD(CURDATE(),INTERVAL -180 DAY)) AND keywort != '' AND `id` != '".$this->id."' AND `published` = '1' ? ORDER BY `date` DESC LIMIT 6")->execute($sql2); 
    Baue ich $sql2 anstelle des ? sofort ein, bekomme ich meist einen Contao-Error. (Nicht immer)

    Mir fehlt jedoch zur Zeit die Phantasie wie ich es anders aufbauen könnte.
    Uff, also das macht ja alles gar keinen Sinn . Ohne zu hinterfragen, was dein Code eigentlich macht und ob das nicht alles sinnvoller geht, hier die "richtige" Variante:
    PHP-Code:
    // build query string
    $query "SELECT pid, alias, headline, stichzeile, teaser, singleSRC, alt 
              FROM tl_news 
              WHERE `date` > UNIX_TIMESTAMP(DATE_ADD(CURDATE(),INTERVAL -180 DAY)) 
                AND keywort != '' 
                AND `id` != ? 
                AND `published` = '1'"
    ;

    // prepare parameters and add id
    $values = array( $this->id );

    // search keywor*D*s
    $keywords explode(','$this->keywort);
    if( 
    count$keywords ) > )
    {
        
    $query.= ' AND (' implode(' OR 'array_map( function( $v ) { return 'KEYWORT like ?'; }, $keywords ) ) . ')';
        
    $values array_merge$valuesarray_map( function( $v ) { return '%'.trim($v).'%'; }, $keywords ) );
    }

    // add order and limit
    $query.= " ORDER BY `date` DESC LIMIT 6";

    // prepare and execute query
    $objResult $this->Database->prepare$query )->execute$values ); 
    Natürlich ungetestet.
    Geändert von Spooky (23.03.2015 um 22:38 Uhr)

  8. #8
    Contao-Nutzer
    Registriert seit
    18.11.2009.
    Ort
    Köln
    Beiträge
    77

    Standard

    Vielen Dank für Deine Mühe!

    Dein Code sieht etwas komplzierter als meiner aus. Im Grunde, erzeugen beide Varianten den gleichen Code. Allerdings scheint es so, als würde Dein Code auch tatsächlich ohne Error funktionieren. Ich habe Ihn bereits eingebaut und teste ihn noch 1-2 Tage.

    Cu Swiper
    php 7.2, mySQL 5.7, 4.4.12

Aktive Benutzer

Aktive Benutzer

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

Lesezeichen

Lesezeichen

Berechtigungen

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