Multiple file upload met jQuery en PHP

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • DeepFreeze.NL
  • Registratie: April 2006
  • Laatst online: 02-03 08:01
Ik ben bezig om een applicatie te ontwikkelen waarmee ik meerdere bestanden tegelijk kan uploaden. Voordat een bestand geüpload wordt, moet er eerst een check gedaan worden om te kijken of het bestand als bestaat. Zo ja, dan moet er de vraag gesteld worden of het bestaande bestand mag worden overschreven.

Ik maak gebruik van jQuery (1.7.1) en de jQuery Form Plugin voor het verzenden van de bestanden.
Controle en verwerking gebeurt in PHP.

Ik heb het volgende in HTML
HTML:
1
2
3
4
5
<form id="uploadForm" method="post" action="upload.php" enctype="multipart/form-data">
<input id="uploads" name='uploads[]' type="file" multiple>
<input id="submit" type="submit" value="Send">
</form>
<div id="uploadOutput"/></div>

Het volgende in JS
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
$(document).ready(function(){
    
    $('#submit').click(function(){
        
        // Loader weergeven
        $('#uploadOutput').html('<img src="images/loading.gif" width="16" height="16" alt="Bezig met laden" class="loading" />');
        
        // Loop door alle upload files.
        var uploads = document.getElementById('uploads');
        for (var i=0; i < uploads.files.length; i++) {
            
            var filename = uploads.files[i].name;
            
            // Check of bestand al bestaat.
            $('#uploadForm').ajaxSubmit({
                url: 'upload.php?action=check', 
                success: function(data) {
                    if (data == 1) {
                        
                        var overwrite = confirm('Let op: ' + filename + ' bestaat al.\nWilt u het bestaande bestand vervangen?');
                        if (!overwrite) {
                            $('#uploadOutput').html('');
                            return false;
                        } else {
                            // Verwerk upload.
                            $('#uploadForm').ajaxSubmit({
                                target: '#uploadOutput'
                            });
                        }
                    } else {
                        // Bestand bestaat nog niet. Verwerk upload.
                        $('#uploadForm').ajaxSubmit({
                            target: '#uploadOutput'
                        });
                    }
                }
            });
        }
        // Voorkom standaard page submit.
        return false;
    });
    
});

En in PHP
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
if (!empty($_FILES)) {

    //echo "<pre>",print_r($uploads),"</pre>";
    //echo "<pre>",print_r($_FILES),"</pre>";
    
    // Number of uploaded files
    $num_files = count($_FILES['uploads']['tmp_name']);
    
    for($i=0; $i < $num_files; $i++) {
        
        $tempFile = $_FILES['uploads']['tmp_name'][$i];
        $targetPath = str_replace('//','/',$_SERVER['DOCUMENT_ROOT'].'/upload2/upload/');
        $targetFile = $targetPath.$_FILES['uploads']['name'][$i];
        
        // Validate the file type
        $fileTypes = array('pdf','doc','docx','txt'); // File extensions
        $fileParts = pathinfo($_FILES['uploads']['name'][$i]);
        
        //echo "<pre>",print_r($fileParts),"</pre>";
        
        // Check of bestand al bestaat.
        if ($_GET['action'] == "check") {       
            if (file_exists($targetFile)) {
                echo 1;
            } else {
                echo 0;
            }
        } else {
            if (in_array(strtolower($fileParts['extension']),$fileTypes)) {
                if (move_uploaded_file($tempFile,$targetFile)) {
                    echo "Bestand <strong>\"".$fileParts['basename']."\"</strong> is met <strong>succes</strong> toegevoegd.<br />";
                }
            } else {
                die('<br>Invalid file type (extension)');
            }
        }
    }
}


Maar nu zit ik met het probleem dat alle geselecteerde bestanden in PHP verwerkt worden. Stel dat bij een bestaand bestand ik de melding krijg of ik deze wil overschrijven en ik druk op Nee, dan worden alsnog alle bestanden verwerkt in PHP die in uploads[] aanwezig zijn.

Hoe krijg ik het voor elkaar dat alleen bestanden geüpload worden die nog niet bestaan of die overschreven mogen worden?

Mij lijkt het beste om de for loop in PHP weer weg te halen en in JS aan te geven welke bestanden verwerkt mogen worden. Hoe krijg ik dit voor elkaar? Of zijn er andere betere oplossingen? Graag hulp :). Bedankt!

Acties:
  • 0 Henk 'm!

  • Koetjeboe
  • Registratie: Maart 2002
  • Laatst online: 14-09 21:36

Koetjeboe

Boe, zegt de koe

Hoe krijg ik het voor elkaar dat alleen bestanden geüpload worden die nog niet bestaan of die overschreven mogen worden?
Met een javascript oplossing niet voor zover ik weet. Je mag de content van het file element niet aanpassen namelijk uit security overwegingen.

Kwa processing kun je misschien een 2e array meesturen waarin staat welke verwerkt moeten worden, ze worden dan nog wel overgestuurd though.

[ Voor 20% gewijzigd door Koetjeboe op 30-01-2012 15:23 ]


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 13-09 09:39

Janoz

Moderator Devschuur®

!litemod

Even een paar stapjes terug. Er zijn 2 dingen die je denk ik even goed in moet prenten:

1. Het verschil tussen clientside en serverside
2. De nogal strenge (en zeker terechte!) veiligheidsmaatregelen omtrent het fileupload element

Sowieso vraag ik me af of je helemaal helder hebt wat er nu precies gebeurt. Als ik namelijk naar je code kijk, krijg ik het idee dat je alle bestanden al keurig aan het uploaden bent op het moment dat je je check doet. Je submit immers het upload formulier.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • DeepFreeze.NL
  • Registratie: April 2006
  • Laatst online: 02-03 08:01
Janoz schreef op maandag 30 januari 2012 @ 15:25:
Even een paar stapjes terug. Er zijn 2 dingen die je denk ik even goed in moet prenten:

1. Het verschil tussen clientside en serverside
2. De nogal strenge (en zeker terechte!) veiligheidsmaatregelen omtrent het fileupload element

Sowieso vraag ik me af of je helemaal helder hebt wat er nu precies gebeurt. Als ik namelijk naar je code kijk, krijg ik het idee dat je alle bestanden al keurig aan het uploaden bent op het moment dat je je check doet. Je submit immers het upload formulier.
Het verschil weet ik heel goed.
Het formulier wordt 2x verzonden. Eerste keer voor de check, dan wordt er gekeken of het bestand al bestaat ja of nee. De 2e keer worden de bestanden daadwerkelijk verplaatst van de tmp_folder naar de juiste map.

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 13-09 09:39

Janoz

Moderator Devschuur®

!litemod

Effectief ben je dus alle bestanden 2x aan het uploaden... Lekker efficiënt ;)

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • DeepFreeze.NL
  • Registratie: April 2006
  • Laatst online: 02-03 08:01
Janoz schreef op maandag 30 januari 2012 @ 15:44:
Effectief ben je dus alle bestanden 2x aan het uploaden... Lekker efficiënt ;)
Daarom ben ik ook opzoek naar een manier hoe het beter kan :). Alle hulp is welkom!

Acties:
  • 0 Henk 'm!

  • OkkE
  • Registratie: Oktober 2000
  • Laatst online: 04-09 08:16

OkkE

CSS influencer :+

Je zou eens kunnen kijken naar de File API.

Maar wat bedoel je met "het bestand al bestaat"? Om wat voor soort bestanden gaat het (images? tekst?) en hoe groot zullen die gemiddeld zijn? Wil je alleen dubbele bestandsnamen tegengaan? Of wil je ook de inhoud checken? Uploaden en daarna checken op filename en bijv. checksum is natuurlijk het beste om duplicates tegen te gaan...

-- edit --

Wanneer het om bestanden van gemiddeld <1mb gaat, is het natuurlijk ook geen probleem dat een gebruiker het bestand sowieso moet uploaden. Gaat het om >100mb, dan is het check op filename voor het uploaden start wel gebruiksvriendelijk. :)
DeepFreeze.NL schreef op maandag 30 januari 2012 @ 16:21:
Het gaat om pdf documenten. Ik wil eigenlijk alleen een eenvoudige check inbouwen dat wanneer een bestand al bestaat de gebruiker eerst nog een melding krijgt waarin hij moet bevestigen dat het bestand overschreven mag worden.
Misschien heb je hier iets aan: http://robertnyman.com/20...gress-for-multiple-files/

[ Voor 52% gewijzigd door OkkE op 30-01-2012 16:23 ]

“The best way to get the right answer on the Internet is not to ask a question, it's to post the wrong answer.”
QA Engineer walks into a bar. Orders a beer. Orders 0 beers. Orders 999999999 beers. Orders a lizard. Orders -1 beers.


Acties:
  • 0 Henk 'm!

  • DeepFreeze.NL
  • Registratie: April 2006
  • Laatst online: 02-03 08:01
OkkE schreef op maandag 30 januari 2012 @ 16:16:
Je zou eens kunnen kijken naar de File API.

Maar wat bedoel je met "het bestand al bestaat"? Om wat voor soort bestanden gaat het (images? tekst?) en hoe groot zullen die gemiddeld zijn? Wil je alleen dubbele bestandsnamen tegengaan? Of wil je ook de inhoud checken? Uploaden en daarna checken op filename en bijv. checksum is natuurlijk het beste om duplicates tegen te gaan...
Het gaat om pdf documenten. Ik wil eigenlijk alleen een eenvoudige check inbouwen dat wanneer een bestand al bestaat de gebruiker eerst nog een melding krijgt waarin hij moet bevestigen dat het bestand overschreven mag worden.

Acties:
  • 0 Henk 'm!

  • Beatboxx
  • Registratie: April 2010
  • Laatst online: 26-10-2022

Beatboxx

Certified n00b

Je kan een database bijhouden met uploaddatum, grootte, naam etc, werkt denk ik sneller dan als je steeds alle files moet langssporen...

edit:
EDIT: woordje vergeten dat betekenis omdraaide:P

[ Voor 20% gewijzigd door Beatboxx op 30-01-2012 16:25 ]


Acties:
  • 0 Henk 'm!

  • MueR
  • Registratie: Januari 2004
  • Laatst online: 00:31

MueR

Admin Tweakers Discord

is niet lief

Beatboxx schreef op maandag 30 januari 2012 @ 16:24:
werkt denk ik sneller dan als je steeds alle files moet langssporen...
Want een simpele check op de filename is magistraal veel langzamer dan een check in je database? Helemaal als je daarna toch naar je disk moet?

Je zou kunnen overwegen om ze de eerste keer te moven naar je directory. Bestaat het bestand al, geef het dan een prefix of dump het in een aparte map. Je 2e scherm kan dan gewoon de boel bevestigen. Ja: overschrijven, Nee: delete geuploade file uit temp map. Vervolgens nog even een cron die alle files ouder dan 1 dag uit die map mikt, voor het geval mensen dat formulier niet versturen.

[ Voor 4% gewijzigd door MueR op 30-01-2012 16:30 ]

Anyone who gets in between me and my morning coffee should be insecure.

Pagina: 1