PHP – Funzione upload con qualche opzioncina

Dato che, nonostante la mia gratificante qualifica di impiegato amministrativo, in ufficio faccio di tutto, e dato che molto di questo tutto lo faccio aggatis, perchè non renderlo disponibile a tutti?

L’azienda per cui lavoro guadagnerà soldi anche con questo. Mentre io, alle lamentele sul fatto che certe cose devo farle a casa nel tempo libero, o presunto tale, mi devo sentir rispondere: "quello che fai oltre l’orario di lavoro non è competenza nostra, e comunque, fuori o dentro l’orario di lavoro quello che deve essere fatto va fatto".
Tradotto vuol dire "devi lavorare a casa se non ce la fai in ufficio, e non rompere le palle!".

Ma lasciamo perdere lo sfogo e andiamo al dunque. Di seguito una facile funzione per l’upload dei file via form http.

Prerequisiti:
Prima di usare la funzione dovete controllare che nel PHP installato sul vostro server sia abilitata la funzione di upload dei file: nel php.ini il parametro file_uploads deve essere impostato ad 1.

Tenete d’occhio anche il parametro upload_max_filesize che in default è impostato a 2M.

Le opzioni abilitate.
La funzione codificata permette di settare determinati parametri che la rendono quanto più funzionale possibile. I parametri a scelta dell’utente sono:

  • $dir = scelta della directory di destinazione.
  • $tipo = selta del tipo o dei tipi di file da poter inviare al server.
  • $dim = dimensione massima del file da inviare al server. Sempre nei limiti delle impostazioni server.
  • $debug = opzioni di debug.

La funzione controlla anche che non esista già un altro file con lo stesso nome nella directory di destinazione, ed avvisa l’utente se la directory impostata per ricevere i file non ha i corretti permessi di scrittura.

Il Codice.
Di seguito il codice della funzione.

  function upload($dir = FALSE, $tipo = FALSE, $dim = FALSE, $debug = FALSE){
 
   //Impostare la path assoluta del proprio sito
   $source_dir = "/var/www/test/";
  
   if(!is_uploaded_file($_FILES[‘file’][‘tmp_name’])){
       echo "Nessun file selezionato da inviare al server";
       exit();
   }
  
   if(is_uploaded_file($_FILES[‘file’][‘tmp_name’])){
  
     //Funzione di debug
     if($debug != FALSE){
        print_r($_FILES);
     }   
  
     //Controllo che il file non esista
     if (is_file($source_dir.$dir.$_FILES[‘file’][‘name’])){
       echo "Esiste gi&agrave; un file con lo stesso nome!<br />
                Rinominarlo e tentare nuovamente!";
       exit();
     }
    
     //Controllo il tipo di file se ne ho definito uno o più obbligatori
     if($tipo != FALSE){ 
       if(is_array($tipo)){
         if(!in_array($_FILES[‘file’][‘type’],$tipo)){
            echo "Tipo file non consentito";
            exit();
         }
       }else{
         if($_FILES[‘file’][‘type’] != $tipo){
            echo "Tipo file non consentito";
            exit();
         }
       }
     }
  
    //Controllo che le dimensioni non eccedino il massimo consentito
    if($dim != FALSE){
      $dimz = $dim * 1024000;   
      if($_FILES[‘file’][‘size’] > $dimz){
        echo "Il file che si sta cercando di inviare &egrave; troppo grande!<br />
              la dimensione massime consentita &egrave; di " . $dim . " megabyte";
        exit();      
      }
    }
  
    //Controllo che la directory di destinazione sia server writable
    if(!is_writable($source_dir.$dir)){
       echo "Non si dispone dei permessi necessari!<br />
                Contattare l’amministratore del sistema e far settare i permessi della directory "<i>" . $dir . "</i>" a 0777";
       exit();      
    }
  
    //Passati tutti i controlli posso inviare il file al server!
    if(move_uploaded_file($_FILES[‘file’][‘tmp_name’], $source_dir.$dir.$_FILES[‘file’][‘name’])){
       echo "Il file &egrave; stato inviato correttamente al server!";
    }
   }
  }

In $source_dir immetto la path assoluta di upload. E’ verosimilmente il percorso assoluto in cui risiedono tutti i file del sito.
Se non setto l’opzione $dir, lo script tenterà di uploadare i file nella $source_dir.

Per la gestione dei tipi di file, si noti che la funzione usa l’elemento type dell’array globase $_FILES per capire che tipo di file si sta inviando. E’ possibile settare un solo tipo consentito, ed in questo caso si userà una forma del tipo:

upload(”,’image/jpeg’);

Oppure più tipi di file. In questo modo magari possiamo abilitare l’invio di più formati immagine. Volendo abilitare l’invio dei file png, jpg e gif, useremo l’opzione type come un array che racchiude gli elementi abilitati.

upload(”, array( ‘image/jpeg’,’image/gif’,’image/png’));

Le dimensioni massime vanno indicate in megabyte. E’ del tutto inutile settare una dimensione massima di 5MB se il parametro upload_max_filesize del php.ini sta in default a 2MB. Per cui regolatevi di conseguenza.

Le opzioni di debug, se abilitare, stampano a video un semplice print_r dell’array $_FILES.

Volete testare il tutto?
Create un file di testo. Rinominatelo in upload.php, o altro nome, basta che il file abbia estenzione *.php. Copiate tutto il codice relativo alla funzione, ed aggiungete quanto segue immediatamente dopo.

<?php
if(isset($_POST[‘go’])){
   upload(‘upload/’,array(‘image/jpeg’,’image/gif’,’image/png’),1, $debug = TRUE);
}else{
?>
<form name="upload" method="post" action="<?=$_SERVER[‘PHP_SELF’]?>" enctype="multipart/form-data" >
<input type="file" name="file" />
<input type="submit" name="go" value="Invia al Server" />
</form>
<?php
}
?>

Ricordatevi di modificare il parametro $soruce_dir.
La funzione, per come evocata nell’esempio, invierà i file nella sottodirectory upload/ del vostro dominio (lo slash finale è molto importante). Abiliterete l’invio dei formati immagine png, jpg e gif, non permetterete l’invio di file superiori ad un megabyte e visualizzerete le informazioni di debug.

Se volete, c’è anche la funzione con relativo esempio in formato testo.

Buona serata : - ) .

34 thoughts on “PHP – Funzione upload con qualche opzioncina”

  1. e ci credo che ti fanno fesso a lavoro…

    scrivi codice come una scimmia… e la chiami funz utile? uno sveglio si prendeva la funz da php.net e con 2 min stava apposto…

    πŸ™‚

  2. Ciao turing, sono la scimmia fessa πŸ™‚

    Invece di perdere tempo a scrivere commenti inutili, perchè non vai a fare i tuoi copia / incolla?
    E' inutile spiegarti cosa vuol dire scrivere codice didattico, tanto te della tastiera userai solo CTRL + C e CTRL + V

    πŸ™‚

  3. Ciao davide,
    son Ciuccio un neofita di php…
    posso chiederti quale sia il codice
    per fare uploadare file .avi.mpeg.vob..
    video insomma?
    garzie

  4. ok rapidissimo grazie!

    Ho provato a testare lo scropt che avevi dato in questo post ma mi dà un errore in prossimità di 'upload/'. 'upload'è una cartella che devo c reare dove verranno immessi i file che mi uploadano?

  5. Prima di tutto devi modificare il parametro:
    $source_dir = "/var/www/test/";

    Con il percorso assoluto del web di riferimento.

    Dopo di che, devi creare una directory, può essere upload, movie, quello che voui. Basta usare una variabile adeguata nello script.

    La directory la devi creare tu, lo script non è fatto per crearla nel caso in cui non la trovi.
    E mi raccomando i permessi di scrittura, altrimenti non va.

  6. la path la ho modificata

    ma mi dà quest errore:

    Parse error: syntax error, unexpected T_STRING in /web/htdocs/www.ciuccioandciu.it/home/upphoto.php on line 80

  7. Ciuccio, attento a ; e i "

    $source_dir = "/web/htdocs/www.ciuccioandciu.it/home/";

    Solitamente quando si ha un errore di questo genere è meglio vedere le righe immediatamente sopra.

  8. @davids
    scusami:

    <?php
    function upload($dir = FALSE, $tipo = FALSE, $dim = FALSE, $debug = FALSE){

    //Impostare la path assoluta del proprio sito
    $source_dir = "/web/htdocs/www.ciuccioandciu.it/home/";

    if(!is_uploaded_file($_FILES['file']['tmp_name'])){
    echo "Nessun file selezionato da inviare al server";
    exit();
    }

    if(is_uploaded_file($_FILES['file']['tmp_name'])){

    //Funzione di debug
    if($debug != FALSE){
    print_r($_FILES);
    }

    //Controllo che il file non esista
    if (is_file($source_dir.$dir.$_FILES['file']['name'])){
    echo "Esiste gi&agrave; un file con lo stesso nome!<br />
    Rinominarlo e tentare nuovamente!";
    exit();
    }

    //Controllo il tipo di file se ne ho definito uno o più obbligatori
    if($tipo != FALSE){
    if(is_array($tipo)){
    if(!in_array($_FILES['file']['type'],$tipo)){
    echo "Tipo file non consentito";
    exit();
    }
    }else{
    if($_FILES['file']['type'] != $tipo){
    echo "Tipo file non consentito";
    exit();
    }
    }
    }

    //Controllo che le dimensioni non eccedino il massimo consentito
    if($dim != FALSE){
    $dimz = $dim * 1024000;
    if($_FILES['file']['size'] > $dimz){
    echo "Il file che si sta cercando di inviare &egrave; troppo grande!<br />
    la dimensione massime consentita &egrave; di " . $dim . " megabyte";
    exit();
    }
    }

    //Controllo che la directory di destinazione sia server writable
    if(!is_writable($source_dir.$dir)){
    echo "Non si dispone dei permessi necessari!<br />
    Contattare l'amministratore del sistema e far settare i permessi della directory "<i>" . $dir . "</i>" a 0777";
    exit();
    }

    //Passati tutti i controlli posso inviare il file al server!
    if(move_uploaded_file($_FILES['file']['tmp_name'], $source_dir.$dir.$_FILES['file']['name'])){
    echo "Il file &egrave; stato inviato correttamente al server!";
    }
    }
    }
    //FINE FUNZIONE UPLOAD

    /*** Questa parte del codice serve solo per testare il tutto.
    Fai un intero copia incolla del codice e potrai testare direttamente la funzione.
    Ricorda che puoi eliminare tranquillamente le righe sottostanti in qualsiasi momento.
    Nell'esempio riportato sotto la funzione di upload prevede i settaggi arbitrari seguenti:

    – directory di destinazione = 'upload/'
    – tipo di file = immagini gif e jpeg
    – dimensione massima = 1 megabyte
    – debug = attivo

    Sono tutti parametri opzionali, ovvero non obbligatori
    ***/

    if(isset($_POST['go'])){
    upload('upload/','array('image/gif','image/jpeg')',1, $debug = TRUE);
    }else{
    ?>
    <form name="upload" method="post" action="<?=$_SERVER['PHP_SELF']?>" enctype="multipart/form-data" >
    <input type="file" name="file" />
    <input type="submit" name="go" value="Invia al Server" />
    </form>
    <?php
    }
    ?>

    forse così facciamo prima, Thanks Two (ciu)

  9. Riga 80:

    upload('upload/','array('image/gif','image/jpeg')',1, $debug = TRUE);
    Sbagliato, deve essere:

    upload('upload/',array('image/gif','image/jpeg'),1, $debug = TRUE);

    Hai messo gli apici nella dichiarazione di array.

  10. quando dici che almeno quelli che ti rompono le p…e almeno servono a qualcosa eh…?!?

    eheheehe… ed io insito, perchè sento che oggi è un giorno per me positivo ( almeno per me )

    e ti domando se posso nascondere questa scritta che compare prima di ogni informazione ( di corretto e non caricamento del file o di quando vi è un file, di quando vi si è caricato un file simile ecc…) : Array ( [file] => Array ( [name] => Asino.jpg [type] => image/jpeg [tmp_name] => /tmp/php6EzOle [error] => 0 [size] => 43540 ) )…????

  11. Ciao davids,
    ti volevo innanzi tutto ringraziare
    perchè grazie ai tuoi consigli sono riuscito ad inserire un carica foto all'interno della mia pagina foto: http://www.ciuccioandciu.it/photoita.php;
    sarai inserito nei blogroll (come minimo)

    su i video, invecie stò avendo dei problemucci (forse dovuti all'hosting in quanto ne ho uno acquistato assieme al dominio con aruba)

    Ti spiego subito il mio obiettivo: vorrei dalla mia pagina dei video (www.ciuccioandciu.it/videoita.php)far uploadare da miei artisti sul mio server i loro video per un
    : name="MAX_FILE_SIZE" value="1000000",
    …che dovrebbe essere 1gb, giusto?

    a tale scopo ho inserito la funzione stringa che mi avevi dato tu -upload('upload/',array('video/x-msvideo','video/mpeg','video/quicktime'));-
    ma senza successo.
    1)Può dipendere dal server? ( anche se ho provato con file video di piccole dimensioni)
    2)Può dipendere dal file php.ini che ho modificato estendedo il upload_max_filesize = 1gb NELLA CARTELLA PHP CHE HO IN C:// , ma ho un file php.ini anche nella cartella di easyphp, devo modificare anche quello?
    ..dopodicchè il file php.ini va caricato sul server??
    3) dimmi tu…

    ho chiesto anche l'ausilio a Mcc 1.0 ma lui mi ha detto che si appoggia al mitico davidonzo ed allora sai come è…

    Siamo all together in Ciuccieria!!!!

    A presto thks Two ( ciu)

  12. Ciao Ciuccio,

    Per i file di grandi dimensioni è sempre un problema il protocollo http (quello usato dalle funzioni di upload via web più comuni – come questa).

    Se non hai accesso di root al server, e quindi non puoi modificare le impostazioni del php.ini e di apache, la vedo estremamente dura.
    Per intenderci, per farlo dovresti avere un server dedicato.

    In alternativa, se le estenzioni ftp del php sono installate, puoi provare a fare un upload via ftp, che è sicuramente un protocollo migliore per le tue esigenze.

  13. So,
    ; Maximum allowed size for uploaded files.
    upload_max_filesize = 2M

    change in :

    ; Maximum allowed size for uploaded files.
    upload_max_filesize = 1gb o 1G ?

    e lo uploado nella mia root principale ?

    …Giosto?

  14. Devi aumentare adeguatamente tutti questi parametri:

    max_execution_time
    max_input_time
    memory_limit
    post_max_size
    upload_max_filesize

    E nel file httpd.conf (il file di configurazione di apache) anche li il memory limit

  15. e poi uploado il php.ini ?

    D. said:"… puoi provare a fare un upload via ftp, che è sicuramente un protocollo migliore per le tue esigenze."

    Così dò un protocollo migliore per le mie esigenze di ricevere filmati da 1gb?

    (Ti saluta Marco, che coincidenza e fortuna l'averti trovato…manco a farlo apposta Tac..)

  16. @ Ciuccio, se sta in hosting su aruba, sicuramente non puoi modificare il php.ini. Che servizio hai comprato? Hosting a 26 euro l'anno?

    Con ftp dovresti avere sicuramente meno sbattimanti, ma dipende sempre dal fatto che l'estenzione sia compilata sul PHP del server, controlla con un phpinfo();

    Ricambia i saluti a Marco πŸ™‚

  17. esatto quello a 26 euro!

    è la mia Wamp su Vista gira perfettamente.

    …quindi carico il php.ini via ftp?

    Comunque anche Marco mi ha detto di andare su

    hostmonster e comperare un server a 6 euro al

    mese circa,

    mi ha detto poi di comprare solo i

    domini con dns su Aruba ( per i .it )

    e con l'ip del server

    spostare tutti i miei domini lì.

    Raga ditemi voi, sono nelle vostre mani…

    se mi dite di buttarmi dalla finestra, io lo

    faccio senza problemi…

    …tranquillamente non vi preoccupate

    Meglio un programmatore vivo di un ciuccio morto!!!

  18. grazie frateeeee , si vede che con Marco siete programmaticamente "Pappa & CiCCia"… adesso spero "Pappa,CiCCia & CiuCcio"

    a presto grazie per il tuo interessamento e perdona le idiozzie ma devi apparire ridicolo per essere preso sul serio!

    ciucciozzo

  19. Ciao David ,

    la assistenza di hostmonster mi ha scritto, in relazione alla mia domanda se anche se non fosse un server dedicato ( quello a 6.95) se mi potesse far gestire il php.ini e l'httdp.config di apache sul loro server ( come avevamo discusso qui sopra):

    You have full control to modify the php.ini file.

    You do not have access to the httpd.config file. The is a root file that cannot be touched except by admin. No alternation will be made by admin on client's request.

    Thank You,

    Marc Good
    Hostmonster.com

    Quindi non potrò farmi upladare file da 1gb?

    grazie

  20. cioè mi avevi già risposto nel #26

    nel link si diceva che fosse possibile mutare tutte le estenzioni del php.ini ma nelle Impostazioni di Apache:

    Apache web server ha una configurazione LimitRequestBody direttiva che limita le dimensioni di tutti i dati postati indipendentemente dal linguaggio di scripting web in uso. RPM alcuni impianti setta il limite di richiesta a 512Kb. È necessario cambiare ad un valore maggiore o rimuovere la voce del tutto.

    …a questo punto se non possono essere modificate le impostazioni di Apache cosa accade che mi potrebbe bloccare il tutto?

    …cosa mi consigli?

    grazie

    Altre opzioni
    Se si prevede di gestire un gran numero di trasferimenti di file a prendere in considerazione il tuo sito web utilizzando un Perl o Java lato server componente. PHP viene ad essere preferito il linguaggio di programmazione web e perl, ma è solo leggermente in anticipo quando si tratta di gestione dei file.

    La maggior parte delle installazioni di Perl come modulo di Apache può accogliere fino a 32 megabyte, fuori dalla scatola. Confronta questo contro i 2 MB di default per PHP. L'aspetto negativo è che perl codifica richiede solo un po 'più di sforzo in PHP, ma ne vale la pena.

  21. Ciuccio, l'unica cosa che puoi fare in quel caso è installare un componente (Java) che ti permetta di spezzettare i file in upload.

    Ora però non ne conosco…

    L'alternativa è prendere un dedicato, con i relativi costi però.

  22. Ciao e grazie mille.
    "E mi raccomando i permessi di scrittura, altrimenti non va."

    Io ho questo problema relativo ai diritti di accessi, come faccio ad impostare diversamente tali diritti?? Grazie ancora

Comments are closed.