Come costruire un uploader S3 personalizzato

Vi siete mai chiesti come creare un modulo in grado di caricare più file direttamente nel secchio S3 desiderato? Mentre strumenti come S3Fox e Transmit certamente svolgono il lavoro abbastanza bene, a volte abbiamo bisogno di un'interfaccia più semplice, con un solo clic per i nostri clienti. Ne costruiremo uno oggi!


Prodotto finale



Il piano di gioco

Vediamo prima i nostri obiettivi.

Vogliamo creare una semplice pagina di caricamento che fornisca ai nostri clienti / membri del team la possibilità di caricare più file (risorse) sul nostro account S3 con un solo clic. Questo renderà il processo il più semplice possibile per loro, e viene fornito anche con il bonus di limitare l'accesso completo al nostro account S3.


Passaggio 1: non reinventare la ruota

Quando si lavora con le API, tenere sempre presente che potrebbe essere molto più vantaggioso utilizzare le classi esistenti, piuttosto che sprecare ore su ore scorrendo la documentazione API da soli. Il tuo tempo è meglio speso altrove. Inoltre, sul lato positivo, una classe di wrapper testata per l'API desiderata avrà il vantaggio di eseguire molti più test e debug.

Con questo in mente, useremo l'eccellente classe PHP di Amazon S3. Vai avanti e scarica il file zip e trascina la cartella nella radice del tuo progetto.


Passaggio 2: includi la classe

Iniziamo a costruire il nostro semplice controller. Crea un nuovo index.php file e aggiungere:

 // Mostra errori durante la produzione ini_set ('display_errors', 1); // include la classe S3 if (! class_exists ('S3')) require_once 's3 / S3.php'; 

Prima assicuriamo che tutti gli errori siano visualizzati sulla pagina durante la produzione.

Successivamente, dobbiamo includere la classe Amazon S3 che abbiamo scaricato nel primo passaggio. Viene chiamato il file specifico che richiediamo S3.php. Ora dovrebbe essere incluso nel nostro progetto solo se il S3 la classe non esiste già. Tecnicamente, dato che abbiamo il controllo completo su questi file, puoi rimuovere questo controllo, ma è comunque una buona pratica.


Screencast completo



Passaggio 3: credenziali di AWS

Il prossimo passo è passare le credenziali di Amazon S3. Questo tutorial presume che tu abbia già effettuato la registrazione per un account e che tali chiavi siano disponibili per te. Poiché questi valori non dovrebbero cambiare durante il ciclo della nostra applicazione, dovrebbero essere dichiarati correttamente come costanti.

 // Informazioni di accesso AWS se (! Defined ('awsAccessKey')) define ('awsAccessKey', 'your-access-key'); if (! defined ('awsSecretKey')) define ('awsSecretKey', 'your-secret-key');

Fase 4: istanziazione

Ok, abbiamo richiesto il file di classe necessario e abbiamo dichiarato le nostre credenziali. È giunto il momento di creare una nuova istanza della classe S3. Questo ci fornirà quindi una pletora di metodi di supporto durante l'accesso a S3.

 // istanzia la classe $ S3 = new S3 (awsAccessKey, awsSecretKey);

Questa classe accetterà inizialmente due parametri: rispettivamente la chiave di accesso e la chiave segreta. Sopra, stiamo passando le costanti che abbiamo dichiarato nel passaggio tre.


Passaggio 5: includi la visualizzazione

Ok, lo farò per ora. Andiamo avanti e costruiamo la nostra vista - o la forma. Piuttosto che combinare tutto questo PHP e HTML, invece, creeremo un file modello e lo includeremo. In fondo a index.php, Inserisci:

 include 'index.tmpl.php';

Vai avanti e crea questo nuovo file, e sentiti libero di memorizzarlo nella radice della directory del tuo progetto. Aggiungiamo il nostro markup iniziale e il modulo stesso.

      Carica su S3     

Caricare un file

Questo dovrebbe sembrarti per lo più familiare. Per precisare alcuni dettagli, però:

  • Il X-UA-Compatible il meta tag assicura che Internet Explorer, indipendentemente da cosa, usi il suo motore di rendering più recente, piuttosto che tornare alla modalità IE7.
  • Useremo JavaScript per consentire più caricamenti di file, quindi abbiamo bisogno di un hook nel nostro markup. La soluzione più comune è applicare una classe di no-js al html elemento, quindi eseguirne l'override con JavaScript js. È una soluzione facile!
  • La nostra semplice forma contiene solo un file ingresso. Si noti che abbiamo impostato il enctype a / Form-data multipart. Questo è richiesto per tutti i caricamenti di file. Il pulsante di invio verrà aggiunto più avanti in questo tutorial, quando integreremo il plugin Uploadify.
  • Per ora, abbiamo impostato il azione del modulo alla pagina corrente, ma abbiamo anche passato il valore "upload" nella querystring.


Passaggio 7: al caricamento

Quindi, cosa succede quando un utente seleziona un file? Ben escludendo il fatto che non abbiamo ancora integrato il Sottoscrivi pulsante ancora, i dati del file verranno memorizzati nella memoria temporanea. In futuro, gestiremo il processo di salvataggio effettivo dei file nella nostra cartella locale. Per ora, procediamo, assumendo che i file siano stati salvati nella nostra cartella "uploads".

Ascoltiamo un caricamento con PHP. Torna al tuo index.php controller. Subito dopo aver creato una nuova istanza della classe S3:

 // istanzia la classe $ s3 = new S3 (awsAccessKey, awsSecretKey); // controlla se è stato inviato un modulo. if (isset ($ _ GET ['uploads'])) 

Ricorda come impostiamo il azione attributo del modulo da passare ?uploads = completa nella querystring? Quel valore sarà quindi disponibile per noi, tramite: $ _GET [ 'upload']. Quindi, quando la pagina viene caricata, se quel valore esiste, allora sappiamo che il modulo è stato inviato. Eccellente!

Successivamente, dovremmo dichiarare alcune variabili, che indicano come e dove vogliamo supportare i file inviati. Il seguente codice deve essere inserito all'interno di Se dichiarazione di cui sopra.

 $ bucketName = 'myUploadr'; $ uploadsDir = 'uploads /'; $ refused_types = array ('application / exe');

Quando leggi "secchio", pensare "cartella."

S3 usa il termine secchio, ma si riferisce essenzialmente al nome di una cartella all'interno del tuo account. Sentiti libero di chiamarlo come desideri. Ho chiamato il mio secchio, myUploadr.

Successivamente, abbiamo bisogno di sapere dove sono stati memorizzati i file caricati. Quindi utilizzeremo quel percorso per caricare in sequenza i file in quella cartella sul bucket S3. Crea una cartella, chiamata uploads, e posizionarlo nella radice del tuo progetto.

Infine, dovremmo indicare quali tipi di file possono essere caricati, o il contrario. Questa opzione dipenderà dalle esigenze specifiche del tuo progetto. In questo caso, per mantenere le cose semplici, negheremo tutto EXE file, ma sentiti libero di modificare questo come desideri.

Si noti che il $ refused_types l'array non fa nulla di per sé. È semplicemente una matrice che collegheremo in seguito.


Passaggio 8: scansione della directory di caricamento

Per determinare quali file dobbiamo lavorare, dobbiamo esaminare la directory dei caricamenti. PHP offre l'utile scandir funzione per consentire questo.

 $ files = scandir ($ uploadsDir); array_shift ($ file); array_shift ($ file);

Mai notato come scandir la funzione restituisce sempre due voci: '.' e '? '? Questi si riferiscono alle cartelle e, anche se potremmo essere un po 'più tecnici a riguardo, cerchiamo di essere pigri e suddividere questi due dalla nostra lista usando il array_shift funzione. Questo ci lascerà con:

 Array ([0] => some-file.jpg)

Passaggio 9: invia a S3

Bene, ora che abbiamo una serie di tutti i file che devono essere caricati, approfittiamo della classe S3! Scopriamolo. Abbiamo bisogno di:

  1. Crea un bucket S3
  2. Filtra attraverso tutti i file nella directory "uploads"
  3. Cambia il nome del file in qualcosa di unico. Forse possiamo usare PHP tempo funzione per questo. In caso contrario, rischiamo di sovrascrivere i file con lo stesso nome.
  4. Carica il file su S3
  5. Elimina il file dalla nostra cartella "uploads" temporanea, perché ora è memorizzato su S3.
 // crea un nuovo bucket $ S3-> putBucket ("$ bucketName", S3 :: ACL_PUBLIC_READ); // filtra gli elementi nella cartella "uploads /" per ($ i = 0; $ i < count($files); $i++ )  // Determine what type of file it is. (for example, "image/png") $mt = mime_content_type('uploads/' . $files[$i]); // If the file type is in our refused_types array, delete it, and continue? if ( in_array($mt, $refused_types) )  // can't accept this file type. Delete it. // You could also reverse this to only accepted allowed-types. unlink($uploadsDir . $fils[$i]); continue;  //Prefix a unique sequence of characters to the file name $fileName = time() . '-' . $files[$i]; // path to file we want to move, the desired bucket, the desired file name, when it is added to the bucket, Access control list if ($S3->putObjectFile ($ uploadsDir. $ files [$ i], "$ bucketName", $ fileName, S3 :: ACL_PUBLIC_READ)) // cancella file unlink ($ uploadsDir. $ files [$ i]); // update filesArr $ filesArr [$ files [$ i]] = "http: //$bucketName.s3.amazonaws.com/$fileName"; 

Linea per linea

Ok, prendiamo quel codice riga per riga, per la massima chiarezza.

 $ S3-> putBucket ("$ bucketName", S3 :: ACL_PUBLIC_READ);

Questo metodo della classe $ S3 ci consente di aggiungere un nuovo bucket al nostro account S3. Accetta due parametri: il nome del bucket e le autorizzazioni. Qui, abbiamo passato in "myUploadr" e abbiamo impostato le autorizzazioni per la lettura pubblica di tutto.

 per ($ i = 0; $ i < count($files); $i++ ) 

Questo per la dichiarazione ci permetterà di scorrere tutte le immagini nel uploads cartella.

 $ fileName = time (). '-'. $ File [$ i];

Questa linea assicurerà che il nome file sia unico e non si scontrino con i file esistenti nel bucket su S3. Il tempo() funzione assegnerà una stringa di caratteri univoca al nostro nome file.

 if ($ S3-> putObjectFile ($ uploadsDir. $ files [$ i], "$ bucketName", $ fileName, S3 :: ACL_PUBLIC_READ)) 

Questa linea gestisce il processo di caricamento del file su S3, grazie all'aiuto putObjectFile metodo della classe S3. Questo metodo accetterà quattro parametri primari.

  • Il percorso del file che vogliamo caricare su S3
  • Il nome del bucket (cartella) in cui stiamo caricando
  • Il nome del file desiderato
  • I tuoi privilegi di accesso assegnati
 scollegare ($ uploadsDir. $ files [$ i]);

Se il file è stato caricato correttamente, non è più necessario archiviarlo localmente. Possiamo cancellare il file usando PHP scollegare funzione e passando un percorso al file che dovrebbe essere cancellato.

Ora, cosa succede se stiamo caricando più file su S3, che è probabile? Abbiamo bisogno di un posto dove archiviare i percorsi di tutti questi file, giusto? Con questo in mente, creiamo un nuovo array, chiamato $ filesArr.

 // un array contenente collegamenti a tutte le immagini caricate $ filesArr = array ();

Puoi posizionarlo in cima al tuo Se dichiarazione. Con quell'array che abbiamo creato, abbiamo solo bisogno di spingere il percorso di ogni file caricato su di esso.

 // update filesArr $ filesArr [$ files [$ i]] = "http: //$bucketName.s3.amazonaws.com/$fileName";

Una volta il per la dichiarazione completa, $ fileArr di conseguenza conterrà un elenco di percorsi per ogni file caricato. Presto!

Completato index.php File

Fare riferimento qui sotto per il codice sorgente completo per il nostro semplice "controller".

 putBucket ("$ bucketName", S3 :: ACL_PUBLIC_READ); // filtra gli oggetti nella cartella di uplaod per ($ i = 0; $ i < count($files); $i++ )  //retrieve post variables $fileName = time() . '-' . $files[$i]; // path to file we want to move, the desired bucket, the desired file name, when it is added to the bucket, Access control list if ($s3->putObjectFile ($ uploadsDir. $ files [$ i], "$ bucketName", $ fileName, S3 :: ACL_PUBLIC_READ)) // cancella file unlink ($ uploadsDir. $ files [$ i]); // update filesArr $ filesArr [$ files [$ i]] = "http: //$bucketName.s3.amazonaws.com/$fileName";  include 'index.tmpl.php';

Passaggio 11: caricamento di file con Uploadify


Abbiamo scritto tutte le funzionalità lato server per la nostra piccola web app. Ma ora, dobbiamo gestire il processo front-end di caricamento di più file sul nostro uploads / directory. Per fare ciò, approfitteremo del pratico Uploadify.

"Uploadify è un plugin jQuery che integra un'utilità di caricamento di file multipli completamente personalizzabile sul tuo sito Web. Utilizza una combinazione di Javascript, ActionScript e qualsiasi linguaggio lato server per creare dinamicamente un'istanza su qualsiasi elemento DOM su una pagina."

Scaricare

Il primo passo, quando si integra Uploadify, è scaricare i file necessari. Possono essere ottenuti qui. Rinominare la cartella scaricata in "uploadify" e posizionarla nella directory principale della directory del progetto.

Riferimenti di script

Successivamente, dobbiamo fare riferimento ai file necessari dal nostro punto di vista. Ritornare a index.tmpl.php, e, poco prima della chiusura corpo etichetta, aggiungi:

    

Qui, facciamo riferimento all'ultima versione di jQuery, swfobject, lo script principale di Uploadify e il nostro file scripts.js (ora puoi creare quel file).

scripts.js

Attiva ora Uploadify.

 (function () var myUploadr = uploadify: function () $ ('# file_upload'). uploadify ('uploader': 'uploadify / uploadify.swf', 'script': 'uploadify / uploadify.php', 'cancelImg': 'uploadify / cancel.png', 'cartella': 'uploads', 'auto': true, 'multi': true, 'wmode': 'transparent', 'buttonText': 'Send to S3' , 'sizeLimit': 10485760, // 10 mega 'onAllComplete': function () // tutti i file hanno finito di caricare location = "index.php? uploads = complete";);) ();

Attivare Uploadify è semplice come chiamare un metodo. Ricorda, Uploadify è solo un fantastico plugin jQuery. Questo metodo accetta molti parametri opzionali. Ti incoraggio a guardarli qui. Per le nostre esigenze particolari, ne richiediamo solo una manciata.

  • uploader: Il percorso per il swf file che gestisce il pulsante di invio
  • script: Il percorso verso uploadify.php
  • cancelImg: Il percorso per il pulsante Annulla. (Uno è fornito di default)
  • cartella: Il percorso della cartella in cui verranno archiviati i file caricati
  • auto: Un valore booleano, che indica se i caricamenti devono essere eseguiti automaticamente.
  • a più: Sono consentiti più caricamenti di file?
  • wmode: Imposta questo a trasparente per garantire che non vi siano problemi di tipo "z-index", in cui il pulsante viene visualizzato tramite un menu a discesa o qualcosa di simile.
  • buttonTxt: Cosa dovrebbe dire il pulsante di invio?
  • SizeLimit: Qual è la dimensione massima del file che accetteremo?
  • onAllComplete: Questo metodo verrà eseguito quando tutti i file hanno completato il caricamento. Nel nostro caso, stiamo ricaricando la pagina e stiamo passando il uploads = completa param nella stringa di query.

Questo dovrebbe farlo! Assicurati di chiamare il nostro uploadify funzione nella parte inferiore di scripts.js.

 myUploadr.uploadify ();

Questo codice applicherà il pulsante personalizzato al modulo e gestirà anche la logica di caricamento e trasferimento dei file nella cartella necessaria.





Passaggio 12: visualizzazione dei risultati

A questo punto, abbiamo scritto la maggior parte della nostra logica. Ma c'è un ultimo compito che dobbiamo finire. Ricorda quando abbiamo scritto la logica che ha gestito gli upload sul nostro account S3? Abbiamo memorizzato i collegamenti in un schieramento, chiamato $ filesArr.

Quando il nostro modulo si carica, dovremmo determinare se questo schieramento esiste e non è vuoto. In tal caso, i file sono già stati caricati, nel qual caso è necessario solo visualizzare i collegamenti a ciascun asset caricato.

Ritornare a index.tmpl.php, e, appena sotto il modulo principale, aggiungi quanto segue:

  

Link ai file caricati

    $ percorso):?>
  • ">

Questo bit di codice determina prima se $ filesArr esiste. Se lo fa, allora contiene sia il nome che il link a ciascun file caricato. Per visualizzare questi collegamenti, il processo è semplice come filtrare attraverso ogni elemento nell'array ed echeggiare un tag di ancoraggio, che collega al file associato.



Completamento

Questo dovrebbe farlo! Ora che tutte le funzionalità sono fuori mano, il tuo prossimo passo è quello di personalizzare la pagina in base alle tue esigenze specifiche. Potremmo coprirlo, ma è decisamente oltre lo scopo di questo tutorial. Usa la tua immaginazione - ecco cosa ho finito con.


Grazie per la lettura e fammi sapere se hai qualche domanda! Se parti del tutorial scritto ti hanno confuso, assicurati di guardare anche lo screencast!