Upload von Dateien

  • Hallo zusammen,


    um Bilddateien hochzuladen haben ich mal ein wenig an das Script von Axel Pratzner gehalten.
    Dort steht dann auch folgende Zeile drin:


    move_uploaded_file ($_FILES['uploaddatei']['tmp_name'],'hochgeladenes/'. $_FILES['uploaddatei']['name'] );




    Also wenn ich das richtig sehe, dann wird die Bilddatei dann in einem Unterverzeichnis 'hochgeladenes/' gespeichert. (relative Position des Unterverzeichnisses muss beachtet werden.)


    Jetzt muss ich aber auf verschiedenen Webseiten auch Bilddateien hochladen. Damit Sie dann aber getrennt von einander sind, wollt ich Sie in verschiedene Unterverzeichnisse laden.
    Dazu der Befehl:


    move_uploaded_file ($_FILES['uploaddatei']['tmp_name'],'images/vorstand/'. $_FILES['uploaddatei']['name'] );



    Aber, man kann es schon erraten; 8) ; die Dateien werden immer noch im alten Verzeichnis gespeichert, obwohl der Speicherort im Befehl was anderes angibt.
    Ein Neustart von XAMPP- Diensten habe ich schon durchgeführt. Gleichzeitig auch den Browser (Chrome) neu gestartet.


    Und, kann jemand das Geheimnis entlüften, warum die Dateien nicht im richtigen Ordner gespeichert werden?





  • Das sollte aber so funktionieren.
    http://php.net/manual/de/function.move-uploaded-file.php
    bool move_uploaded_file ( string $filename , string $destination )
    Du kannst ja mal testen, was die Funktion zurück gibt. Evtl guckst Du auf "alte Files" und die eigentlichen wurden nicht verschoben.


    Teste mal:

    PHP
    $path = 'images/vorstand/';
    $destination = $path . $_FILES['uploaddatei']['name'];
    var_dump(is_writable($path));  
    $result = move_uploaded_file($_FILES['uploaddatei']['tmp_name'], $file);



    Info am Rande: beim Fileupload werden die Dateien in das tmp Verzeichnis gelegt.
    Dateien, die dort drin verbleiben, werden nach Ablauf des PHP Scripts automatisch gelöscht (wenn nicht um-/abgestellt).

  • Zuerst mal danke cotton.


    Also dann mal da zu:
    Ich kann direkt in den Ordner rein schauen. Und da kommt kein Bild an. Und ich leere ihn jedesmal bevor ich es erneut versuche?!, Brauch ich aber nicht, kommt ja nix an.
    Ich hatte es schon einmal auf einer anderen Seite, wo ich mir zum Verständnis diesen Bilderupload schon einmal genau so gebaut hatte. Und dort funktionierte es.


    Also nach einer schlecht geschlafenen Nacht, und einer ewig langen Dusche, kam mir folgende Frage:


    Da ich auf dieser Seite schon einmal ein <form>-tag geöffnet habe, und dieses erste <form>-tag erst nach dem <form>-tag des Bilderuploads wieder schließe:


    Kann man überhaupt <form>-tags schachteln. Oder muss ich den ersten beenden bevor ich ein weiteres Formular öffne?
    Nur so ein Gedanke, für den ich auf dieversen Pages auch keine Antwort gefunden habe.
    Also ich kann immer wieder nur sagen:


    Nach endlicher Verzweiflung und jede Menge ausprobieren, gibt es kein besseres Gefühl, als dass, wenn es dann funktioniert.
    MAN DARF NUR NICHT AUFGEBEN!!!


    Also meine Idee den <form>-tag anders zu setzen, und immer erst den <form>-tag zu schließen, bevor ein neuer geöffnet wird, war genau richtig.


    Das man dafür aber erst immer eine Nacht schlecht schlafen muss, und erst unter der langen Dusche die Erleuchtung kommt stört mich.


    Und damit ist meine Frage auch beantwortet:


    NEIN <form>-tags kann man nicht schachteln. Formular im Formular geht nicht. Das innere Formular reagiert dann nicht mehr, oder zumindest nur mit den Konditionen des äußeren.

  • Stimm, das geht net.
    Manche Fehler findet man alleine nicht am gleichen Tag. Ist öfter so. Am nächsten Tag guckt man sich das an und denk "oh man, ist doch klar ... " :)
    Schön, dass es funktioniert =)

  • So weit so gut.


    Es geht mir hier um eure Abschätzung der Sicherheit.
    Mit dem obigen habe ich jetzt die Grundlage geschaffen Bilder uploads zu machen. Kommen auch im richtigen Ordner an.
    Also bei der Webpage die ich baue, werden es drei Ebenen geben.
    1) Der Interessierte im Web. Der bekommt die 'Front-End-Page' zu sehen.
    2) Der User: Hier ist der erste Passwortgeschützte Teil: Hier können Einstellungen vorgenommen werden, und Bilder hochgeladen werden.
    3) Der Master: Dieser Bereich ist für mich: Dort kann ich grundsätzlich Seiten freigeben, und Einstellungen Administrativ machen.


    So dieser Beitrag dreht sich um Ebene 2 und Ebene 1.
    Also in Ebene 2 möchte ich die Bilder wie oben beschrieben uploaden. Da ich ja in der Variablen $_FILES['uploaddatei']['name'] den Dateinamen habe, möchte ich diesen in der Datenbank speichern.
    Da dieser Vorgang ungefähr 15 mal wiederholt wird (der vorstand ist groß) lohnt es sich für diesen Bereich ein eigene Tabelle anzulegen. Auf der Ebene 1 möchten dann den Dateiname im <img src=""> wieder auslesen und das Bild anzeigen lassen.


    Mein Gedanke dabei: Es kann doch jetzt nur das Bild geladen werden, welches in der Datenbank hinterlegt ist. Und ist das Bild mi diesem Dateinamen im Ordner nicht vorhanden, dann wird keines geladen und ein leerer Frame erscheint. Somit kann aber auch kein anderes geladen werden.


    Was haltet ihr von diesem Gedankengang?
    Wo sind hier die Sicherheitslücken?!

  • Prüfe beim Upload, ob es ein Bild ist. Wenn nicht, dann Fehler und verwerfen.
    Guck mal in Google nach "php check if uploaded file is image".
    (Ich empfehle da imagecreatefromstring( file_get_contents($source) ); -- wenn es kein Bild ist, gibt es einen Fehler)


    Nutze beim Speichern der Bilder und Namen der Dateien in SQL eigene Namen (zb md5(filename)).

  • Hallo cotton,


    wie von Axel Pratzner empfohlen: nutzte PHP.net für die Dinge die Du nicht weißt.
    Also bin ich dann mal da rein und hab mir die Beschreibungen von imagecreatefromstring angeschaut:


    imagecreatefromstring — Create a new image from the image stream in the string


    Beschreibung ¶


    resource imagecreatefromstring ( string $image )
    imagecreatefromstring() returns an image identifier representing the image obtained from the given image. These types will be automatically detected if your build of PHP supports them: JPEG, PNG, GIF, WBMP, and GD2.



    Also so wie ich das verstehe, wird hier ein neues Bild erzeugt aus einem string?!?!?!?
    Oder meldet diese Funktion nur, ob es ein Bild des Formats jpg, jpeg, png, gif usw. ist?


    Aber wie hilft mir das richtig weiter?
    Den Dateinamen habe ich doch schon in der Datenbank. Und das es ein Bild ist, sehe ich daran, das er es mir direkt anzeigt! Oder wird durch diese Funktion grundsätzlich alles abgefangen was keine Bild ist?


    Wird dies nicht auch dadurch erreicht?
    $zugelassenedateitypen = array("image/png", "image/jpeg", "image/gif");
    if ( ! in_array( $_FILES['datei1']['type'] , $zugelassenedateitypen ))

  • Die Typen kann man Fälschen.
    Eine Datei my.png kann auch ein Javascript sein, das einfach nur mit einer andere Endung versehen wurde.


    Die Funktion imagecreatefromstring nutzt die Rohdaten (deswegen file get contents) um ein neues Image zu erstellen.
    Sollten die Rohdaten nicht ~"von einem Bild" stammen, kann diese Funktion kein Bild erstellen.
    Und genau dann wei0t Du , dass jemand versucht hat etwas anderes hochzuladen.


    Es gibt sicherlich noch andere Wege. Ich fand diesen Weg einfach recht simpel und sicher.


    Bsp:


    Siehe auch comment => http://php.net/manual/de/funct…reatefromstring.php#94254

  • Danke cottton, habe ich verstanden, kommt bestimmt zum Einsatz!


    ==============================================================================================================================================
    Dateiupload erweitert:


    Im code von Axel Pratzner



    <form name="uploadformular" enctype="multipart/form-data" action="dateiupload.php" method="post" >
    Datei: <input type="file" name="uploaddatei" size="60" maxlength="255" >
    <input type="Submit" name="submit" value="Datei hochladen">
    </form>


    Ich habe dann ein Formular entwickelt, in dem direkt mehrere Felder ausgegeben werden:


    Ich gebe die Input felder (nicht nur die aus dem code oben, auch noch andere) direkt in einer while-schleife aus.
    Somit habe ich aber das Problem, das beim Ablauf der while-Schleife das inputfeld immer den selben namen hat. Gut hab schon einmal ein bischen geguckt, kann den Namen sehr wahrschienlich erweitern auf name="uploaddatei[id]" oder so, damit direkt bei $_POST[uploaddatei[id]] ein 2 dimensionales Array entsteht.
    Geht das nicht einfacher?


    Mein weiteres Problem, ist das speichern der jeweiligen Dateinamen aus dem Array, in die Datenbank?!
    Ich denke, das beim speichern dann auch eine while Schleife durchlaufen werden muss.

  • OK, kommt:


    habe jetzt bestimmt 10 mal versucht den Quellcode mit Zeilenformatierung hierher zu kopieren, doch die Leerstellen am Anfang werden einfach gelöscht, sorry!
    Also, gestern habe ich da noch was geändert, aber funkt noch nicht:



    PHP
    <?php
    while($reihe=mysqli_fetch_assoc($datensatz)) 	{                echo"<section id="person">";	// ############################ // #####   Eingabe Bild   ##### // Kontrolle, ob Dateityp zulässig ist $dateitypen = array("image/png", "image/jpeg", "image/gif"); if ( ! in_array( $_FILES['reihe']['type'] , $dateitypen ))	{                            echo "<p>Dateitype ist NICHT zugelassen</p>";                        } else  {                            move_uploaded_file ($_FILES['reihe']['tmp_name'],'images/vorstand/'.$_FILES['reihe']['name']); 	    echo "<img src="images/vorstand/".$_FILES['reihe']['name']."" height="250px" width="188px" class="bild"></br>"; 	 $vorstand1=clearstring($_FILES['reihe']['name']);                            echo"<p>Dateiname: ".$vorstand1."</p>";                        } 
    echo"<form name="uploadformular" enctype="multipart/form-data" action="vorstand_TEST.php" method="post" >"; echo"<img src="images/vorstand/".clearstring($reihe['bild'])."" height="250px" width="188px" class="bild" >"; echo"<input type="file" name="datei[pos]" size="60" maxlength="255" class="submit_button"></br>"; echo"<input type="Submit" name="submit" value="Datei hochladen / speichern" class="submit_button"></br>";                echo"</form>";
    ?>


    [size=10]
    <section> und <table> dienen nur der Ordnung, und der Ansprache über CSS.
    Sinn und zweck: Es sollen Daten aus der Datenbank abgerufen werden. Diese Sollen durch einen While Schleife laufen, und ausgegeben werden.
    Gleichzeitig sollen aber auch die Input Felder und der Dateiupload für jeden Datensatz aufgebaut werden.


    Mein Gedankliches Problem: Baue ich die INPUT Felder durch ne Whileschleife auf, muss jedes Inputfeld eine eigene Bezeichnung in name="" bekommen, damit ich Sie dann über $POST wieder separate ansprechen und dann die geänderten Daten durch SQL="Update ... in die Datenbank schreiben kann. Da die Daten in der Datenbank über die 'pos' -Felder eindeutig werden, wollte ich dieses Feld 'pos' aus Datenbank für den index des INPUT Feldes nehmen. Dann wäre das Inputfeld direkt über die pos nr mit dem Datenbankfeld verbunden.


    Unter der Überschrift #### Eigabe Dateiname #### gebe ich nur den Dateinamen des Bildes aus. Die Eingabe des Dateinamen geschieht automatisch beim Upload der Bilddatei.


    Die Datenbankfelder sind aufgebaut:


    1 id
    2 seite (hiermit möchte ich nur selektieren können, in welcher Seite ich die Datensätze verwenden möchte. Also werden aus verschiedenen Sieten Daten in einer Tabelle gesichert.)
    3. pos (Feld damit ich die Ausgabenreihefolge festlegen kann; Über die id geht es nicht, da in dieser Tabelle gleiche Daten aus anderen Seiten gespeichert werden. Zudem wird es möglich sein die Datensätze zu löschen und neu anzulegen. Dann stimmt die Reihenfolge der id ohnehin nicht mehr.)
    4. titel
    5. bild (Dateiname)
    6. Name (Name der Person


    So jetzt sind alle Geheimnisse gelüftet.


    Habe den Quelltext jetzt mal gekürzt. Jetzt steht oben nur noch, wo es mir darauf ankommt. Und ich habe die Echo's so weit gekürzt, wie ich konnte, damit ich den Code noch verstehe. Besser so cottton?

  • Wenn du PHP Code posten möchtest musst du ihn einfach in den entsprechenden BB-Code einfügen.


    Diese Eingabe:

    Code
    Mein Code:
    [code=php]
    if(isset($name))
    {
        print "Hallo $name!";
    }

    [/code]
    Erzeugt diese Ausgabe:


    Zitat

    Mein Code:

    PHP
    if(isset($name))
    {
        print "Hallo $name!";
    }


    Ich habe deine Beiträge mal entsprechend angepasst. Du kannst auch mal auf Bearbeiten klicken und schauen wie ich das gemacht habe.


    Alles dazu kannst du, wie von wolf: angemerkt, auch hier nachlesen.

  • Das hier:

    PHP
    $_POST['pos[pos]']


    sollte so aussehen:

    PHP
    $_POST['pos']['pos']


    Tipp: bei den vielen echos sieht man nicht durch.
    Würde empfehlen:


    oder:

  • Mein Problem im Moment:


    Ich habe Inputfelder (beziehe mich hier aber nur auf eins).
    Gelesen habe ich im Internet, dass ich bei einem Inputfeld über das Attribut name="" bestimmen kann, die Daten direkt in ein Array gespeichert werden können.
    Dazu sieht der Aufbau dann so aus:


    <input type="text" name="input[] method="POST"">


    So damit würde wenn ich jetzt über eine Schleife mehrere input-Felder aufbaue der Ausgabewert für die Felder folgender massen sein:


    input Feld 1 => $_POST['input['1']']
    input Feld 2 => $_POST['input['2']']
    input Feld 3 => $_POST['input['3']']
    usw.


    Soweit richtig?


    Wenn ja dann weiter:
    Aus einer Datenbank hole ich mir Daten:


    $sql_datenbank="SELECT
    `pos`,
    FROM
    `wcm_person`
    WHERE
    `seite` = 'vorstand'
    order by pos ";
    $datensatz=mysqli_query($mysqli, $sql_datenbank);

    Diese Daten lasse ich mir in einer Schleife ausgeben, und gleichzeitig werden die inputfelder erzeugt:


    while($reihe=mysqli_fetch_assoc($datensatz))
    {
    Ausgabe Datenbankinhalte (siehe anefügtes Bild!)
    echo"<input type=\"text\" name=\"pos['$pos']\" class=\"feldinhalt\" value=\"".$_POST['pos[$pos]']."\">";

    }
    Ich möchte erreichen, dass nicht nur die inputfelder direkt den richtigen Arraynamen über das Attribut name bekommen, sondern beim Auslesen der Daten aus der Datenbank lese ich auch das Feld 'pos' aus. Dieses soll jetzt als Index dienen im Inputfeld 'name'.


    Also ungefäht so (und hier komme ich einfach nicht weiter):


    <input name="input['$pos']" >
    oder
    <input name="[input] [pos]>
    oder
    <input name="[input] [$pos]>
    oder
    <input name="[$input] [$pos]>




    Hab schon etliche Seiten durchforstet, aber nix gefunden wie hier die Formatierung sein muss, damit ich im nachhinein dann auch wieder innerhalb der Schleife die Daten in die Datenbank zurückschreiben kann. Denn hier sehe ich das nächste Problem:


    $sql_person = " UPDATE `wcm_person`
    SET
    `pos` = '{$_POST['pos[$pos]']}', (wie muss hier dann die Formatierung sein?
    WHERE
    'seite' = 'vorstand'
    AND
    'pos' = '$pos'";
    mysqli_query($mysqli, $sql_person);




    ###########################################################################################################
    Erst mal Danke cottton.
    Soweit verstanden. Muss Also $_POST['pos']['pos'] heißen.

    Dazu noch ne Frage: das zweite ['pos'] kann das auch ['$pos'] sein? Denn ich möchte ja nicht nur ein dreidimensionales Array aufbauen, sondern der zweite Indize soll ja vorbelegt sein - halt mit der jeweiligen Positionsnummer die mit der Positionsnummer aus der Datenbank gleich ist?




    Damit aber noch nicht genug meiner Unkenntnis:
    Bei einem Input Feld kann ich dann auch direkt den Namen des dreidimensionalen Arrays dort im Attribut name= "" hinterlegen?
    Sähe das dann in etwa so aus:?
    <input name="['$pos'] ['pos']>





    Also hab den Input dann mal so gestaltet:
    echo"<td><input type=\"text\" name=\"{['$pos']['pos']}\" class=\"feldinhalt\" value=\"".$_POST['$pos']['pos']."\"></td>";



    Bekomme auch keine Fehlermeldung und der Index ['$pos'] stimmt jetzt auch überein mit der Position aus der Datenbank.
    Aber speichern tut er noch nicht.
    Dort ist dann immer eine 1 im Feld. Also $_POST['$pos'][pos] ist immer mit einer 1 gefüllt. Und da steig ich noch nicht hinter warum das so ist.
    Abgesehen davon das er die Werte damit nicht in die Datenbank bringt:

    $sql_person = " UPDATE `wcm_person`
    SET
    `pos` = '{$_POST['$pos']['pos']}',
    `titel` = '{$_POST['titel']}',
    `bild` = '{$_FILES['datei']['name']}',
    `name` = '{$_POST['name']}'
    WHERE
    'seite' = 'vorstand'
    AND
    'pos' = '$pos'


    ";
    mysqli_query($mysqli, $sql_person);

    Hallo,


    also mizt den untenstehenden Zeilen definiere ich doch eigentlich das Array $reihe[] schon mit den Indizes [Vorname] und [Name], oder?


    PHP
    $reihe['Vorname'] = empty($_POST['st_bn_vorname'])?$reihe['Vorname']:$_POST['st_bn_vorname'];$reihe['Name'] = empty($_POST['st_bn_name'])?$reihe['Name']:$_POST['st_bn_name'];



    Warum bekomme ich dann folgende Warnungen:

    Code
    Notice: Undefined variable: reihe in D:\Webseiten\SchuetzengesellschaftHubertus\app\benutzer_detail.php on line 330
    Notice: Undefined index: Name in D:\Webseiten\SchuetzengesellschaftHubertus\app\benutzer_detail.php on line 331
  • Man kann es in eine Zeile schreiben, muss man aber nicht ;)


    Du verwendest $reihe['Vorname'], obwohl es wohl nicht gesetzt war:


    Wenn Du $reihe['Vorname'] Hier das erstemal definieren willst, dann eher so:

  • REGEX 'en


    Ich will überprüfen ob in einer Eingabe nur folgende Zeichen verwendet werden:
    - Kleinbuchstaben
    - Großbuchstaben
    - Sonderzeichen !, #, %



    und habe nun folgendes mal geschrieben:
    "/[0-9a-zA-Z\#\!\%]/"


    Aber dies überprüft nur auf das erste eingegebene Zeichen. Nun hab ich mich auch im Internet umgeschaut und hab ne Erweiterung gefunden:


    "/[0-9a-zA-Z\#\!\%]*/"


    Soll bezwecken, dass er jede Stelle der Zeichenkette überprüft, ob Sie aus den oben angegebenen Zeichen besteht.
    Funktioniert aber nicht.



    2 Mal editiert, zuletzt von willi356 () aus folgendem Grund: Anderes Thema hat sich erledigt.

  • Also eigentlich funktioniert alles, nur nicht so, wie ich es will:


    PHP
    function pr_bennr($inhalt){  if ($inhalt ==="") { echo"<td><img src="../standard/icon/gelbes_ausruf.png"></td>";                         $pr = 'falsch';}  else { $ausdruck="/[[0-9]{5}[^(a-zA-ZäöüÄÖÜ<>#!*+")]*/";  if   (preg_match($ausdruck, $inhalt)== false)  { echo"<td><img src="../standard/icon/rotes_kreuz.png"></td></tr>";  echo"<tr><td></td><td class="red">- 5-stellig</br>- nur Zahlen</td>";  $pr = 'falsch';}  else { echo"<td><img src="../standard/icon/gruener_haken.png"></td>";  $pr = 'richtig';}  }    $inhalt="";    return($pruefung);    }


    Für die Darstellung des PHP kann ich nix, neine ich schreibe das nicht alles in eine Zeile, Wolf untersucht dieses Phänomen schon, noch keine Lösung in Sicht.






    Die Ausgabe ist die '1' die links unten neben dem Kasten steht.
    Wie kann ich die Ausgabe von dem return unterdrücken?




    Aber irgendwie habe ich im Moment einen Balken vor dem Hirn.

  • Du brauchst glaub ich einen edito, der Dir Fehler markiert.
    Sieh Dir mal das Bild an:html-seminar.de/woltlab/attachment/969/


    Das hier könnte funzen:


    PS: evtl kann das Forum den Code wegen der Fehler nicht richtig darstellen.

  • Hallo Cotton,



    ne nutzte doch einen Editor: Brackets.
    Habe das mit Wolf schon durchgekaut. Liegt nicht an dem Brackets, oder an meinem Windows, oder, oder, oder...
    Wolf hat von mir diverse Dateien bekommen und ist am Suchen (hoffe ich zumindest).



    UNd jetzt zu oben:


    Die Ausgabe in Array habe ich gelöst. Aber durch den return $pr wird mir der Wert immer ausgegeben, also aufs Bild geschrieben. Also immer richtig oder falsch auf den Bildschirm ausgegeben.
    Wenn ich jetzt 6 x verschiedenen Felder Prüfe, stehen dort auch 6 mal richtig oder falsch hintereinander.



    Wie kann ich das unterbinden?
    Han in anderen Foren was davon gelesen die Variable in der Funktion als globale variable zu verwenden! Wäre das was?

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!