Julius: Erster Prototyp des PHP-Forums

Moin,

ich habe jetzt den ersten Prototyp der Forumssoftware für einen Wiki-Artikel fertiggestellt. Im Wesentlichen ist es eine sehr stark überarbeitete Version des Forums aus dem SELFHTML-Aktuell-Artikel „Threadbasiertes Forum mit PHP und MySQL“.

Meine Überarbeitungen haben im Wesentlichen zwei Ziele:

  1. Aktualisierung der auf modernen Systemen nicht mehr lauffähigen Software
  2. Nutzbarkeit: Das Forum soll zwar möglichst simpel, aber dennoch nutzbar sein

Bereits erledigt:

  • unter aktuellen PHP-Versionen (5 und 7) lauffähig gemacht
  • Tabellenlayout in neu.php entsorgt und auf heutigen Stand gebracht
  • Die Konfiguration und das HTML-„Template“ in config.php bzw. template.inc.php ausgelagert
  • das Ganze per CSS etwas ansehnlicher gestaltet
  • Anlegen der Datenbank-Tabellen per init.php
  • Vorbelegen der Eingabe-Felder in der neu.php über URL-Parameter
  • Software merkt sich Eingaben, wie z.B. den Nick
  • antworten ohne Zitat

Vor allem die letzten drei Punkte erinnern doch etwas an das CForum ;-)

ToDo:

  • Fehlermeldungen im Produktiv-Modus nicht ausgeben (in config.php festlegen)
  • Pagination: Dazu müsste ich, glaube ich, jeweils das erste Posting eines Threads in der Datenbank gesondert kennzeichnen
  • RegEx für E-Mail scheint nicht auf heutige neuen Domains zu passen, beispielsweise wird mail@example.hamburg abgelehnt – kennt jemand einen guten RegEx für E-Mails?
  • Kommentare im Quelltext verbessern, Formatierung überarbeiten
  • den zugehörigen Wiki-Artikel schreiben

Fragen:

  • habe ich Sicherheitslücken im Code?
  • was kann ich stilistisch verbessern – ich will ja auch noch etwas dabei lernen :-)
  • Die Variablen (siehe neu.php) müssen nicht mehr gelöscht werden, seit sie nicht mehr von PHP automatisch importiert werden (magic_qoutes?), liege ich da richtig?
unset($errors);
unset($Thread);

Ideen für zukünftige Erweiterungen (zu beschreiben in separaten Artikeln):

Den Code kann ich derzeit nur als ZIP-Datei zum Download anbieten, wenn ich auch die alten Teile des Programms neu geschrieben habe, kann ich den Code auf GitHub bereitstellen, bisher bin ich mir mit der Lizenz nicht so sicher.
Eine Live-Demo biete ich dann an, wenn ich sicher bin, dass ich keine Sicherheitslücken eingebaut habe...

Ein paar Screenshots:

index.php
Startseite des Forums

lesen.php
Lesen eines Eintrags

neu.php
Auf einen Eintrag antworten

Was meint ihr dazu?

Gruß
Julius

akzeptierte Antworten

  1. Hallo Julius,

    • RegEx für E-Mail scheint nicht auf heutige neuen Domains zu passen, beispielsweise wird mail@example.hamburg abgelehnt – kennt jemand einen guten RegEx für E-Mails?

    .*@.*\..* ;-)

    alles andere ist mehr oder weniger sinnfrei. Es gibt keinen Grund, die Validität einer E-Mail-Adresse prüfen zu wollen.

    Bis demnächst
    Matthias

    --
    Wenn eine Idee nicht zuerst absurd erscheint, taugt sie nichts. (Albert Einstein)
    1. Hallo Matthias,

      Es gibt keinen Grund, die Validität einer E-Mail-Adresse prüfen zu wollen.

      Doch, den gibt es.

      • offensichtliche Fehler direkt ausschließen und so dem User Ärger ersparen
      • Sicherheitsprüfungen: man könnte durchaus versuchen, über die E-Mail Schadcode einzuschleusen

      LG,
      CK

    2. Hi,

      kennt jemand einen guten RegEx für E-Mails?

      .*@.*\..* ;-)

      der erlaubt aber keine lokalen Adressen (z.B. root@localhost). Aber lassen wir das mal.

      alles andere ist mehr oder weniger sinnfrei. Es gibt keinen Grund, die Validität einer E-Mail-Adresse prüfen zu wollen.

      Genau, denn erstens gibt es so viele Wenns und Abers, oder je nach Domain mal erlaubte, mal nicht erlaubte Eigenheiten, dass schon allein eine formale Prüfung ausufert, wenn sie alle Eventualitäten abdecken soll.
      Und zweitens sagt die Tatsache, dass eine e-Mail-Adresse formal korrekt ist, noch nichts darüber aus, ob sie tatsächlich existiert.

      So long,
       Martin

      1. Hallo Der Martin,

        Und zweitens sagt die Tatsache, dass eine e-Mail-Adresse formal korrekt ist, noch nichts darüber aus, ob sie tatsächlich existiert.

        Und erst recht nicht, ob sie auch verwendet wird.

        Bis demnächst
        Matthias

        --
        Wenn eine Idee nicht zuerst absurd erscheint, taugt sie nichts. (Albert Einstein)
        1. Liebe Leute,

          Und zweitens sagt die Tatsache, dass eine e-Mail-Adresse formal korrekt ist, noch nichts darüber aus, ob sie tatsächlich existiert.

          Und erst recht nicht, ob sie auch verwendet wird.

          niemand sagt, dass eine formale Prüfung ein hinreichendes Kriterium ist. Aber sie wegzulassen ist fahrlässig.

          LG,
          CK

          1. Hallo Christian Kruse,

            niemand sagt, dass eine formale Prüfung ein hinreichendes Kriterium ist. Aber sie wegzulassen ist fahrlässig.

            Eine formale Prüfung auf Client-Seite leistet bereits <input type="email">. Der verwendete RegEx ist

            [a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*
            

            Quelle: https://www.w3.org/TR/html-markup/input.email.html

            Die PHP-Filter-Funktion verwendet denselben, wenn ich das richtig lese.

            Bis demnächst
            Matthias

            --
            Wenn eine Idee nicht zuerst absurd erscheint, taugt sie nichts. (Albert Einstein)
            1. Hallo Matthias,

              Eine formale Prüfung auf Client-Seite leistet bereits <input type="email">. Der verwendete RegEx ist

              [a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*
              

              Quelle: https://www.w3.org/TR/html-markup/input.email.html

              Die PHP-Filter-Funktion verwendet denselben, wenn ich das richtig lese.

              Ich habe mir dafür mal ein kleines Skript gebastelt (bei der arabischen Beispiel-Adresse bin ich mir nicht sicher):

              $email = array(
              	'mail@example.org',
              	'mäil@fußhölle.de',
              	'test@موقع.وزارة-الاتصالات.مصر',
              	'bla@Доменні.ru');
              
              foreach($email as $value)
              {
               echo '<label>';
               if(filter_var($value, FILTER_VALIDATE_EMAIL))
               {
                echo 'Ist E-Mail-Adresse laut filter';
               }
               else
               {
                echo 'keine E-Mail-Adresse laut Filter ';
               }
               if((bool)preg_match('/[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*/', $value))
               {
                echo ' Ist E-Mail-Adresse laut RegEx ';
               }
               else
               {
                echo ' Ist keine E-Mail-Adresse laut RegEx ';
               }
               echo '<input type="email" value="'.htmlspecialchars($value).'" required></label>';
              }
              

              Wenn ich das unter PHP5.6 ausführe, werden alle E-Mail-Adresse bis auf die erste (mail@example.org) als Falsch ausgegeben, während Firefox alle bis auf die mit dem „mäil“ vor der Adresse durchgehen lässt (anscheinend mag er keine nicht-ASCII-Zeichen vor dem @).

              „Wer“ hat Recht?

              Beim RegEx scheint nur Unfug raus zu kommen (alle Adressen sind falsch), aber ich denke mal, dass ich da irgend einen Fehler gemacht habe (falsche RegEx-Begrenzer?).

              Gruß
              Julius

              1. Hallo Julius, @Matthias Apsel, @Christian Kruse, @Der Martin, @Auge, @Camping_RIDER

                mein Fehler, ich habe vergessen den Slash / im RegEx selbst zu escapen:

                preg_match('/[a-zA-Z0-9.!#$%&’*+\/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*/', $value)
                

                Ein Problem bleibt noch: Es kommt nicht das gleiche Ergebnis heraus!

                |Adresse|Filter|RegEx|Firefox| |mail@example.org|✔|✔|✔| |mäil@fußhölle.de|✗|✔|✗| |test@موقع.وزارة-الاتصالات.مصر|✗|✗|✔| |bla@Доменні.ru|✗|✗|✔|

                Bei mir schwirren einige Fragezeichen umher:

                • Welche Validierungsmethode liegt richtig?
                • Habe ich einen Fehler in meiner Überprüfung der Überprüfung von E-Mails?
                • Sind meine kyrillischen und arabischen E-Mail-Adressen korrekt?

                Gruß
                Julius

                1. Tach,

                  |Adresse|Filter|RegEx|Firefox| |mail@example.org|✔|✔|✔| |mäil@fußhölle.de|✗|✔|✗| |test@موقع.وزارة-الاتصالات.مصر|✗|✗|✔| |bla@Доменні.ru|✗|✗|✔|

                  PHP und Firefox prüfen vermutlich zusätzliches im Local Part, und ich würde raten, dass Firefox den Domainpart einfach durch den IDN-Algorithmus schickt und dann die punyencoded Domain testet.

                  • Welche Validierungsmethode liegt richtig?

                  Bezogen auf welchen Standard? Firefox macht wohl was anderes als in der HTML5-Spec steht; kodiert FF die Domain beim Versenden eines Formulars nicht auch um, erhält der Server vielleicht etwas mit dem er nicht umgehen kann (IDN sind in der Mailkette nicht sehr verbreitet); die Regex scheitert an manchen Domains, wenn man SMTPUTF8 zu Grunde legt (bla@example.Доменні.ru geht aber z.B. wieder durch); der PHP-Filter scheint zumindest mit klassischem 7-Bit SMTP kompatibel zu sein.

                  • Sind meine kyrillischen und arabischen E-Mail-Adressen korrekt?

                  Sie sehen kyrillisch und arabisch aus, aber es scheinen nicht die vorgesehenen Test IDN top-level domains zu sein und ich rate mal, dass die für .ru zuständige NIC Доменні.ru nicht als Beispieldomain reserviert hat und die arabische ist die des egyptischen Kommunikationsministeriums (auch wenn mich die Schreibrichtung verwirrt hat, ich hatte erwartet, dass die Hierarchie die selbe bleibt und nicht auch umgekehrt wird).

                  mfg
                  Woodfighter

                2. Hallo

                  bla@Доменні.ru

                  • Sind meine kyrillischen und arabischen E-Mail-Adressen korrekt?

                  Den kyrillischen Domainnamen stelle ich infrage. Es gibt zwar grundsätzlich ein „i“ im kyrillischen Alphabet – zumindest das ukrainische Alphabet kennt es –, aber nicht speziell im russischen Alphabet. Inwieweit es automatisiert überhaupt möglich und erwünscht wäre, einen Mischmasch von Zeichen aus verschiedenen Alphabeten/Schriftsystemen als solchen zu identifizieren und zu blocken, ist eine weitere, aber andere Frage.

                  Tschö, Auge

                  --
                  Wir hören immer wieder, dass Regierungscomputer gehackt wurden. Ich denke, man sollte die Sicherheit seiner Daten nicht Regierungen anvertrauen.
                  Jan Koum, Mitgründer von WhatsApp, im Heise.de-Interview
                  1. Tach,

                    Inwieweit es automatisiert überhaupt möglich und erwünscht wäre, einen Mischmasch von Zeichen aus verschiedenen Alphabeten/Schriftsystemen als solchen zu identifizieren und zu blocken, ist eine weitere, aber andere Frage.

                    Punycode ist ja darauf ausgelegt, das zu tun, z.B. für Sprachen wie deutsch, die in ASCII fast abgebildet werden: holzkämper.example wird zu xn--holzkmper-z2a.example.

                    mfg
                    Woodfighter

                    1. Hallo

                      Inwieweit es automatisiert überhaupt möglich und erwünscht wäre, einen Mischmasch von Zeichen aus verschiedenen Alphabeten/Schriftsystemen als solchen zu identifizieren und zu blocken, ist eine weitere, aber andere Frage.

                      Punycode ist ja darauf ausgelegt, das zu tun, z.B. für Sprachen wie deutsch, die in ASCII fast abgebildet werden: holzkämper.example wird zu xn--holzkmper-z2a.example.

                      Soweit ist das klar. Ob man den Umlaut, der mit lateinischen Schriftzeichen gemischt wird, genauso als „Mischmasch“ sieht, wie das kyrillische „м“ in einem Domainnamen, der sonst ausschließlich aus lateinischen Zeichen besteht, ist wohl eine Frage der Gewohnheit im Umgang mit solchen Zeichen. Umlaute sind für uns normal.

                      Es wird mit Punycode wohl auch möglich sein, Zeichen gänzlich verschiedener Schriftsysteme in einem Domainnamen zu mischen. Meine Frage bezog sich darauf, ob das intendiert oder durch irgendwelche Regeln verboten ist. Und, ob es – wenn es denn verboten sein sollte – überhaupt möglich ist, das skript- oder programmseitig zu erkennen. Schriftsysteme, um ein entsprechendes Regelwerk regelmäßig platzen zu lassen, haben wir auf unserem Planeten ja vermutlich genug.

                      Tschö, Auge

                      --
                      Wir hören immer wieder, dass Regierungscomputer gehackt wurden. Ich denke, man sollte die Sicherheit seiner Daten nicht Regierungen anvertrauen.
                      Jan Koum, Mitgründer von WhatsApp, im Heise.de-Interview
                      1. Tach,

                        Meine Frage bezog sich darauf, ob das intendiert oder durch irgendwelche Regeln verboten ist.

                        ah, ja, auf TLD-Basis können die Registries festlegen, welche Domainnamen sie eintragen:

                        „A registry will publish one or several lists of Unicode code points that are permitted for registration and will not accept the registration of any name containing an unlisted code point. Each such list will indicate the script or language(s) it is intended to support. If registry policy treats any code point in a list as a variant of any other code point, the nature of that variance and the policies attached to it will be clearly articulated. All such code point listings will be placed in the IANA Repository for IDN TLD Practices in tabular format together with any rules applied to the registration of names containing those code points, before any such registration may be accepted.“ - http://www.icann.org/en/topics/idn/idn-guidelines-02sep11-en.htm

                        DENIC erlaubt im Moment z.B. nur 93 zusätzliche Zeichen: https://www.denic.de/en/know-how/idn-domains/idn-character-list/; Доменні.de ist im Moment also nicht möglich, aber Доменні.leidergibteskeinedeexampledomain.de wäre wieder möglich.

                        Und, ob es – wenn es denn verboten sein sollte – überhaupt möglich ist, das skript- oder programmseitig zu erkennen.

                        Nicht wirklich sinnvoll, wenn man da nicht sehr viel Arbeit reinstecken will; IANA hat eine Liste, aber die ist nicht vollständig, zumindest kann ich مصر und de nicht als TLD darauf finden.

                        mfg
                        Woodfighter

                3. Hi,

                  preg_match('/[a-zA-Z0-9.!#$%&’*+\/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*/', $value)
                  

                  ist das der Regex, der für die Tabelle unten verwendet wurde?

                  |Adresse|Filter|RegEx|Firefox| |mail@example.org|✔|✔|✔| |mäil@fußhölle.de|✗|✔|✗| |test@موقع.وزارة-الاتصالات.مصر|✗|✗|✔| |bla@Доменні.ru|✗|✗|✔|

                  Das ✔ steht, wie die erste Zeile andeutet, wohl für "als korrekt erkannt". Das paßt aber nicht zur zweiten Zeile - der Regex erlaubt weder vor noch nach dem @ Umlaute, dennoch soll mäil@fußhölle als korrekt erkannt worden sein?

                  Das paßt nicht zusammen.

                  Ah - doch - wegen der fehlenden Anker matcht das il@fu ...

                  (Ich bin java.util.regex ... gewöhnt - da gibt es match und find - match setzt diese Anker implizit, es gibt nur true zurück, wenn der gesamte String gefunden wird - da dachte ich im ersten Moment, daß auch preg_match den gesamten String prüft ...)

                  Mit den Ankern ^ am Anfang und $ am Ende käme auch in der zweiten Zeile beim Regex das ✗ hin ...

                  cu,
                  Andreas a/k/a MudGuard

      2. Hallo Martin,

        kennt jemand einen guten RegEx für E-Mails?

        .*@.*\..* ;-)

        der erlaubt aber keine lokalen Adressen (z.B. root@localhost). Aber lassen wir das mal.

        Adressen mit localhost anzugeben, macht in einer Forumssoftware nicht wirklich Sinn, oder? Oder gibt es dafür einen realistischen Anwendungsfall?

        alles andere ist mehr oder weniger sinnfrei. Es gibt keinen Grund, die Validität einer E-Mail-Adresse prüfen zu wollen.

        Genau, denn erstens gibt es so viele Wenns und Abers, oder je nach Domain mal erlaubte, mal nicht erlaubte Eigenheiten, dass schon allein eine formale Prüfung ausufert, wenn sie alle Eventualitäten abdecken soll.
        Und zweitens sagt die Tatsache, dass eine e-Mail-Adresse formal korrekt ist, noch nichts darüber aus, ob sie tatsächlich existiert.

        Das sieht man ja an dem alten RegEx, der ließ nur fünfstellige Top-Level-Domains zu, weil man damals noch nicht damit rechnete, dass es jemals etwas Längeres wie beispielsweise .hamburg geben könnte...

        Gruß
        Julius

        1. Hallo

          kennt jemand einen guten RegEx für E-Mails?

          .*@.*\..* ;-)

          der erlaubt aber keine lokalen Adressen (z.B. root@localhost). Aber lassen wir das mal.

          Adressen mit localhost anzugeben, macht in einer Forumssoftware nicht wirklich Sinn, oder? Oder gibt es dafür einen realistischen Anwendungsfall?

          Rein theoretisch könnte man sich als Admin eines dedizierten Servers Status- und Fehlermeldungen dieses Servers an eine systemeigene Adresse schicken lassen. Ein sich registrierender Benutzer oder ein postender Besucher kann eine solche Adresse zwar ebenfalls angeben, sie wird dann aber unnerreichbar bleiben. Ein realistisches Szenario sehe ich hier auch nicht.

          Das sieht man ja an dem alten RegEx, der ließ nur fünfstellige Top-Level-Domains zu, weil man damals noch nicht damit rechnete, dass es jemals etwas Längeres wie beispielsweise .hamburg geben könnte...

          Dieses Problem wurde, wenn ich nicht irre, schon wenig später im hiesigen Forum diskutiert. Denn die den Regex sprengende TLD „museum“, die in den Diskussionen immer wieder herangezogen wurde, gibt es ja auch schon seit 2001.

          Tschö, Auge

          --
          Wir hören immer wieder, dass Regierungscomputer gehackt wurden. Ich denke, man sollte die Sicherheit seiner Daten nicht Regierungen anvertrauen.
          Jan Koum, Mitgründer von WhatsApp, im Heise.de-Interview
          1. Mahlzeit,

            .*@.*\..* ;-)

            der erlaubt aber keine lokalen Adressen (z.B. root@localhost). Aber lassen wir das mal.

            Adressen mit localhost anzugeben, macht in einer Forumssoftware nicht wirklich Sinn, oder? Oder gibt es dafür einen realistischen Anwendungsfall?

            nicht wirklich, das war eher als scherzhafter Einwand gemeint.

            Rein theoretisch könnte man sich als Admin eines dedizierten Servers Status- und Fehlermeldungen dieses Servers an eine systemeigene Adresse schicken lassen.

            Könnte man. Wenn aber ein mindestens zweiteiliger Hostname vorgeschrieben wird, gibt man stattdessen halt root@localhost.example.org an, also den FQDN.

            Ciao,
             Martin

        2. Tach!

          kennt jemand einen guten RegEx für E-Mails?

          .*@.*\..* ;-)

          der erlaubt aber keine lokalen Adressen (z.B. root@localhost). Aber lassen wir das mal.

          Mein Favorit ist .*

          Adressen mit localhost anzugeben, macht in einer Forumssoftware nicht wirklich Sinn, oder? Oder gibt es dafür einen realistischen Anwendungsfall?

          Ja. Ein Forum (oder eine Software allgemein) muss nicht zwingend nur im Internet eingesetzt werden. Es gibt genügend Anwendungsfälle für einen privaten Gebrauch, lokal oder im Intranet. Mich stört das jedes Mal ungemein, wenn eine Software keine lokalen Mailadressen entgegennehmen möchte. root ist ein perfekt valides Ziel auf meinem System, also lass mich das doch einfach verwenden, liebe Software, und versuch nicht klüger zu sein als ich!

          PHP hat eine eingebaute Filter-Extension, da gibts auch eine Email-Validierung. Aber die krankt auch an nicht verwendbaren lokalen Adressen.

          dedlfix.

          1. Hallo dedlfix,

            der erlaubt aber keine lokalen Adressen (z.B. root@localhost). Aber lassen wir das mal.

            Mein Favorit ist .*

            Also alle Zeichen erlauben?

            Adressen mit localhost anzugeben, macht in einer Forumssoftware nicht wirklich Sinn, oder? Oder gibt es dafür einen realistischen Anwendungsfall?

            Ja. Ein Forum (oder eine Software allgemein) muss nicht zwingend nur im Internet eingesetzt werden. Es gibt genügend Anwendungsfälle für einen privaten Gebrauch, lokal oder im Intranet.

            Ok, dann sollte ich das einbauen.

            Mich stört das jedes Mal ungemein, wenn eine Software keine lokalen Mailadressen entgegennehmen möchte. root ist ein perfekt valides Ziel auf meinem System, also lass mich das doch einfach verwenden, liebe Software, und versuch nicht klüger zu sein als ich!

            Deshalb finde ich diese „smarten“ Geräte auch nicht sonderlich hilfreich...

            PHP hat eine eingebaute Filter-Extension, da gibts auch eine Email-Validierung. Aber die krankt auch an nicht verwendbaren lokalen Adressen.

            Hm, dann lieber auf alles, dann ein @ und dann wieder alles Mögliche prüfen? – das scheint ja so ziemlich das einzig zuverlässig Überprüfbare zu sein...

            Gruß
            Julius

          2. Aloha ;)

            PHP hat eine eingebaute Filter-Extension, da gibts auch eine Email-Validierung. Aber die krankt auch an nicht verwendbaren lokalen Adressen.

            Das (oder besser gesagt das, was @Christian Kruse in seinem Posting verlinkte) habe ich durchgelesen, und bin dann auf folgenden sehr interessanten Kommentar gestoßen:

            Regarding "partial" addresses with no . in the domain part, a comment in the source code (in ext/filter/logical_filters.c) justifies this rejection thus:
            
                 * The regex below is based on a regex by Michael Rushton.
                 * However, it is not identical.  I changed it to only consider routeable
                 * addresses as valid.  Michael's regex considers a@b a valid address
                 * which conflicts with section 2.3.5 of RFC 5321 which states that:
                 *
                 *   Only resolvable, fully-qualified domain names (FQDNs) are permitted
                 *   when domain names are used in SMTP.  In other words, names that can
                 *   be resolved to MX RRs or address (i.e., A or AAAA) RRs (as discussed
                 *   in Section 5) are permitted, as are CNAME RRs whose targets can be
                 *   resolved, in turn, to MX or address RRs.  Local nicknames or
                 *   unqualified names MUST NOT be used.
            

            Es scheint also, dass "lokale" Adressen (ohne .) mit SMTP sowieso generell "verboten" sind; stattdessen sind wie @Der Martin schon schrieb dann wohl FQDNs zu verwenden.

            Gerade in diesem Licht scheint es mir dann doch sinnvoll (@Julius) einen Regex zu verwenden, der Adressen ohne . im Domain-Teil ausschließt. (Oder noch besser, direkt die genannte eingebaute Filter-Extension nutzen, der solche Adressen ja auch ausschließt.) Man könnte sogar darüber nachdenken, in den Wiki-Artikel einen kurzen Kommentar dazu aufzunehmen, der die Gründe für die Entscheidung (RFC-Verletzung) erklärt.

            Grüße,

            RIDER

            --
            Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
            # Facebook # Twitter # Steam # YouTube # Self-Wiki # Selfcode: sh:) fo:) ch:| rl:) br:^ n4:? ie:% mo:| va:) js:) de:> zu:} fl:( ss:) ls:[
          3. @@dedlfix

            PHP hat eine eingebaute Filter-Extension, da gibts auch eine Email-Validierung. Aber die krankt auch an nicht verwendbaren lokalen Adressen.

            Und an nicht verwendbaren internationalen Adressen.

            LLAP 🖖

            --
            „Wir haben deinen numidischen Schreiber aufgegriffen, o Syndicus.“
            „Hat auf dem Forum herumgelungert …“
            (Wachen in Asterix 36: Der Papyrus des Cäsar)
            1. Aloha ;)

              PHP hat eine eingebaute Filter-Extension, da gibts auch eine Email-Validierung. Aber die krankt auch an nicht verwendbaren lokalen Adressen.

              Und an nicht verwendbaren internationalen Adressen.

              Du weißt - ich bin nicht gerade eine Koryphäe was internationale Adressen angeht. Deshalb mal ganz naiv: Gibt es eine Möglichkeit, eine beliebige (internationale oder auch nicht) Adresse zu "transkribieren" (Stichwort Punycode, der ja teils für URLs verwendet wird)? So, dass man dann das Transkript mit der Filterfunktion validieren kann? Für die Validität ist es nach meinem Verständnis ja nicht weiter wichtig, ob das in der Adresse jetzt eigentlich ASCII-Zeichen sind oder nicht, es geht ja nur darum, die formalen Eigenschaften einer E-Mail-Adresse zu erfüllen oder eben nicht.

              Grüße,

              RIDER

              --
              Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
              # Facebook # Twitter # Steam # YouTube # Self-Wiki # Selfcode: sh:) fo:) ch:| rl:) br:^ n4:? ie:% mo:| va:) js:) de:> zu:} fl:( ss:) ls:[
              1. Tach,

                PHP hat eine eingebaute Filter-Extension, da gibts auch eine Email-Validierung. Aber die krankt auch an nicht verwendbaren lokalen Adressen.

                Und an nicht verwendbaren internationalen Adressen.

                Du weißt - ich bin nicht gerade eine Koryphäe was internationale Adressen angeht. Deshalb mal ganz naiv: Gibt es eine Möglichkeit, eine beliebige (internationale oder auch nicht) Adresse zu "transkribieren" (Stichwort Punycode, der ja teils für URLs verwendet wird)? So, dass man dann das Transkript mit der Filterfunktion validieren kann? Für die Validität ist es nach meinem Verständnis ja nicht weiter wichtig, ob das in der Adresse jetzt eigentlich ASCII-Zeichen sind oder nicht, es geht ja nur darum, die formalen Eigenschaften einer E-Mail-Adresse zu erfüllen oder eben nicht.

                jein, mit Punycode-Domains würde das im Domainteil gehen, aber der Lokalteil wird nicht durch umkodieren erreicht; bei SMTP hat man sich entschieden zukünftig auf UTF-8-Header zu setzen (Punycode für die Domain ist dann auch nicht mehr nötig), die Unterstützung ist allerdings bei weitem noch nicht in allen SMTP-Servern angekommen (Postfix kann es inzwischen; GMail unterstützt es wohl auch; Microsoft arbeitet wohl zumindest für die diesjährige Outlook-Version dran; in Exim ist es im Moment experimental, für Sendmail gibt es einen Patch) und ich würde davon ausgehen, dass es mindestens 5-10 Jahre dauern wird, bis die gesamte Infrastruktur umgestellt ist, nachdem alle nötigen Produkte (SMTP-Server, Libraries in div. Sprachen, IMAP-Server, Mailclients, Webclients) das unterstützen.

                mfg
                Woodfighter

  2. Hallo Julius,

    • RegEx für E-Mail scheint nicht auf heutige neuen Domains zu passen, beispielsweise wird mail@example.hamburg abgelehnt – kennt jemand einen guten RegEx für E-Mails?

    Benutze keine Regex, sondern eine Validierungs-Funktion, die dafür vorgesehen ist.

    LG,
    CK

    1. Hallo Christian,

      Benutze keine Regex, sondern eine Validierungs-Funktion, die dafür vorgesehen ist.

      Danke, das ist sehr praktisch! Damit kann ich auch gleich die Homepage-URL des Autors überprüfen.

      Gruß
      Julius

    2. Hi,

      Benutze keine Regex, sondern eine Validierungs-Funktion, die dafür vorgesehen ist.

      guter Punkt. Mit diesen Filter-Funktionen habe ich noch keine Erfahrungen. Aber ich fürchte, damit wird man auch einige False Positives bekommen. Ich weiß nicht, nach welchen Kriterien diese Funktionen vorgehen (und es ist mir im Moment zu viel Aufwand, im Quellcode zu wühlen). Existierende Domains könnte man durch eine direkte Anfrage ans DNS herausfinden.

      Aber wie sieht es mit RFC Violations bei einzelnen Anbietern aus? Ich entsinne mich, dass ich in den einschlägigen RFCs mal gelesen habe, ein Punkt am Ende des Local Part, also unmittelbar vor dem '@', sei nicht zulässig (keine Ahnung, warum). Aber beispielsweise GMX lässt solche Adressen zu - ein Bekannter von mir hat jahrelang eine Adresse in der Form x.y.@gmx.de verwendet (anstatt x und y seine echten Initialen eingesetzt). Wie geht man mit sowas um? Da hat man eine nicht regelkonforme, aber trotzdem existierende und verwendete Adresse. Eine kritische Prüfung würde sie aber als fehlerhaft abweisen.

      Deswegen bin ich trotz aller RegEx-Entwürfe und existierenden Validierungsfunktionen der Meinung, man kann/sollte eine e-Mail-Adresse nur auf die grundlegendsten Merkmale testen. Und das sind IMO die, die Matthias mit seinem Trivial-RegEx abdeckt: Ein paar beliebige Zeichen, dann ein '@', noch ein paar beliebige Zeichen, irgendwo ein Punkt und noch ein paar Zeichen dahinter.

      So long,
       Martin

      1. Tach!

        Benutze keine Regex, sondern eine Validierungs-Funktion, die dafür vorgesehen ist.

        guter Punkt. Mit diesen Filter-Funktionen habe ich noch keine Erfahrungen. Aber ich fürchte, damit wird man auch einige False Positives bekommen. Ich weiß nicht, nach welchen Kriterien diese Funktionen vorgehen (und es ist mir im Moment zu viel Aufwand, im Quellcode zu wühlen).

        "In general, this validates e-mail addresses against the syntax in RFC 822, with the exceptions that comments and whitespace folding are not supported."

        Also im Grunde genommen auch nur ein Regex.

        dedlfix.

      2. Hallo Martin,

        guter Punkt. Mit diesen Filter-Funktionen habe ich noch keine Erfahrungen. Aber ich fürchte, damit wird man auch einige False Positives bekommen.

        Es geht nicht darum, false positives zu vermeiden; das wird eh nichts. Es geht wirklich nur darum, nicht jeden Scheiss reinzulassen (z.B. blub@example.org\nBcc: long@example.org, list@example.org) und dafür zu sorgen, dass offensichtliche Fehler dem User nochmal vorgesetzt werden.

        LG,
        CK

        1. Hallo Christian Kruse,

          und dafür zu sorgen, dass offensichtliche Fehler dem User nochmal vorgesetzt werden.

          Was aber, wenn der offensichtliche Fehler kein Fehler ist?

          Bis demnächst
          Matthias

          --
          Wenn eine Idee nicht zuerst absurd erscheint, taugt sie nichts. (Albert Einstein)
          1. Hallo Matthias,

            und dafür zu sorgen, dass offensichtliche Fehler dem User nochmal vorgesetzt werden.

            Was aber, wenn der offensichtliche Fehler kein Fehler ist?

            Das ist schade, aber immer noch besser als seine Sender Reputation zu verlieren, denn die wiederzugewinnen kann wirklich lange dauern und sehr aufwendig sein.

            Edit: ja, da spreche ich aus Erfahrung... ein Kollege hat einmal aus Versehen eine automatisch generierte Mail an alle Absender seiner Inbox geschickt (>30k Mails), es hat mich insgesamt ein Jahr gekostet, in dem ich immer wieder mit verschiedenen Services kommunizieren musste, um wieder Mails an bestimmte Empfänger zustellen zu können.

            LG,
            CK

        2. Hi,

          guter Punkt. Mit diesen Filter-Funktionen habe ich noch keine Erfahrungen. Aber ich fürchte, damit wird man auch einige False Positives bekommen.

          Es geht nicht darum, false positives zu vermeiden; das wird eh nichts.

          okay, das heißt, du nimmst in Kauf, dass hin und wieder ein Anwender verunsichert wird, weil seine zumindest pragmatisch korrekte Mailadresse angeblich fehlerhaft ist. Dann muss aber die Möglichkeit bestehen, dass der arme Tropf in der zweiten Runde sagt: Leck mich, nimm's einfach.

          Es geht wirklich nur darum, nicht jeden Scheiss reinzulassen (z.B. blub@example.org\nBcc: long@example.org, list@example.org)

          Okay. Steuerzeichen sind AFAIK generell nicht erlaubt, die könnte man gezielt "rausprüfen". In dem Fall dürfte auch die nochmalige Bestätigung im Sinne von "Doch! Ich will das so!" nicht möglich sein.

          Das führt aber zwangsläufig dazu, dass man mindestens zweigleisig prüfen muss. Eine Warnstufe für mögliche Fehler, die dann aber in einem zweiten Schritt nochmal explizit bestätigt werden können, und eine Art Immediate Fail für offensichtlichen Quatsch, wie du ihn als Beispiel anführst.
          Damit ist unterm Strich weder ein RegEx, noch eine dedizierte Prüffunktion brauchbar, denn die können nur klar "Ja" oder "Nein" liefern, aber kein "Vielleicht".

          So long,
           Martin

          1. Hallo Martin,

            okay, das heißt, du nimmst in Kauf, dass hin und wieder ein Anwender verunsichert wird, weil seine zumindest pragmatisch korrekte Mailadresse angeblich fehlerhaft ist. Dann muss aber die Möglichkeit bestehen, dass der arme Tropf in der zweiten Runde sagt: Leck mich, nimm's einfach.

            Das wäre das Optimum, ja, aber vermutlich würde ich diesen Schritt einfach Zugunsten einfacheren Codes weglassen. Mir geht es hauptsächlich um...

            Es geht wirklich nur darum, nicht jeden Scheiss reinzulassen (z.B. blub@example.org\nBcc: long@example.org, list@example.org)

            Okay. Steuerzeichen sind AFAIK generell nicht erlaubt, die könnte man gezielt "rausprüfen". In dem Fall dürfte auch die nochmalige Bestätigung im Sinne von "Doch! Ich will das so!" nicht möglich sein.

            ... diese Art Fehler (z.B. durch c&p hervorgerufen, passiert hin und wieder halt) und Angriffe, um zu verhindern, dass man als Spammer eingestuft wird. Denn aus der Ecke heraus zu kommen ist wirklich schwer und aufwendig.

            LG,
            CK

      3. Hallo Der Martin,

        Aber wie sieht es mit RFC Violations bei einzelnen Anbietern aus? Ich entsinne mich, dass ich in den einschlägigen RFCs mal gelesen habe, ein Punkt am Ende des Local Part, also unmittelbar vor dem '@', sei nicht zulässig (keine Ahnung, warum). Aber beispielsweise GMX lässt solche Adressen zu - ein Bekannter von mir hat jahrelang eine Adresse in der Form x.y.@gmx.de verwendet (anstatt x und y seine echten Initialen eingesetzt). Wie geht man mit sowas um? Da hat man eine nicht regelkonforme, aber trotzdem existierende und verwendete Adresse. Eine kritische Prüfung würde sie aber als fehlerhaft abweisen.

        Der Regex, den <input type="email"> verwendet, erlaubt solche Adressen. Da die sich auch an den RFCs orientieren, gehe ich mal davon aus, dass es sich um eine valide Adresse handelt.

        Danke, @Matthias Scharwies für den entscheidenden Hinweis per PM.

        Bis demnächst
        Matthias

        --
        Wenn eine Idee nicht zuerst absurd erscheint, taugt sie nichts. (Albert Einstein)
    • Die Variablen (siehe neu.php) müssen nicht mehr gelöscht werden, seit sie nicht mehr von PHP automatisch importiert werden (magic_qoutes?), liege ich da richtig?
    unset($errors);
    unset($Thread);
    

    Variablen müssen in PHP eigentlich nie gelöscht werden. Stattdessen sorgt man besser dafür, dass man unterschiedliche Variablen für unterschiedliche Zwecke benutzt. Um Namenskonflikte zu vermeiden ist es hilfreich den Gültigkeitsbereich seiner Variablen einzuschränken, zum Beispiel über Funktionen. Beim Aufruf einer Funktion wird ein neuer Stackframe erzeugt. Wenn sie abgearbeitet ist wird der Stackframe wieder vom Stack genommen. Objekte in diesem Stackframe bleiben der Umgebung erhalten, wenn sie von außerhalb noch referenziert werden. Die Variablen selbst sind an die Lebensdauer des Stackframes gebunden. Damit verhindert man also viel eleganter, dass unerwünschte Nebenwirkungen auftreten, weil eine Variable unbeabsichtiger Weise von verschiedenen Teilen des Codes geteilt wird.

    1. Hallo 1unitedpower,

      • Die Variablen (siehe neu.php) müssen nicht mehr gelöscht werden, seit sie nicht mehr von PHP automatisch importiert werden (magic_qoutes?), liege ich da richtig?
      unset($errors);
      unset($Thread);
      

      Variablen müssen in PHP eigentlich nie gelöscht werden.

      Deshalb hat es mich auch gewundert, warum der Autor dieses Scripts das (Am Anfang des Scripts!) so gemacht hat und daher auch die Vermutung, dass das etwas mit register_globals zu tun hat.

      Stattdessen sorgt man besser dafür, dass man unterschiedliche Variablen für unterschiedliche Zwecke benutzt. Um Namenskonflikte zu vermeiden ist es hilfreich den Gültigkeitsbereich seiner Variablen einzuschränken, zum Beispiel über Funktionen. Beim Aufruf einer Funktion wird ein neuer Stackframe erzeugt. Wenn sie abgearbeitet ist wird der Stackframe wieder vom Stack genommen. Objekte in diesem Stackframe bleiben der Umgebung erhalten, wenn sie von außerhalb noch referenziert werden. Die Variablen selbst sind an die Lebensdauer des Stackframes gebunden. Damit verhindert man also viel eleganter, dass unerwünschte Nebenwirkungen auftreten, weil eine Variable unbeabsichtiger Weise von verschiedenen Teilen des Codes geteilt wird.

      Das hat der Autor des ursprünglichen Codes auch so gemacht, für meinen Geschmack hat der viele Funktionen verwendet. Hätte ich das von Grund auf geschrieben, wäre das wesentlich undurchsichtiger...

      Gruß
      Julius

    • Fehlermeldungen im Produktiv-Modus nicht ausgeben (in config.php festlegen)

    Die Möglichkeit bietet PHP dir bereits von Haus aus, wenn du das eingebaute Exception-System nutzt. Das gibt dir nämlich die Möglichkeit über php.ini-Einstellungen die Stufe des Error-Reporting einzustellen. Das Exception-System ist sowieso eine viel bessere Alternative zu abenteuerlichen Konstrukuten aus die() und exit().

    Und es erfordert für dein Tutorial gar nicht so viele Änderungen. Du müsstest beispielsweise aus diesem hier:

     $result = mysqli_query($db, $query);
     if (!$result) die("Die Datenbank konnte nicht abgefragt werden");
    

    nur dieses machen:

     $result = mysqli_query($db, $query);
     if (!$result) throw new Exception("Die Datenbank konnte nicht abgefragt werden");
    

    Oder noch schöner:

     $result = mysqli_query($db, $query);
     if (!$result) throw new Exception($result->error);
    

    Was du im Falle von mysqli-Fehlern sogar noch einfacher haben kannst, indem du die Library automatisch Fehler werfen lässt:

    mysqli_report(MYSQLI_REPORT_ALL);
    

    Das hat gleichzeitig den Vorteil, dass der aufrufende Code die Möglichkeit bekommt den Fehler abzufangen und zu behandeln. Dein Programm bleibt dann also lauffähig.

    • was kann ich stilistisch verbessern – ich will ja auch noch etwas dabei lernen :-)

    Wie gut kennst du dich denn mit Objektorientiertheit aus? Das würde sicher sehr zu einer erkennbaren Strukturierung des Codes beitragen.

    Besser nicht.

    1. Hallo 1unitedpower,

      • Fehlermeldungen im Produktiv-Modus nicht ausgeben (in config.php festlegen)

      Die Möglichkeit bietet PHP dir bereits von Haus aus, wenn du das eingebaute Exception-System nutzt. Das gibt dir nämlich die Möglichkeit über php.ini-Einstellungen die Stufe des Error-Reporting einzustellen. Das Exception-System ist sowieso eine viel bessere Alternative zu abenteuerlichen Konstrukuten aus die() und exit().

      Und es erfordert für dein Tutorial gar nicht so viele Änderungen. Du müsstest beispielsweise aus diesem hier:

       $result = mysqli_query($db, $query);
       if (!$result) die("Die Datenbank konnte nicht abgefragt werden");
      

      nur dieses machen:

       $result = mysqli_query($db, $query);
       if (!$result) throw new Exception("Die Datenbank konnte nicht abgefragt werden");
      

      Oder noch schöner:

       $result = mysqli_query($db, $query);
       if (!$result) throw new Exception($result->error);
      

      Was du im Falle von mysqli-Fehlern sogar noch einfacher haben kannst, indem du die Library automatisch Fehler werfen lässt:

      mysqli_report(MYSQLI_REPORT_ALL);
      

      Jepp, es ging mir von vornherein um das Melden der mysqli-Fehler, das ich an und Abschalten wollte, aber wenn ich das in die Log-Dateien schreiben kann, ist das noch besser, dann brauche ich das gar nicht abschaltbar machen...

      Vielen Dank, für deine Anregungen, ich schaue mir das alles mal genau an.

      Das hat gleichzeitig den Vorteil, dass der aufrufende Code die Möglichkeit bekommt den Fehler abzufangen und zu behandeln. Dein Programm bleibt dann also lauffähig.

      • was kann ich stilistisch verbessern – ich will ja auch noch etwas dabei lernen :-)

      Wie gut kennst du dich denn mit Objektorientiertheit aus? Das würde sicher sehr zu einer erkennbaren Strukturierung des Codes beitragen.

      Kannst du mir da Lesestoff zu empfehlen? Vielleicht etwas Kompaktes, wo die Konzepte von OOP in PHP genauer erklärt werden? Den Rest hole ich mir dann aus der PHP-Doku.

      Besser nicht.

      Vielen Dank für den Hinweis, ich werde mich damit auseinander setzen.

      Gruß
      Julius

      1. @1unitedpower

        • was kann ich stilistisch verbessern – ich will ja auch noch etwas dabei lernen :-)

        Wie gut kennst du dich denn mit Objektorientiertheit aus? Das würde sicher sehr zu einer erkennbaren Strukturierung des Codes beitragen.

        Kannst du mir da Lesestoff zu empfehlen? Vielleicht etwas Kompaktes, wo die Konzepte von OOP in PHP genauer erklärt werden? Den Rest hole ich mir dann aus der PHP-Doku.

        Was hältst du von dieser Einführung von Peter Kropff in OOP in PHP?

        Danke & Gruß
        Julius

        1. Hallo,

          Was hältst du von dieser Einführung von Peter Kropff in OOP in PHP?

          Ich finde sie nicht sonderlich gut, grade nach der Einleitung, wonach andere so schlecht sein sollen. Da hatte ich deutlich mehr erhofft. Stellenweise sind die Beispiele nur peinlich.

          Gruß
          Kalk

          1. Hallo Tabellenkalk,

            Was hältst du von dieser Einführung von Peter Kropff in OOP in PHP?

            Ich finde sie nicht sonderlich gut, grade nach der Einleitung, wonach andere so schlecht sein sollen. Da hatte ich deutlich mehr erhofft. Stellenweise sind die Beispiele nur peinlich.

            Was würdest du mir empfehlen? Vielleicht doch lieber „Klassen und Objekte“ im offiziellen PHP-Handbuch?

            Gruß
            Julius

            1. Hallo,

              Was würdest du mir empfehlen? Vielleicht doch lieber „Klassen und Objekte“ im offiziellen PHP-Handbuch?

              Das wäre zumindest erster Anlaufpunkt für das Umsetzen von OOP in PHP. Ansonsten ist OOP ja nur Programmierprinzip, das man unabhängig von der verwendeten Sprache verstanden haben muss. Eine echte Empfehlung habe ich leider nicht.

              Gruß
              Kalk

              1. Hallo Tabellenkalk,

                Ansonsten ist OOP ja nur Programmierprinzip, das man unabhängig von der verwendeten Sprache verstanden haben muss.

                Alles klar. Dann versuche ich erst mal OOP zu verstehen und dann wie es in PHP umgesetzt wird.

                Gruß
                Julius