Kalle_B: Gültigkeit von Parametern überprüfen

Hallöle,

bei Aufruf eines PHP-Programms können Parameter übergeben werden, die ich zu prüfen habe.

Ein Parameter kann aus einer Aufzählung von Zahlen bestehen, getrennt durch Kommata. Das soll so in die MySQL WHERE-Klausel eingehen:

$ort = '4711,5,4813,23689';

... WHERE ort_id IN (".$ort.")

Um Missbrauch zu verhindern, möchte ich die zulässige Eingabe überprüfen. Habe mich mit preg_match beschäftigt, ohne es zu verstehen.

Das erste Zeichen muss eine Ziffer sein, dann dürfen Ziffern und Kommata folgen, aber nicht zwei Kommata nacheinander und auch nur 6-stellige Zahlen.

Ist das überhaupt ein Fall für preg_match, oder muss ich da eine eigene Funktion schreiben?

LG Kalle

  1. Ist das überhaupt ein Fall für preg_match, oder muss ich da eine eigene Funktion schreiben?

    /^\d{1,6}(?:,\d{1,6}){0,5}$/

    verlangt mindestens einen Integer < 1'000'000 bis maximal 6 durch Komme separierte Integer.

    mfg Beat

    --
    ><o(((°>           ><o(((°>
       <°)))o><                     ><o(((°>o
    Der Valigator leibt diese Fische
    1. /^\d{1,6}(?:,\d{1,6}){0,5}$/

      Danke für die Antwort. Habe ich die obigen Zeichen so richtig interpretiert?

      ^     Angabe bezieht sich auf 1. Stelle des Strings
      \d    Digit (Zahl) gefordert,
      {1,6} die 1 - 6 Stellen haben darf
      (     für den Rest gilt:
      ?:,   muss mit Komma beginnen
      \d    dann eine Zahl
      {1,6} 1 - 6 stellig
      )     Ende der Bedingung
      {0,5} es dürfen 0..5 Elemente vorkommen
      $     (keine Ahnung)

      LG Kalle

      1. /^\d{1,6}(?:,\d{1,6}){0,5}$/

        Danke für die Antwort. Habe ich die obigen Zeichen so richtig interpretiert?

        ^     Angabe bezieht sich auf 1. Stelle des Strings

        Muss den Stringbeginn matchen.

        \d    Digit (Zahl) gefordert,
        {1,6} die 1 - 6 Stellen haben darf
        (     für den Rest gilt:
        ?:,   muss mit Komma beginnen

        lies (?:) eine non capuring group, reserviert kein $1 etc...

        \d    dann eine Zahl
        {1,6} 1 - 6 stellig
        )     Ende der Bedingung
        {0,5} es dürfen 0..5 Elemente vorkommen

        De Gruppe darf so oft vorkommen

        $     (keine Ahnung)

        Muss das Stringende matchen.

        Es sei dir wirklich empfohlen das ABC für PCRE Syntax zu lernen.

        mfg Beat

        --
        ><o(((°>           ><o(((°>
           <°)))o><                     ><o(((°>o
        Der Valigator leibt diese Fische
      2. Hi,

        ^     Angabe bezieht sich auf 1. Stelle des Strings

        Nein, auf den Stringanfang (der ist noch VOR der 1. Stelle).

        \d    Digit (Zahl) gefordert,

        Ziffer, nicht Zahl

        {1,6} die 1 - 6 Stellen haben darf

        1 bis 6 mal das vorherige Element (hier also Ziffer)

        (     für den Rest gilt:
        ?:,   muss mit Komma beginnen

        falsch.

        (?:
        Eine öffnende non-capturing Klammer

        ,
        ein Komma

        \d    dann eine Zahl

        Nein, wieder eine Ziffer.

        {1,6} 1 - 6 stellig

        s.o.

        )     Ende der Bedingung

        Ende der (non-capturing) Klammer

        {0,5} es dürfen 0..5 Elemente vorkommen

        Das vorherige Element (also die non-capturing Klammer) 0 bis 5-mal.

        $     (keine Ahnung)

        Das Gegenstück zu ^ - sprich Stringende

        cu,
        Andreas

        --
        Warum nennt sich Andreas hier MudGuard?
        O o ostern ...
        Fachfragen per Mail sind frech, werden ignoriert. Das Forum existiert.
        1. Hallo,

          $     (keine Ahnung)

          Das Gegenstück zu ^ - sprich Stringende

          Ich möchte allerdings darauf hinweisen, dass preg_match bei PHP - wenn ohne Modifier angewandt - $ auch ein Zeilenende-Zeichen matchen kann.

          /^\d{1,6}(?:,\d{1,6}){0,5}$/

          matcht auch folgenden String:

          "1,2,3\n"

          Hier in diesem Fall ist das unkritisch (ein SQL-Statement geht durch \n nicht kaputt), aber generell ist das ein Fehler, der gerne gemacht wird.

          Abhilfen für andere Fälle, wo so etwas kritisch sein kann:

          D-Modifier: /^\d{1,6}(?:,\d{1,6}){0,5}$/D

          \z statt $: /^\d{1,6}(?:,\d{1,6}){0,5}\z/
           (nicht mit \Z verwechseln, was das Gegenteil ist, d.h. immer auch eine
            optionale Newline mitmatcht)

          Viele Grüße,
          Christian

          --
          Mein "Weblog" [RSS]
          Using XSLT to create JSON output (Saxon-B 9.0 for Java)
          »I don't believe you can call yourself a web developer until you've built an app that uses hyperlinks for deletion and have all your data deleted by a search bot.«
                      -- Kommentar bei TDWTF
  2. Hi,

    Ein Parameter kann aus einer Aufzählung von Zahlen bestehen, getrennt durch Kommata. Das soll so in die MySQL WHERE-Klausel eingehen:

    $ort = '4711,5,4813,23689';

    ... WHERE ort_id IN (".$ort.")

    Um Missbrauch zu verhindern, möchte ich die zulässige Eingabe überprüfen. Habe mich mit preg_match beschäftigt, ohne es zu verstehen.

    Wozu preg_match?

    Mit explode am Komma zerlegen,
    Array-Inhalte validieren, wenn ungültig ggf. entfernen,
    mit implode wieder mit Komma als Trenner zusammenfügen,
    in Query einsetzen.

    MfG ChrisB

    --
    Light travels faster than sound - that's why most people appear bright until you hear them speak.
    1. Moin!

      Wozu preg_match?

      Frage ich mich auch, allerdings ist die Frage, welche Fehlerfälle wohl auftreten können, und wie man mit diesen dann umgeht.

      Mit explode am Komma zerlegen,
      Array-Inhalte validieren, wenn ungültig ggf. entfernen,

      Es gibt ctype*-Funktionen, die auf bestimmte Zeichentypen prüfen können.

      mit implode wieder mit Komma als Trenner zusammenfügen,
      in Query einsetzen.

      Von den ctype-Funktionen wird behauptet: "Die ctype Funktionen sind grundsätzlich performanter als die entsprechenden regular Expressions und oft auch schneller als die equivalenten str_* und is_* Funktionen da sie direkt in C geschrieben und optimiert sind."

      Allerdings ist die Frage, ob die Kombination aus explode, Array-Operationen, Aussortieren und implode tatsächlich schneller ist als die Anwendung eines passenden RegEx. Dies festzustellen wäre Aufgabe eines entsprechenden Profilings.

      Aber Performance sollte nicht das primäre Handlungsinteresse sein. An allererster Stelle steht die Klarheit des Codes. Wenn der Code nicht auf den ersten Blick offenbart, was er tut, und auch kein entsprechender Kommentar hilft, es zu verstehen, dann ist der Code schlecht und ein Quell beliebigen Übels.

      Was die Performance angeht: Relevant wird das ohnehin erst, wenn Code tatsächlich mehrfach ausgeführt wird. Das ist bei der Prüfung von Eingangsparametern eigentlich eher nicht der Fall.

      - Sven Rautenberg

      1. Hi,

        Frage ich mich auch, allerdings ist die Frage, welche Fehlerfälle wohl auftreten können, und wie man mit diesen dann umgeht.

        Wenn es eine herkömmliche Suchfunktionalität werden soll, dann erfordern Fehlerfälle normalerweise kein wirkliches "umgehen" mit ihnen, sondern brauchen nur ignoriert zu werden.

        Mit explode am Komma zerlegen,
        Array-Inhalte validieren, wenn ungültig ggf. entfernen,

        Es gibt ctype*-Funktionen, die auf bestimmte Zeichentypen prüfen können.

        Ich hätte hier zu intval gegriffen - bei einer Ort_id wird 0 höchstvermutlich kein gültiger Wert sein, also kann alles, aus dem intval 0 macht, aus dem Array entfernt werden.

        Nur ob dann nachher gar nichts mehr drin ist, sollte man überprüfen, bevor man's wieder imploded und in die Query einsetzt.

        MfG ChrisB

        --
        Light travels faster than sound - that's why most people appear bright until you hear them speak.
  3. hi Kalle,

    Um Missbrauch zu verhindern, möchte ich die zulässige Eingabe überprüfen. Habe mich mit preg_match beschäftigt, ohne es zu verstehen.

    Warum so kompliziert? Prüf doch einfach, ob der eingegebene Wert in der Tabelle vorkommt _bevor_ Du den in die Wehre-Klause einbaust.

    Hotte