Körpergröße prüfen mit preg_match("/[0-9]{3}$/",$groesse)

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

  • Körpergröße prüfen mit preg_match("/[0-9]{3}$/",$groesse)

    Hallo,

    wie kann ich die Körpergröße in cm auf eine gültige Eingabe überprüfen?

    preg_match("/[0-9]{3}$/",$groesse)

    Das schränkt es zumindest auf eine 3-stellige Zahl ein, aber da sind ja dann trotzdem noch Zahlenkombis wie 000 und 999 möglich.

    Wie füge ich also noch einen Bereich hinzu (z.B. 150 - 200 cm)?

    Danke,
    Truncate

  • #2
    Zitat von Truncate Beitrag anzeigen
    Wie füge ich also noch einen Bereich hinzu (z.B. 150 - 200 cm)?
    Du könntest als erste Ziffer nur 1 oder 2 zulassen.

    Aber generell sind reguläre Ausdrücke für sowas weniger geeignet, auch nicht gedacht.
    Wandle den Wert in eine Zahl um, und prüfe dann auf den erlaubten Wertebereich.
    I don't believe in rebirth. Actually, I never did in my whole lives.

    Kommentar


    • #3
      Zitat von wahsaga Beitrag anzeigen
      Wandle den Wert in eine Zahl um, und prüfe dann auf den erlaubten Wertebereich.
      Muss das zwingend sein?

      Reicht das nicht aus:

      if($_POST['groesse']>=145 && $_POST['groesse']<=210){...}

      Oder ist da in irgendeiner Form noch Betrug (andere Zahlen, Injections) möglich?

      Kommentar


      • #4
        Zitat von Truncate Beitrag anzeigen
        Muss das zwingend sein?

        Reicht das nicht aus:

        if($_POST['groesse']>=145 && $_POST['groesse']<=210){...}

        Oder ist da in irgendeiner Form noch Betrug (andere Zahlen, Injections) möglich?
        Ja, ein älteres PHP könnte hier bei Benutzereingaben, die als Gleitkommazahl daherkommen, in eine Endlosschleife geraten. Der Bug wurde erst Anfang diesen Jahres entdeckt und behoben.

        PHP-Code:
        $groesse = isset ($_POST['groesse'][0]) 
            ? (int) 
        $_POST['groesse'
            : 
        $defaultwert;
        if (
        $groesse >= 145 && $groesse <= 210) {
            
        // ...

        Mit Regex sähe es für den Bereich 150 bis 210 (cm?) so aus:

        PHP-Code:
        if (preg_match(
            
        '/\A\s*(1[5-9][0-9]|20[0-9]|210)\s*\z/'
            
        $_POST['groesse']
        )) {
            
        // ...

        Das wird aber je nach gewünschtem Bereich unterschiedlich komplex und ist daher nur was für Leute, denen sowas Spaß macht.
        Klingon function calls do not have “parameters”‒they have “arguments”‒and they always win them!

        Kommentar


        • #5
          Zitat von fireweasel Beitrag anzeigen
          Ja, ein älteres PHP könnte hier bei Benutzereingaben, die als Gleitkommazahl daherkommen, in eine Endlosschleife geraten. Der Bug wurde erst Anfang diesen Jahres entdeckt und behoben.
          Eben, der Bug wurde behoben. Wo ist das Problem? Nur weil irgendwelche Gammel-Server noch mit Uralt-PHP laufen? Die sind dann selber schuld. Hier hat der Server-Admin seinen Beruf verfehlt.

          Kommentar


          • #6
            Du könntest auch filter_input() verwenden.

            Kommentar


            • #7
              Zitat von h3ll Beitrag anzeigen
              Eben, der Bug wurde behoben. Wo ist das Problem?
              Du glaubst doch nicht ernsthaft, dass das der letzte Bug dieser Art war ...?

              Nur weil irgendwelche Gammel-Server noch mit Uralt-PHP laufen?
              Ja, toll. Das nützt jemandem, der ein Script schreiben muss, welches bei möglichst vielen Hostern fehlerfrei laufen soll, jetzt wieviel?

              Stell dir vor, du wärst der Autor einer beliebten Scriptsammlung (Framework, Library, CMS, Blog, Board was auch immer). Als solcher bekämst du Bugreports, diesen Fehler betreffend. Selbstverständlich denken die User, es wäre deine Software, die fehlerhaft ist. Wie würdest du reagieren?

              ... Die sind dann selber schuld. Hier hat der Server-Admin seinen Beruf verfehlt.
              Jeder Admin, der freiwillig PHP auf einem Server installiert, fällt in diese Kategorie.
              Zuletzt geändert von fireweasel; 19.03.2011, 18:22. Grund: typos
              Klingon function calls do not have “parameters”‒they have “arguments”‒and they always win them!

              Kommentar


              • #8
                Mal interessehalber: Was machen wir denn, wenn Floats als Eingaben akzeptiert werden müssen?

                Immerzu auf Stringbasis prüfen, ob die Eingabe nicht "2.2250738585072011e-308" ist?

                Was ist, wenn die Anwendung zum Beispiel zwei Eingaben multipliziert?

                Kommentar


                • #9
                  Zitat von mermshaus Beitrag anzeigen
                  Mal interessehalber: Was machen wir denn, wenn Floats als Eingaben akzeptiert werden müssen?
                  Wenn wirklich nur die ungepatchte PHP-Version zur Verfügung steht, kannst du verschiedenes versuchen:

                  - Die Eingaben auf bestimmte Werte zu begrenzen (maximale Länge und keine Exponenten). Das sollte bspw. bei der Auswertung von HTTP-Headern helfen, die Quality-Factors enthalten ("Accept" usw.).

                  - Das Muster zu erkennen und den Wert auf 0.0 setzen, da solche Zahlen der 0.0 wohl ausreichend nahe kommen.

                  - Unter Windows die COM-Extension verwenden. Deren Variant-Datentypen sind nicht von diesem Bug betroffen. Man kann ihnen auch Strings übergeben, die dann als Gleitkommazahl interpretiert werden. Allerdings ist die Interpetation anscheinend Locale-abhängig. Auf einer "deutsch eingestellten" Windows-Version werden nur Gleitkommazahlen mit richtigem Komma ',' als Trennzeichen akzeptiert. Mit dem Dezimalpunkt '.' klappt das nicht.

                  Immerzu auf Stringbasis prüfen, ob die Eingabe nicht "2.2250738585072011e-308" ist?
                  Das ist (leider) nicht die einzige Zahl und auch nicht die einzige Darstellung dieser Zahl, die Schwierigkeiten macht.

                  PHP Hangs On Numeric Value 2.2250738585072011e-308 - Exploring Binary

                  In den Benutzer-Kommentaren auf der Website des Bug-Entdeckers findet sich ein Ansatz das Muster zu erkennen: Die zu verarbeitende Variable wird serialisiert und dann auf das Ziffernmuster untersucht.

                  Eventuell lässt sich auch eine der Notlösungen für Java portieren.

                  Was ist, wenn die Anwendung zum Beispiel zwei Eingaben multipliziert?
                  PHP-Code:
                  $a = new variant($_GET['a'], VT_R8);
                  $b = new variant($_GET['b'], VT_R8);
                  $x variant_mult($a$b);
                  printf('%s * %s = %s'$a$b$x); 
                  Da der Fehler nur in der Umwandlungsphase von String nach Double auftritt, sollte auch
                  Code:
                  $x = $a * $b;
                  funktionieren.

                  ==
                  Nachtrag:
                  Man kann die Umwandlung notfalls nachbauen, indem man den String in Mantissen- und Exponent-Teil zerlegt und anschließend die beiden Teile per pow() wieder zusammenbastelt:

                  PHP-Code:
                  /// COM-Variant-Variante
                  /// return double() | FALSE
                  function dpfloat_vt($str) {
                      try {
                          
                  // strtr() wandelt Dezimalpunkt in Komma
                          
                  $vt_dbl = (float) new variant(strtr($str'.'','), VT_R8);
                      }
                      catch (
                  com_exception $ex) {
                          
                  $vt_dbl FALSE;
                      }
                      return 
                  $vt_dbl;
                  }

                  /// Hobbythek-Variante: Selberbasteln mit pow()
                  /// und Notfall-Laengenbegrenzung der Mantisse
                  /// return double() | FALSE
                  function dpfloat_val($str) {
                      
                  $pcre '/\A
                          ((?:0\.0{0,306}(0)*|[0-9]*\.|)[0-9]+) # mantissa
                          (?:[eE]([+-]?[0-9]+))? # optional exponent
                      \z/x'
                  ;
                      if (!
                  preg_match($pcre$str$hits)) {
                          return 
                  FALSE;
                      }
                      
                  $double = isset($hits[2][0])
                          
                  // truncating mantissa which starts with 0.000..., but has too many 0
                          
                  ? (double) substr($hits[1], 0, -strlen($hits[2]))
                          : (double) 
                  $hits[1];
                      return isset (
                  $hits[3])
                          ? 
                  $double pow(10, (int) $hits[3]) // has exponent
                          
                  $double;
                  }

                  // einige Beispielwerte:

                  // Extremfaelle mit "langer" Mantisse
                  // 0.22250738585072011e-307
                  $x str_pad('0.'309'0') . '22250738585072011';
                  $y str_pad('0.'309'0') . '2225073858507201';
                  $xe $x 'e0';

                  $test = array (
                      
                  '0.333333333333333314829616256247390992939472198486328125'// 1/3
                      
                  '1',
                      
                  '3.14',
                      
                  '1.23456789012345678901234567890',
                      
                  '0.1e-10',
                      
                  '0.1e10',
                      (string) 
                  pow(252),
                   
                      
                  '2.2250738585072011e-308',
                      
                  '22.250738585072011e-309',
                      
                  '0.22250738585072011e-307',
                      
                  '.22250738585072011e-307',
                      
                  '2.22507385850721e-308',
                      
                  '2.22507385850722e-308',
                      
                  '2.22507385850725e-308',
                      
                  '2.22507385850729e-308',

                      
                  $x,
                      
                  $y,
                      
                  $xe,

                      
                  'b',
                  );

                  foreach (
                  $test as $input) {
                      
                  $my_dbl dpfloat_val($input);
                      
                  $vt_dbl dpfloat_vt($input);
                      
                  $diff abs($my_dbl $vt_dbl);
                      
                  printf('%s ?= %s diff: %s' "<br />"$my_dbl$vt_dbl$diff);

                  Wie man sieht, gibt es ein paar Abweichungen bei sehr kleinen Zahlen. Aber wer genau mit Gleitkommazahlen rechnen möchte, wird höchstwahrscheinlich kein PHP einsetzen.
                  Zuletzt geändert von fireweasel; 22.03.2011, 12:30.
                  Klingon function calls do not have “parameters”‒they have “arguments”‒and they always win them!

                  Kommentar


                  • #10
                    Danke für die Infos.

                    Ein Regex-Check von Eingabe-Strings gegen etwa /\d+(?:\.\d{1,4})?/ (Zahl mit maximal vier Nachkommastellen) sollte es also tun, nehme ich an.

                    Ich finde die Frage, ob das anwendungsseitig behandelt werden sollte, auch nicht ganz leicht zu beantworten. In „Bibliothekscode“ kommt man wohl schwer drumrum.

                    Kommentar


                    • #11
                      Zitat von sili
                      Du könntest auch filter_input() verwenden.
                      Theoretisch ist die Filter-Erweiterung eine gute Idee.

                      Der Sanitize-Filter entfernt Zeichen, die nicht in einer Gleitkommazahl vorkommen dürfen. Nur wenn die Zeichenkette dann nach Float gewandelt wird, geht die Sache trotzdem schief.

                      Gleiches wird wohl beim Validate-Filter passieren: Das Muster '2.2250738585072011e-308' ist ja eine gültige Float-Darstellung. Das dürfte (und sollte) der Filter anstandslos durchlassen.

                      Wenn man aber konsequent mit den Filtern arbeitet und Daten nicht anderweitig ins Script lässt, könnte man per Callback-Filter eine Funktion einbauen, die das handhabt.


                      Zitat von mermshaus Beitrag anzeigen
                      Danke für die Infos.

                      Ein Regex-Check von Eingabe-Strings gegen etwa /\d+(?:\.\d{1,4})?/ (Zahl mit maximal vier Nachkommastellen) sollte es also tun, nehme ich an.
                      Für die typischen (oben erwähnten) Web-Anwendungen sollte das ausreichen. Wichtig ist hier die Längenbegrenzung.

                      Ich finde die Frage, ob das anwendungsseitig behandelt werden sollte, auch nicht ganz leicht zu beantworten. In „Bibliothekscode“ kommt man wohl schwer drumrum.
                      Klar sind das alles nur Workarounds, die die zwei darunterliegenden Probleme nicht beheben: Den Fehler selbst und die "Type-Coercion", die dafür sorgt, dass automatisch nach Float gewandelt wird. Aber wie schon gesagt: Wenn bspw. eine Blogsoftware (die nun nicht gerade unter "Bibliothekscode" fällt) überall laufen soll, kommt man nicht drumherum, den Fehler zu berücksichtigen. Die älteste PHP-Version, die ich bei einem großen Free-Hoster gesehen habe, ist derzeit 5.2.11. Es dürften aber auch noch einige ungepatchte 5.3.-er rumlaufen.
                      Zuletzt geändert von fireweasel; 22.03.2011, 13:35.
                      Klingon function calls do not have “parameters”‒they have “arguments”‒and they always win them!

                      Kommentar


                      • #12
                        Zitat von fireweasel Beitrag anzeigen
                        Du glaubst doch nicht ernsthaft, dass das der letzte Bug dieser Art war ...?
                        Wenn es nach dem geht, darfst du gar kein PHP verwenden, weil in jeder Funktion ein Bug stecken könnte, mit dem man Code einschleusen oder den Server blockieren könnte.

                        Zitat von fireweasel Beitrag anzeigen
                        Ja, toll. Das nützt jemandem, der ein Script schreiben muss, welches bei möglichst vielen Hostern fehlerfrei laufen soll, jetzt wieviel?
                        Irgendwo muss man Abstriche machen. Man kann nicht bis in alle Ewigkeit Gammel-Server supporten. Sonst müsste man heute immer noch PHP 3 programmieren.

                        Wofür gibt es Mindestvoraussetzungen? Wenn ich eine Software kaufe, die nur unter Windows Vista und Windows 7 läuft, dann hab ich eben Pech gehabt, wenn ich noch Windows XP verwende.

                        Zitat von fireweasel Beitrag anzeigen
                        Stell dir vor, du wärst der Autor einer beliebten Scriptsammlung (Framework, Library, CMS, Blog, Board was auch immer). Als solcher bekämst du Bugreports, diesen Fehler betreffend. Selbstverständlich denken die User, es wäre deine Software, die fehlerhaft ist. Wie würdest du reagieren?
                        Nicht wirklich. Oder sind auch automatisch alle Programmierer schuld, wenn eine Intel CPU einen Rechenfehler hat?
                        Zuletzt geändert von h3ll; 25.03.2011, 16:34.

                        Kommentar


                        • #13
                          Im Prinzip gebe ich dir ja recht. Warum freust du dich nicht einfach darüber, dass du in der glücklichen Lage bist, auf solchen Unfug keine Rücksicht nehmen zu müssen?

                          Zitat von h3ll Beitrag anzeigen
                          Wenn es nach dem geht, darfst du gar kein PHP verwenden, weil in jeder Funktion ein Bug stecken könnte, mit dem man Code einschleusen oder den Server blockieren könnte.

                          Irgendwo muss man Abstriche machen. Man kann nicht bis in alle Ewigkeit Gammel-Server supporten. Sonst müsste man heute immer noch PHP 3 programmieren.

                          Wofür gibt es Mindestvoraussetzungen? Wenn ich eine Software kaufe, die nur unter Windows Vista und Windows 7 läuft, dann hab ich eben Pech gehabt, wenn ich noch Windows XP verwende.
                          Hast du dir die Geschichte dieses speziellen Bugs mal näher angesehen? In der Originalroutine war der 1997 schon gefixt (per #ifdef "ausgeklammert"). Die PHP-Macher haben es trotzdem fertiggebracht, irgendwann danach genau die Teile zu kopieren (oder wieder zu aktivieren), die diesen Fehler hatten. Anfang 2011, schlappe 14 Jahre nach 1997, haben sie mitbekommen, dass da ein schwerwiegender Fehler drin ist. Aber sie ersetzen den fehlerhaften Code nicht durch den seit 1997 gefixten, sondern fummeln an den Speicherklassen rum. Kommt irgendwann mal ein neuer Compiler, der das nun erzwungene Zwischenspeichern wegoptimiert, können wir nur hoffen, dass dann entweder kein Prozessor mehr da ist, der noch x87-Mathematik kann, oder dass die Helden wenigstens einen passenden Test hinzugefügt haben, damit sie das mitbekommen.

                          Und da erzählst du mir was von alten Zöpfen, die man rechtzeitig abschneiden sollte ...?

                          Nicht wirklich. Oder sind auch automatisch alle Programmierer schuld, wenn eine Intel CPU einen Rechenfehler hat?
                          Darum geht es doch nicht. Du musst das aus Sicht des Endkunden betrachten: Wenn der feststellt, dass eine gerade von ihm gekaufte Anwendung nicht auf seinem Computer funktioniert, andere aber schon, wird er zuerst den Programmierer|Hersteller verantwortlich machen. Das liegt zum einen daran, dass er nicht erkennen kann, was die wirkliche Ursache ist und zum anderen am Hersteller der Software, weil nämlich die Konkurrenz sicher Workarounds in ihre Produkte eingebaut hat. Mag sein, dass der Prozessorhersteller die Kunden mit viel Aufwand und Medienrummel informiert und Rückrufaktionen gestartet hat. Vor den Endkunden hat er aber die Softwarehersteller informiert. Was glaubst du wohl warum?

                          Der Klassiker war hier der FDIV-Bug im Pentium (kann man in "Inside Intel" schön aufbereitet nachlesen"). Es gibt auch aktuelle Beispiele, wie das hier:
                          Glibc memcpy change exposing bugs : programming (und das "Improvement" dazu)

                          Mal abgesehen davon, sind heutzutage Prozessoren oft eingelötet. Die kannst du nur per Software-Workaround (BIOS, Betriebssystem, häufig benutzte Bibliothek, Anwendung) "fixen".
                          Zuletzt geändert von fireweasel; 27.03.2011, 13:35.
                          Klingon function calls do not have “parameters”‒they have “arguments”‒and they always win them!

                          Kommentar

                          Lädt...
                          X