Ankündigung

Einklappen
Keine Ankündigung bisher.

PDO Prepared Statements LIMIT

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • PDO Prepared Statements LIMIT

    Ein simples LIMIT im Querystring funktioniert jetzt mit PDO Prepared Statements named nicht mehr. Ohne dem funktioniert alles einwandfrei. Lösungen im Internet habe ich keine gefunden, außer Hinweise, dass das nicht geht?

    PHP-Code:
    $search "SELECT `id`, `column` FROM `table` WHERE `column` LIKE :string AND LIMIT :limit";

    $limit 25;
    $string '%' $search '%';

    $array = array(
        
    ':string' => $string,
        
    ':limit' => $limit
    ); 

  • #2
    $pdo->setAttribute( PDO::ATTR_EMULATE_PREPARES, false );

    musst du setzen.

    das erste Stackoverlow https://stackoverflow.com/questions/...ared-statement weiter runter scorllen mit 4 upvotes..
    apt-get install npm -> npm install -g bower -> bower install <package> YOLO [URL]https://www.paypal.me/BlackScorp[/URL] | Mein Youtube PHP Kanal: [url]https://www.youtube.com/c/VitalijMik[/url]

    Kommentar


    • #3
      ? man muss den Vorteil gegenüber real_escape_string() deaktivieren? Gibt es da keine andere Lösung? Ist das bei der Verwendung von der Methode mit ? auch so? Ich brauch das an einem echt wunden Punkt: der öffentlich zugänglichen Suche!

      Kommentar


      • #4
        Zitat von psoido Beitrag anzeigen
        ? man muss den Vorteil gegenüber real_escape_string() deaktivieren? Gibt es da keine andere Lösung? Ist das bei der Verwendung von der Methode mit ? auch so? Ich brauch das an einem echt wunden Punkt: der öffentlich zugänglichen Suche!
        nein, PHP emuliert die prepares, mit dem setzen auf false machst du ein richtiges prepared statement (also mysql seitig nicht PHP Seitig).

        https://stackoverflow.com/questions/...repares-or-not
        apt-get install npm -> npm install -g bower -> bower install <package> YOLO [URL]https://www.paypal.me/BlackScorp[/URL] | Mein Youtube PHP Kanal: [url]https://www.youtube.com/c/VitalijMik[/url]

        Kommentar


        • #5
          Ach, man muss etwas deaktivieren um etwas zu aktivieren? Dieses PDO Prepared ist schon der Wahnsinn...
          Also ich habe jetzt mal das dazu gefunden:
          https://www.php-einfach.de/2015/08/e...late_prepares/
          Wenn ich das richtig verstehe, wobei es einem sehr leicht gemacht wird es falsch zu verstehen, dann ist es so:

          $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
          Damit werden Querystring und Werte getrennt an die DB gesendet, was Injections verhindert.

          $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
          Damit werden die Werte in PHP maskiert und es wird alles auf einmal zur DB gesendet. Das ist ähnlich der Nutzung von real_escape_string().

          Richtig oder falsch?




          Kommentar


          • #6
            Zitat von psoido Beitrag anzeigen
            Ach, man muss etwas deaktivieren um etwas zu aktivieren? Dieses PDO Prepared ist schon der Wahnsinn...
            Also ich habe jetzt mal das dazu gefunden:
            https://www.php-einfach.de/2015/08/e...late_prepares/
            Wenn ich das richtig verstehe, wobei es einem sehr leicht gemacht wird es falsch zu verstehen, dann ist es so:

            $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
            Damit werden Querystring und Werte getrennt an die DB gesendet, was Injections verhindert.

            $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
            Damit werden die Werte in PHP maskiert und es wird alles auf einmal zur DB gesendet. Das ist ähnlich der Nutzung von real_escape_string().

            Richtig oder falsch?



            falsch.
            du hast in beiden Fällen ein Prepared statement. Wenn Parameter auf true gesetzt ist, regelt das PHP, wenn parameter auf false gesetzt ist, regelt die Datenbank

            PHP hat intern eine Funktion die so tut als ob da ein Statement vorbereitet wird. PHP teilt dabei automatisch den string und bereitet alles vor und schickt das zu der Datenbank. wenn du es auf false setzt, macht das PHP selbst nicht sondern sendet es direkt als prepare kommando zu der Datenbank.

            Wenn parameter auf true gesetzt ist, macht das halt PHP, wenn es auf false gesetzt ist macht das mysql.

            ich vermute weil LIMIT kein standard SQL ist, ist es nicht in PHP verbaut. wie gesagt PDO unterstützt auch andere Datenbanken wie etwa Oracle oder Microsoft DB die kennen LIMIT nicht.

            Das wird dann deaktiviert und die MYSQL Datenbank wiederum die kennt das Limit und kann damit arbeiten.


            apt-get install npm -> npm install -g bower -> bower install <package> YOLO [URL]https://www.paypal.me/BlackScorp[/URL] | Mein Youtube PHP Kanal: [url]https://www.youtube.com/c/VitalijMik[/url]

            Kommentar


            • #7
              Aha! DBs ohne Limit? unvorstellbar! was es alles gibt. Wie machen die das dann? Gibt es eine andere Möglichkeit das zu limitieren?
              OFFTOPIC: Hat schon mal jemand die Anzahl der Suchergebnisse in Google überprüft? Bei jedem Klick auf eine nächste Seite wird die Zahl immer kleiner und kleiner und zuletzt verschwinden Seiten, die als Pagnation-Button vorher noch angezeigt wurden. In einem Fall waren es auf Seite 1 ca. 300.000, auf ein paar Seiten weiter ist die Zahl geschrumpft auf 300. kurios.

              Also ist es genau andersherum, bzw. doch so, dass man etwas aktiviert, indem man etwas deaktiviert. Der Vorteil von Prepared Statement wird doch mit dem separaten Senden von Querystring und Werten angepriesen, oder etwa nicht, und dann ist das default gar nicht aktiviert!

              Rät jemand davon ab das standardmäßig gleich nach new PDO() auf false zu setzen?

              Kommentar


              • #8
                Zitat von psoido Beitrag anzeigen
                Aha! DBs ohne Limit? unvorstellbar! was es alles gibt. Wie machen die das dann? Gibt es eine andere Möglichkeit das zu limitieren?
                https://www.w3schools.com/sql/sql_top.asp es gibt SELECT TOP in normalen SQL Servern .

                Zitat von psoido Beitrag anzeigen
                Also ist es genau andersherum, bzw. doch so, dass man etwas aktiviert, indem man etwas deaktiviert. Der Vorteil von Prepared Statement wird doch mit dem separaten Senden von Querystring und Werten angepriesen, oder etwa nicht, und dann ist das default gar nicht aktiviert!
                Du hast nicht verstanden was eine Emulation ist... es wird EGAL OB TRUE ODER FALSE ein preparedstatement ausgeführt. PDO EMULIERT prepared statment per default.. aber dennoch ist es ein prepared statement.

                du deaktivierst nur die EMULATION aber NICHT das Prepared statement..
                apt-get install npm -> npm install -g bower -> bower install <package> YOLO [URL]https://www.paypal.me/BlackScorp[/URL] | Mein Youtube PHP Kanal: [url]https://www.youtube.com/c/VitalijMik[/url]

                Kommentar


                • #9
                  Ach, ein Emulator! kenn ich von Synthesizern! Die tun nur so wie Hardware Synths. Für heute bin ich genug prepared.

                  Kommentar


                  • #10
                    Zitat von BlackScorp Beitrag anzeigen
                    PDO EMULIERT prepared statment per default.. aber dennoch ist es ein prepared statement.
                    Soweit ich weiß tut es das nur bei MySQL/MariaDB. (Habe allerdings sonst nur SQLite testen können, wo das einen Fehler wirft, für PG sollte unser lokaler Experte mehr dazu sagen können).

                    Kommentar


                    • #11
                      1. Diese SQL Anweisung ist falsch.
                      Zitat von psoido Beitrag anzeigen
                      PHP-Code:
                      $search "SELECT `id`, `column` FROM `table` WHERE `column` LIKE :string AND LIMIT :limit"
                      Das AND vor dem LIMIT ist da zuviel.

                      2. LIMIT akzeptiert keine Strings. Parameter welche per Array dem execute übergeben werden können werden aber alle als String ausgeliefert. Bleibt hier nur die Parameter einzeln mit bindValue zuzuweisen. Ein Beispiel:
                      PHP-Code:
                      $limit 2;
                      $userNameLike '%ax%';

                      $sql "SELECT datumzeit, username 
                        FROM protg1 
                        WHERE username like :username 
                        limit :limit"
                      ;
                      $stmt $db->prepare($sql);

                      $stmt->bindValue (':limit'$limitPDO::PARAM_INT); 
                      $stmt->bindValue (':username'$userNameLike);

                      if(
                      $stmt->execute() !== false){ 
                      3. Per PDO::ATTR_EMULATE_PREPARES ein anderes Verhalten der Parameter beim execute bei MySQL zu erzwingen halte ich für etwas gewagt, auch wenn dies bei Stackoverflow als Lösung gefeiert wird.


                      Kommentar


                      • #12
                        Aha. Vielen Dank jspit für die Info und Hinweise. Da muss ich wohl noch mal ran.
                        Das mit dem AND vor dem LIMIT war ein copy&paste Fehler. Da steht noch ein column = :value dazwischen.
                        Vielleicht sollte ich allgemein doch auf dieses bindValue umsteigen?

                        Kommentar


                        • #13
                          Wie schon festgestellt, übergibt PDOStatement::execute() alle Werte als Strings. Kann man über eine erweiterte Statement-Klasse lösen:

                          PHP-Code:
                          class Statement extends PDOStatement {

                              public function 
                          execute(array $values = []) {
                                  foreach(
                          $values as $name => $value) {
                                      
                          $this->bindValue(
                                          
                          $name,
                                          
                          $value,
                                          
                          $this->getValueType($value)
                                      );
                                  }
                                  return 
                          parent::execute();
                              }

                              protected function 
                          getValueType($value) {
                                  if(
                          is_null($value)) {
                                      return 
                          PDO::PARAM_NULL;
                                  }
                                  if(
                          is_bool($value)) {
                                      return 
                          PDO::PARAM_BOOL;
                                  }
                                  if(
                          is_int($value)) {
                                      return 
                          PDO::PARAM_INT;
                                  }
                                  return 
                          PDO::PARAM_STR;
                              }

                          }

                          $pdo = new \PDO('mysql:host=mysql;dbname=' getenv('MYSQL_DATABASE'), getenv('MYSQL_USER'), getenv('MYSQL_PASSWORD'), [
                              
                          PDO::ATTR_STATEMENT_CLASS => [Statement::class]
                          ]);
                          $statement $pdo->prepare('SELECT * FROM geoip_location LIMIT :limit');
                          $statement->execute([
                              
                          'limit' => 5
                          ]);
                          var_dump($statement->fetchAll()); 

                          Kommentar


                          • #14
                            Das die execute Methode nur Strings verarbeitet hat mich auch schon geärgert. Zudem benötige ich sehr oft für ein Select die Kombination von prepare, mehreren bindvalue und execute. Habe dafür die PDO-Klasse und PDOStatement erweitert. Vom Grundsatz ähnlich wie es Blar gezeigt hat. Wen Details dazu interessieren kann sich gerne diese Demo anschauen: http://jspit.sculptor.uberspace.de/c...lass.pdodb.php . Dort sind auch Bespiele mit LIMIT und NULL in Abfragen.

                            Kommentar


                            • #15
                              Sorry, Beitrag war doppelt. Habe immer die Meldung ungültige Serverantwort.

                              Kommentar

                              Lädt...
                              X