Julius: Wiki: Dateiupload mit PHP

Beitrag lesen

problematische Seite

Hallo dedlfix,

  • Dateinamen werden zufällig erzeugt, man spart sich die ganzen Probleme mit Case-sensitivity, Zeichen oder ganzen Dateinamen mit spezieller Bedeutung.

Der zufällig erzeugte Name und der im Upload übergebene Name sollten am Ende übergeben werden. Der Verwender möchte letzteren vielleicht nicht verlieren. Andererseits vergibt PHP bereits einen zufälligen temporären Namen, den man weiterverwenden kann, auch wenn man die Datei anderswohin kopiert. Die Wahrscheinlichkeit sollte ausreichend gering sein, dass der Name mehrfach vergeben wird. Gegebenenfalls muss nur eine Endung hinzugefügt werden, damit der Webserver sie mit richtigem Content-Type behandeln kann.

Die Vergabe der richtigen Endung ist geplant. Was die Eindeutigkeit des Dateinamens angeht, habe ich tatsächlich auch schon über die Weiterverwendung des temporären Namens (ggf. plus ein paar extra-Zeichen) nachgedacht, denn PHP wird bei mehreren gleichzeitig durchgeführten Dateiupload wohl kaum mehrmals den selben Namen vergeben, sodass man sich wohl eher kein Time-of-Check-to-Time-of-Use-Problem einhandeln dürfte. Mir gefällt nicht, dass move_uploaded_file keine Möglichkeit bietet, den gewünschten Dateinamen vor dem Verschieben irgendwie zu „reservieren“. Vorab kann ich natürlich prüfen, ob die angedachte Datei bereits existiert (sicher ist sicher), aber eben leider nicht sperren. Dieses Problem ist mir aufgefallen und TS beim Schreiben des ursprünglichen Artikels offensichtlich auch. Nur sonst konnte ich nichts dazu finden, weshalb ich mich frage, ob das überhaupt tatsächlich ein Problem darstellt.

  • Uploads werden außerhalb des Document-Roots gespeichert – gibt es eigentlich wirklich Webhoster, bei denen das nicht geht?

Welche Verzeichnisse außerhalb vom DocumentRoot liegen und beschrieben werden können, ist individuell. Ob der Verwender das generell außerhalb haben möchte, ist auch nicht gewiss.

Irgendwie muss man sicherstellen, dass der PHP-Interpreter sich nicht für die hochgeladenen Dateien interessiert (ja, das ist trotz der richtigen Dateiendung bei schlampiger Konfiguration des Webservers möglicherweise ein Problem). Außerhalb des Document-Roots zu speichern erschien mir da die sicherste Lösung. Wenn denn das ausliefernde Skript den übergebenen Dateinamen korrekt behandelt...
Ich sollte mal in den Quellcode von WordPress gucken, wie die das lösen. Sollte das tatsächlich ein solches Problem sein, dann müssten die sich ja bei der Verbreitung damit beschäftigt haben.

Ich werde wohl nicht darum herum kommen, beide Ansätze und deren Fallstricke genau zu erklären. Die Konfiguration des Webservers erwähne ich nur, das ist definitiv ein Thema für sich und individuell.

Angenommen du schreibt eine Funktion, die sich um das Behandeln des Uploads kümmert, und dazu ein move_uploaded_file() ausführt, dann kann es sein, dass der Verwender die Datei nochmal kopieren muss, weil er sie woanders ablegen möchte.

Guter Punkt! So ein Gebastel habe ich tatsächlich kürzlich in einem Projekt gefunden: base64-kodierte Daten werden als Parameter entgegengenommen, dekodiert und als Datei gespeichert, die selbe Datei drei Zeilen später eingelesen und gelöscht, deren Inhalt wieder base64-kodiert und per E-Mail verschickt 🤦.

Andererseits ist es wie erwähnt sowieso individuell, wo was abgelegt werden kann respektive soll, so dass du im Falle einer Funktion einen Parameter entgegennehmen müsstest, der den Zielpfad angibt. Aber wenn du nichts weiter als move_uploaded_file() zuzüglich vorheriger Prüfungen ausführst, dann kann diesen letzten Schritt auch der Verwender selbständig gehen. Es reicht dann, nur zu zeigen, welche Prüfungen erforderlich sind.

Den Weg werde ich auch gehen, Danke! Es nimmt Komplexität aus dem Code, schafft Raum für Erklärungen und ermuntert den Leser des Tutorials zum Nachdenken über seine Anforderungen.

Das Web ist voll von halbgaren Lösungen, auf die sonst zurückgegriffen würde (diese ist davon noch die am wenigsten unsicherste [...]

Die Fehlerbehandlung mit die() führt zu einer unakzeptablen UX. Das kann man so nicht bieten. Andererseits kann man auch nicht so allgemein eine bessere Variante zeigen, die allen Ansprüchen und Gegebenheiten gerecht wird. Exceptions werfen oder eine Liste mit Fehlermeldungen zurückgeben wären Alternativen, bei denen der Verwender individuell reagieren kann.

Danke! Aus der UX-Perspektive habe ich die Verwendung von die() tatsächlich noch nicht betrachtet. Mit die() schnell das Programm zu beenden, ist für den Entwickler vermutlich einfach die am schnellsten hingerotztbare „Lösung“. Meine angedachte Lösung habe ich bereits intuitiv mit einer solchen Liste ausgestattet und überlegt, welche der Fehlermeldungen dem Nutzer wie vermittelt werden sollen. Dass z. B. eine PHP-Extension den Upload abgebrochen hat, interessiert den Entwickler, aber nicht den Nutzer. Der muss nur wissen, dass es nicht geklappt hat.

Und nun zuletzt meine Frage: Meint ihr, dass dieser Artikel ins Wiki passen würde? Ich habe Bedenken, dass er am Ende wie das Loginsystem damals entfernt wird und die Arbeit letztlich für die Katz war.

Das kommt ganz darauf an, ob man sich einigen kann, welche Qualität der Artikel haben soll.

Klar, wenn ich Müll oder Unpassendes schreibe und mir das begründet wird, werde ich keinen Aufstand machen, wenn das weg kommt. Ich bemühe mich um Qualität und bin um Hilfe auf dem Weg dorthin dankbar 😀.

Gruß
Julius

3 52

Wiki: Dateiupload mit PHP

Julius
  • php
  • selfhtml-wiki
  • sicherheit
  1. 0
    dedlfix
    1. 0
      Matthias Scharwies
      1. 2
        Julius
    2. 3
      Julius
      1. 1
        TS
        1. 0
          1unitedpower
          1. 1
            Julius
            1. 0
              1unitedpower
              1. 0
                TS
                1. 0
                  1unitedpower
          2. 0
            robertroth
            1. 3
              Raketenquellsuchsystem
              1. 0

                Wiki: Dateiupload mit PHP (Verständlichere Ergänzung)

                Raketenquellsuchsystem
              2. 2
                robertroth
                1. 0
                  Raketenquellsuchsystem
                2. 1
                  Rolf B
          3. 1
            TS
            1. 0
              1unitedpower
              1. 1
                TS
                1. 0
                  1unitedpower
                2. 1
                  robertroth
                  • idee
                  • php
                  • sicherheit
            2. 1
              Julius
              1. 2
                TS
                1. 2
                  Julius
                  1. 0
                    TS
            3. -1
              Raketenstarter
              1. -1
                Raketenstarter
      2. 0
        dedlfix
  2. 1
    Gunnar Bittersmann
    • grafik
    • grafik
    • selfhtml-wiki
    1. 0
      Der Martin
      1. 0

        webp-Konverter <.->

        Raketenwilli
        1. 0
          Der Martin
          • grafik
          • grafik
          1. 0
            Raketenwilli
            • produktinfo
            1. 0
              Der Martin
              • humor
              • produktinfo
          2. 0
            Raketenwilli
    2. 2
      dedlfix
  3. 2
    Matthias Apsel
    1. 2
      Julius
  4. 2
    Felix Riesterer
    1. 4
      Julius
  5. 0
    1unitedpower
    1. 1
      Julius
  6. 2
    Julius
    1. 0
      TS
      1. 1
        Julius
        1. 0
          TS
          1. 0
            Tabellenkalk
            1. 0
              TS
              1. 0
                raketenquelltextleser
                1. 1
                  Julius
                  • php
                  • sicherheit
              2. 1
                Julius