# Fileupload via File Dialog im Browser



## KarlPichler (1. März 2012)

Hallo liebes Forum,

Hab wieder mal ne Frage! 
Ich möchte gerne eine File Upload programmieren.

Der sollte wie folgt aussehen: 

Wenn ich den "Browse" Button drücke, öffnet sich ein FileOpenDialog. Darin kann ich mehrere Datein auswählen. 

Möchte auf jeden Fall mehrere Datein auswählen können! 

Diese Dateien sollen danach auf einen FTP Server hochgeladen werden. Wünschenswert wäre eine progressBar dazu, und das ganze im Browser. 

So wie der Bilderupload bei beispielsweise Facebook.
Ich hab allerdings keine Ahnung wie ich das machen kann, nicht einmal wie ich anfangen sollte. PHP, Java, keine Ahnung.

Gibt es für so etwas eine Art tuorial, oder etwas vorgefertigtes? 
Bitte um Hilfe! Danke im Vorraus!


Lg


----------



## threadi (2. März 2012)

Mit HTML alleine geht das was Du willst schonmal nicht. HTML stellt einzig das Dateiupload-Feld zur Verfügung.


```
<input type="file" name="datei">
```

Damit kann man jedoch in den meisten Browsern nur eine einzige Datei hochladen. Erst HTML5 unterstützt auch die Auswahl mehrerer Dateien, was aber nur von wenigen Browsern unterstützt wird. Siehe:
http://dojotoolkit.org/documentation/tutorials/1.6/uploader/

Das Speichern wie auch ein Fortschrittsbalken musst Du mit einer Webprogrammiersprache realisieren. Weit verbreitet ist dafür PHP wo im Handbuch bereits die Grundlagen zum Speichern von Dateien beim Hochladen erklärt werden:
http://www.php.net/manual/de/features.file-upload.php


----------



## Parantatatam (2. März 2012)

Leider ist eine Fortschrittsbalken so ohne weiteres nicht mit PHP möglich, da es weder die Möglichkeit gibt zu ermitteln, wie PHP seine temporären Dateien nennt, noch per PHP abzufragen, wie weit eine Datei bereits hochgeladen wurde. Letzteres liegt daran, dass erst die Datei hochgeladen wird und dann PHP ausgeführt wird. Theoretisch könntest du aber per AJAX zeitgleich mit Beginn des Hochladens eine Anfrage an ein weiteres PHP-Skript schicken, dass dann einen Abgleich aller temporärer Dateien macht samt Zeitstempel. Daraus kann man dann den (vermutlichen) Namen der temporären Datei ermitteln und somit schauen, wie groß die Datei ist. Leider kann man daraus keinen Prozentsatz ermitteln, da man zu der Zeit noch nicht weiß, wie groß die Datei insgesamt ist.

Ansonsten gibt es auch schon vor HTML5 die Möglichkeit mehrere Dateien gleichzeitig hochzuladen, in dem man per Javascript weitere Auswahlflächen ermittelt. Die Dateien kann man dann auch per AJAX (nein, es sieht nur so aus, aber eigentlich wird es in Frames hochgeladen) hochladen, ohne das ein Neuladen der gesamten Seite nötig ist.


----------



## KarlPichler (2. März 2012)

Hallo, erstmal danke für die Antworten! 

ist mir alles bekannt was ihr hier geschrieben habt. Einzelne Datein mit PHP hochzuladen ist ja kein problem. und mit html5 ist auch das file auswählen nicht das problem. 

ich erklär meine frage nochmals: mit was programmiert man den sowas? brauch ich JSP oder gibt es in C# irgendwas, ich habe eben keine Ahnung wie ich anfangen soll und vor allem mit was. ich habe mit java, c# erfahrung, allerdings weis ich nicht wie ich ein web-plugin programmiere.

gibt es vl. irgendetwas vorgefertigtes im web? 
oder habt ihr ein beispiel?  oder einen link? 


Lg


----------



## threadi (2. März 2012)

Es kommt weniger auf die Programmiersprache selbst an. Wenn der Fortschrittsbalken den tatsächlichen Stand des Hochladens repräsentieren soll, dann muss der Webserver selbst es ermöglichen die bereits bei einem Upload übertragene Datenmenge zu ermitteln. Die Daten werden ja über HTTP übertragen und sind erst komplett dem Server bekannt, wenn alles hochgeladen ist - grob gesagt.

Such mal nach "apache upload progress", da gibt es einiges dazu, auch Apache-Module glaube ich die das unterstützen. Die dabei ermittelten Werte musst Du "nur" noch mit einer Programmiersprache deiner Wahl auslesen (PHP reicht da aus, ich habe auch schon Perl dabei gesehen) und so die Ausgabe in der Webseite steuern.


----------



## KarlPichler (2. März 2012)

okay danke, bezieht sich aber alles auf die progress bar.

die prgress bar ist im moment zweitrangig! 

wichtig ist mir wie ich die Daten auf den server bekomm, ohne timeout, sowie es in PHP mit der POST methode der fall ist. 
PHP mit FTP upload oder so, aber keinen Dunst wie. 

auserdem weis ich nicht wie das input feld so programmiere das der user mehrere Dateien gleichzeitg auswählen kann, auser natürlich in HTML 5, welches ja wie schon erwähnt nicht in jedem browser funktioniert. 

ich hoffe ich habe meine frage richtig formuliert. 

beim googlen bin ich auf folgendes gestoßen: http://www.pixlie.de/willkommen
habs aber noch nicht ausprobiert! 

Lg


----------



## ComFreek (2. März 2012)

einfach nur crack hat gesagt.:


> Leider ist eine Fortschrittsbalken so ohne weiteres nicht mit PHP möglich, da es weder die Möglichkeit gibt zu ermitteln, wie PHP seine temporären Dateien nennt, noch per PHP abzufragen, wie weit eine Datei bereits hochgeladen wurde.



Es gibt anscheinend doch eine Möglichkeit mit HTML 5 und der File API. Zumindest habe ich das aus der letzten Spezifikation entnommen: http://www.w3.org/TR/FileAPI/#dfn-loadend-event.




> auserdem weis ich nicht wie das input feld so programmiere das der user mehrere Dateien gleichzeitg auswählen kann, auser natürlich in HTML 5, welches ja wie schon erwähnt nicht in jedem browser funktioniert.


Mit JavaScript: http://jsfiddle.net/WMqrN/ oder habe ich dich falsch verstanden?


----------



## KarlPichler (2. März 2012)

Hallo, danke für die antwort!
Am ja aber bei deinem JS Bsp, kann ich wieder nur eine datei auswählen! 
Ich hätte aber gerne die Function wie im Windows Explorer, das ich mehrere Elemente markieren kann und dann mit dem Klck "Hinzufügen" alle ausgewählten Dateien auf den FTP Server ladet! 

Sowie wenn ich bei Picasa eine neue Gallerie hinzufüge. Da muss ich auch nicht jedes Bild einzeln auswählen und hinzufügen, sondern ich markiere die Fotos die ich möcht und lade sie mit einem Schlag rauf. 

Sollte das Input feld "problem" gelöst sein, frage ich mich noch immer wie ich diese Datein dann hochlade! Ich weis nicht einmal nach was ich googeln soll! ^^


Lg


----------



## KarlPichler (2. März 2012)

ja gleich noch  ne Frage: Was ist jetzt eig. mit HTML5, wie weit funktioniert das alles schon? 
Wer kanns und wer nicht?


----------



## Parantatatam (2. März 2012)

HTML5 soll 2014 fertig sein, wurde aber vor kurzer Zeit als _Last Call_ gekennzeichnet, was bedeutet, dass HTML5 eigentlich de facto schon vollständig ist bis auf wenige Details. Du solltest es also ohne Sorgen nutzen können und allen Nutzern mit zu altem Browser ein Fenster vor die Birne werfen, dass sie sich gefälligst mal einen zeitgemäßen Browser installieren sollen. Wenn man immer nur auf die achtet, die man vielleicht noch auf irgendwelchen Umwegen unterstützen könnte, bewegt man die Menschen doch nie dazu etwas bei sich zu ändern.


----------



## KarlPichler (30. März 2012)

Hallo "einfach nur crack". ich möchte diesen Thread wieder aufleben lassen 

Und zwar ich hab jetzt den Dateiupload mit dem jquery script "uploadfiy" realisiert. 
Funktioniert auch wirklich einfach und super, allerdings check ich einige sachen noch nicht. 

Also erstens: ich möchte gerne immer den gesamten Bilderordner ausgeben lassen, so dass der user auch immer seine Bilder sehen kann.
Dafür möchte ich auf eine extere php Datei verweisen, die mir diese Bilder ausgibt. 
Diesen "Link" sollte ich ja in der "InitDone" und in der "AllComplete" Mehtode aufrufen, oder? 
Allerdings hab ich keine Ahnung wie den das funktioniert! Also die Verlinkung. 

Hier ist mal der Code für das Uploadfiy

```
<CODE><script type="text/javascript">
// <![CDATA[
$(document).ready(function() {
  $('#file_upload').uploadify({
	'uploader'  : '/uploadify/uploadify.swf',
	'script'    : '/uploadify/uploadify.php',
	'cancelImg' : '/uploadify/cancel.png',
	'folder'    : '/uploads',
	'multi'		: true,
	'auto'      : true,
        'onComplete'  : function(event, ID, fileObj, response, data) {
          //Verlinkung auf die PHP Datei welche mir den gesamten inhalt des upload folders ausgibt
        }
  });
});
// ]]>
</script>
 </CODE>
```

Uploadfiy:
http://www.uploadify.com/documentation/events/oncomplete-2/

Hast du eine Idee, bzw. hast du schon mal sowas gmacht, bzw. gibt es eine gute alternative? 

Für eine Antwort wäre ich sehr dankbar!


----------



## Parantatatam (30. März 2012)

Du brauchst einfach ein PHP-Skript, das dir alle Bilder aus einem Verzeichnis als JSON-Objekt zurück gibt und dann folgenden Javascript-Teil in deinem "oncomplete"-Ereignis:

```
$.post('get-all-files.php', { user_id: user_id }, function (data) {
  // in data sind jetzt alle Bilder des Nutzers gespeichert als Array
});
```
Wenn ich dir bei deinem PHP-Skript helfen soll, müsste ich aber genauer wissen, wie du deine Bilder benennst, wie deine Verzeichnisstruktur aussieht und wo deine Bilder dann liegen.


----------



## KarlPichler (30. März 2012)

Okay danke erstmals für die antwort!
Ja soweit hab ich das noch gewusst, allerdings micht mir die umsetztung zu schaffen! 

Kannst du nen Example- Code posten? wäre super!, den durch googlen find ich auch nicht das richtige bzw. kenn mich damit nicht aus! 

Lg


----------



## Parantatatam (30. März 2012)

Ich gehe mal davon aus, dass alle deine Nutzer ein eigenes Verzeichnis haben, in dem die Bilder gespeichert werden:

```
$directory = 'images/' . (int) $_POST['user_id'] . '/*.jpg';
$images    = glob($directory);
echo json_encode($images);
```


----------



## KarlPichler (30. März 2012)

naja ich habe ein PHP script welches mir alle Bilder aus einem Verzeichnis auslest, und das funktioniert, allerdings weis ich eben nicht wie ich das mit dem uploadfiy aufrufen muss. danke

dieses sieht folgendermaßen aus: 


```
<html>
<head><link rel="stylesheet" type="text/css" href="style.css"/>
</head>
<body>
<ul id="galerie">
<?php
$ordner = "upload";
 
$allebilder = scandir($ordner); // Sortierung A-Z
 
foreach ($allebilder as $bild) {
    $bildinfo = pathinfo($ordner."/".$bild);
    $size = ceil(filesize($ordner."/".$bild)/1024);
 
    if ($bild != "." && $bild != ".."  && $bild != "_notes" && $bildinfo['basename'] != "Thumbs.db") {
    ?>
    <li>
        <a href="<?php echo $bildinfo['dirname']."/".$bildinfo['basename'];?>">
        <img src="<?php echo $bildinfo['dirname']."/".$bildinfo['basename'];?>" width="140" alt="Vorschau" /></a>
        <span><?php echo $bildinfo['filename']; ?> (<?php echo $size ; ?>kb)</span>
    </li>
<?php
    };
 };
?>
</ul>
</body>
</html>
```

danke


----------



## Parantatatam (30. März 2012)

Du willst also auf eine andere Seite verweisen und nicht die Bilder auf der aktuellen Seite nachladen?

Nachtrag: Ich habe dein Skript mal etwas ausgebessert, da man generell erst einmal alle Daten verarbeiten sollte bevor man sie ausgibt und nicht während der Erstellung der Ausgabe erst die Daten ermitteln sollte.

```
<?php
  $directory = 'upload';
  $images    = glob($directory . '/*.*');
  $images    = array_filter($images, function ($image) {
    return (strrchr($image, '/') !== 'Thumbs.db');
  });
  array_walk($images, function (&$image) {
    $image = array(
      $image,
      ceil(filesize($image) / 1024)
    );
  });
?>
<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
  <ul id="galerie">
  <?php foreach($images as $image): ?>
    <li>
      <a href="<?php echo $image[0]; ?>">
        <img src="<?php echo $image[0]; ?>" width="140" alt="Vorschau" />
      </a>
      <span><?php echo $image[0];?> (<?php echo $image[1]; ?>)</span>
    </li>
  <?php endforeach; ?>
  </ul>
</body>
</html>
```


----------



## KarlPichler (30. März 2012)

okay danke. 

nein ich will alles auf einer seite haben. 

Ich möchte auf der seite alle bilder sehen die sich momentan im Ordner befinden 
--> InitDone --> alle Bilder ausgeben.

Auf der selben seite befindet sich auch das Upload script --> Upload Images

Ist dies nun durchgeführt sollte sich das <div> wo dall Bilder angezeigt werden, aktualisieren und auch alle neuen Bilder mitanzeigen.
--> OnComplete --> alle Bilder erneut ausgeben. 

Bilder Ausgeben

Bild1Bild2Bild3Bild4Bild5Bild6Bild7Bild8Bild9Bild10Bild11Bild12Bild13Bild14Bild15


Upload Button 


upload bild 1upload bild 2upload bild 3upload bild 4upload bild 5

ich hoffe du kennst dich aus  

ein gesamter code wäre perfekt, vl. auch mit einer delete Methode, wenn du zufällig eine auf Lager hast!

LG


----------



## Parantatatam (30. März 2012)

Ich habe es nicht komplett ausprobiert, aber es sollte so funktionieren:

```
<!DOCTYPE html>
<html>
<head>
  <title>Bildergallerie</title>
  <script type="application/javascript" src="jquery.js"></script>
  <script type="application/javascript">
    $(document).ready(function () {
      var userid = 1;
      
      $('#upload-submit-button').click(function () {
        // disable all input fields and buttons
        $('#upload-images > li > *').add(this).attr('disabled', 'disabled');
        // upload all files
        $('#upload-images input').uploadify({
          'uploader'    : '/uploadify/uploadify.swf',
          'script'      : '/uploadify/uploadify.php',
          'cancelImg'   : '/uploadify/cancel.png',
          'folder'      : '/uploads',
          'multi'       : true,
          'onComplete'  : function(event, ID, fileObj, response, data) {
            $.post('uploaded-files.php', { userid: userid }, function (data) {
              var gallery = $('#image-gallery');
              gallery.html('');
              for(var i in data)
              {
                gallery.append('<li><img src="' + data[i].src + '" width="150" alt="picture" /></li>');
              }
            }, 'json');
          }
        });
      });
      $('#upload-images button').live('click', function () {
        // remove this input field
        $(this).prev('input').andSelf().remove();
        // if there is only one input field left then disable the submit button
        if($('#upload-images input').length === 1)
        {
          $('#upload-submit-button').attr('disabled', 'disabled');
        }
      });
      $('#upload-images input').live('change', function () {
        $('#upload-submit-button').add($(this).next('button')).removeAttr('disabled');
        $(this).parent().append(
          '<li>' + "\n" +
            '<input type="file" name="file[]" accept="image/*" />' + "\n" +
            '<button type="button" disabled="disabled">entfernen</button>' + "\n" +
          '</li>'
        );
      });
    });
  </script>
  <style type="text/css">
    #image-gallery, #upload-images {
      list-style-type:none;
      padding:0;
      margin:0;
    }
    #image-gallery li {
      float:left;
    }
  </style>
</head>
<body>
  <ul id="image-gallery"></ul>
  <form method="post" id="form-upload-images">
    <button id="upload-submit-button" type="button" disabled="disabled">Hochladen</button>
    <ul id="upload-images">
      <li>
        <input type="file" name="file[]" accept="image/*" />
        <button type="button" disabled="disabled">entfernen</button>
      </li>
    </ul>
  </form>
</body>
</html>
```


----------



## KarlPichler (30. März 2012)

Hallo.

Erstmal danke für den Mega- Support, allerdings funktioniert da rein gar nichts!
Entweder bin ich zu dumm uns es einzusetzten oder es hat was im Quellcode. 
ich habe in der Zwischenzeit etwas herumgetüfftelt, und mittlerweile kann alle bilder ausgeben, allerdings komme ich damit gleich auf meine nächste frage.


Ich wiederhole nochmals die Ausgangslage:
Ich habe einen Ordnern in welchen Bilder gespeichert sind. 
Wenn ich nun auf die Seite "Neue Bilder hinzufügen" gehe, sollten alle Bilder die sich zu diesem Zeitpunkt im Ordner befinden ausgegebn werden. 
Unter den Bildern befindet sich ein Button, welcher einen FileDialog öffnet.
Ich wähle meine Files aus und drücke "Upload. --> Bilder werden hochgeladen.
Nach dem erfolgreichen Upload sollte sich die Anzeige der Bilder aktualiesren, quasi die neu hinzugefügten Bilder auch anzeigen. 

Als Zuckerl wäre es schön wenn jedes Bild einen "delete" Button hätte, mit dem ich das Bild löschen kann.

-------ENDE AUSGANGSLAGE---------------

Ist Stand:
Ich habe den Upload mit "uploadfiy" realisiert, funktioniert auch super! 
Ich gebe auch alle Bilder mitlerweile aus, nur das Problem ist, das ich dafür auf eine zweite seite verlinke, und ich eig. die Bilder gerne auf der selben seite ausgeben würde.

Mit dem Delete Button habe ich mich nicht beschäftigt! 

Hier ist mal mein code:


```
//upload script

$(document).ready(function() {
  $('#file_upload').uploadify({
	'uploader'  : 'uploadify/uploadify.swf',
	'script'    : 'uploadify/uploadify.php',
	'cancelImg' : 'uploadify/cancel.png',
	'folder'    : '<?php echo $upload_pre_dir.$global_mysql_id_to_chg;?>',
	'multi'		: true,
    'onAllComplete'  : function(event, queueID, fileObj, reponse, data) {    
            location.href="php_admin_show.php?val=<?php echo $global_mysql_id_to_chg; ?>"; 
        }
  });
});


//php datei dazu, ich nehme momentan noch die alte, und nicht die du mir gesendet hast, aber werd deine sicher als nächsten schritt einbauen.
<?php
$id = $_REQUEST['val'];
?>

<html>
<head><link rel="stylesheet" type="text/css" href="style.css"/>
</head>
<body>
<ul id="galerie">
<?php
$ordner = "upload_offers/".$id;
echo $ordner;
 
$allebilder = scandir($ordner); // Sortierung A-Z
 
foreach ($allebilder as $bild) {
    $bildinfo = pathinfo($ordner."/".$bild);
    $size = ceil(filesize($ordner."/".$bild)/1024);
 
    if ($bild != "." && $bild != ".."  && $bild != "_notes" && $bildinfo['basename'] != "Thumbs.db") {
    ?>
    <li>
        <a href="<?php echo $bildinfo['dirname']."/".$bildinfo['basename'];?>">
        <img src="<?php echo $bildinfo['dirname']."/".$bildinfo['basename'];?>" width="140" alt="Vorschau" /></a>
        <span><?php echo $bildinfo['filename']; ?> (<?php echo $size ; ?>kb)</span>
    </li>
<?php
    };
 };
?>
</ul>
</body>
</html>
```

Danke bis jetzt und auch für künftige antworten!

Lg


----------

