Een aangepaste S3-uploader maken

Heeft u zich ooit afgevraagd hoe u een formulier kunt maken dat meerdere bestanden rechtstreeks naar uw gewenste S3-bucket kan uploaden? Hoewel tools als S3Fox en Transmit de klus behoorlijk goed klaren, hebben we soms een eenvoudiger interface met één muisklik nodig voor onze klanten. We zullen er vandaag een bouwen!


Eindproduct



Het speelplan

Laten we eerst onze doelen achterhalen.

We willen een eenvoudige uploadpagina maken die onze klanten / teamleden de mogelijkheid biedt om met één klik meerdere bestanden (assets) naar onze S3-account te uploaden. Dit maakt het proces zo eenvoudig mogelijk voor hen, en wordt ook geleverd met de bonus van het beperken van volledige toegang tot ons S3-account.


Stap 1 - Stel het wiel niet opnieuw uit

Denk er bij het werken met API's altijd aan dat het veel voordeliger kan zijn om bestaande klassen te gebruiken in plaats van urenlang urenlang zelf de API-documentatie te doorzoeken. Je tijd is beter elders te besteden. Trouwens, aan de positieve kant, een geteste wrapper klasse voor jouw gewenste API zal het voordeel hebben van veel meer testen en debuggen.

Met dat in gedachten, zullen we de uitstekende Amazon S3 PHP Class gebruiken. Ga je gang en download het zipbestand en sleep de map naar de hoofdmap van je project.


Stap 2 - Neem de klas op

Laten we beginnen met het bouwen van onze eenvoudige controller. Maak een nieuw index.php bestand en voeg toe:

 // Weergavefouten tijdens productie ini_set ('display_errors', 1); // neem de S3-klasse op als (! class_exists ('S3')) require_once 's3 / S3.php'; 

We zorgen er eerst voor dat alle fouten tijdens de productie op de pagina worden weergegeven.

Vervolgens moeten we de Amazon S3-klasse toevoegen die we in stap één hebben gedownload. Het specifieke bestand dat we nodig hebben, wordt gebeld S3.php. Nu zou het alleen in ons project moeten worden opgenomen als het S3 klasse bestaat nog niet. Technisch gezien, omdat we de volledige controle hebben over deze bestanden, kun je wegkomen met het verwijderen van deze cheque, maar het is nog steeds een goede gewoonte.


Volledige screencast



Stap 3 - AWS-referenties

De volgende stap is om onze Amazon S3-inloggegevens door te geven. In deze zelfstudie wordt ervan uitgegaan dat u zich al hebt aangemeld voor een account en dat deze sleutels voor u beschikbaar zijn. Aangezien deze waarden niet door de cyclus van onze applicatie moeten veranderen, moeten ze op de juiste manier worden aangegeven als constanten.

 // AWS-toegangsinformatie als (! Defined ('awsAccessKey')) define ('awsAccessKey', 'your-access-key'); if (! defined ('awsSecretKey')) define ('awsSecretKey', 'your-secret-key');

Stap 4 - Instantiatie

Oké, we hebben het benodigde klassenbestand nodig en hebben onze inloggegevens opgegeven. Het is nu tijd om een ​​nieuw exemplaar van de S3-klasse te maken. Dit biedt ons dan een overvloed aan hulpmethoden bij het benaderen van S3.

 // instantiate de klasse $ S3 = nieuwe S3 (awsAccessKey, awsSecretKey);

Deze klasse accepteert aanvankelijk twee parameters: de toegangssleutel en de geheime sleutel. Hierboven passeren we de constanten die we in stap drie hebben verklaard.


Stap 5 - Neem de weergave op

Oké, dat zal voorlopig wel lukken. Laten we verder gaan en onze visie opbouwen - of de vorm. In plaats van al deze PHP en HTML te combineren, maken we in plaats daarvan een sjabloonbestand en nemen het op. Onderaan index.php, toevoegen:

 include 'index.tmpl.php';

Ga je gang en maak dit nieuwe bestand aan, en voel je vrij om het op te slaan in de root van je projectdirectory. Laten we onze initiële markup en het formulier zelf toevoegen.

      Uploaden naar S3     

Een bestand uploaden

Dit zou je allemaal vooral bekend moeten voorkomen. Om een ​​paar details te noemen, hoewel:

  • De X-UA-Compatible Metatag zorgt ervoor dat Internet Explorer, ongeacht wat, zijn nieuwste rendering-engine gebruikt, in plaats van terug te vallen naar de IE7-modus.
  • We zullen JavaScript gebruiken om meerdere bestandsuploads toe te staan, dus we hebben een haakje nodig in onze markup. De meest gebruikelijke oplossing is om een ​​klasse van toe te passen no-js naar de html element en negeer dit dan met JavaScript to js. Het is een eenvoudige oplossing!
  • Onze eenvoudige vorm bevat alleen een het dossier invoer. Merk op dat we de enctype naar multipart / form-data. Dit is vereist voor alle bestandsuploads. De knop Verzenden wordt later in deze zelfstudie toegevoegd wanneer we de plug-in voor Uploadify integreren.
  • Voorlopig hebben we de actie van het formulier naar de huidige pagina, maar we hebben ook de waarde "uploads" in de querystring doorgegeven.


Stap 7 - Na het uploaden

Wat gebeurt er wanneer een gebruiker een bestand selecteert? Met uitzondering van het feit dat we het. Nog niet hebben geïntegreerd voorleggen knop, de bestandsgegevens worden opgeslagen in het tijdelijke geheugen. We zullen het proces van het daadwerkelijk opslaan van de bestanden in een volgende stap naar onze lokale map afhandelen. Laten we voorlopig verder gaan, ervan uitgaande dat bestanden zijn opgeslagen in onze map "uploads".

Laten we luisteren naar een upload met PHP. Keer terug naar jouw index.php controller. Onmiddellijk nadat u een nieuw exemplaar van de S3-klasse hebt gemaakt:

 // instantiate de klasse $ s3 = new S3 (awsAccessKey, awsSecretKey); // controleer of een formulier is ingediend. if (isset ($ _ GET ['uploads'])) 

Onthoud hoe we de actie attribuut van het formulier om door te geven ?= volledige uploads in de querystring? Die waarde zal dan beschikbaar zijn voor ons, via: $ _GET [ 'upload']. Dus als de pagina wordt geladen en deze waarde bestaat, weten we dat het formulier is ingediend. Uitstekend!

Vervolgens moeten we enkele variabelen declareren, die verwijzen naar hoe en waar we de ingediende bestanden willen ondersteunen. De volgende code moet worden geplaatst in de als verklaring hierboven.

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

Wanneer je leest "emmer", denken "map."

S3 gebruikt de term emmer, maar het verwijst in essentie naar een mapnaam in uw account. Voel je vrij om dit te noemen zoals je wilt. Ik heb mijn emmer gebeld, myUploadr.

Vervolgens moeten we weten waar de geüploade bestanden zijn opgeslagen. Vervolgens gebruiken we dat pad om de bestanden in die map sequentieel naar de S3-bucket te uploaden. Maak een map, genaamd uploads, en plaats het in de hoofdmap van uw project.

Ten slotte moeten we aangeven welke bestandstypen kunnen worden geüpload of omgekeerd. Deze optie is afhankelijk van de specifieke behoeften van uw project. In dit geval zullen we alles weigeren om dingen eenvoudig te houden exe bestanden, maar voel je vrij om dit aan te passen zoals jij dat wilt.

Merk op dat de $ refused_types array doet niets op zichzelf. Het is gewoon een array waar we later op ingaan.


Stap 8 - De Uploads-directory scannen

Om te bepalen met welke bestanden we moeten werken, moeten we de uploaddirectory scannen. PHP biedt de behulpzame scandir functie om dit mogelijk te maken.

 $ files = scandir ($ uploadsir); array_shift ($ bestanden); array_shift ($ bestanden);

Ooit opgevallen hoe het scandir functie retourneert altijd twee items: '.' en '? '? Deze verwijzen naar mappen, en hoewel we wat technischer kunnen zijn, laten we lui zijn en die twee van onze lijst afsnijden met behulp van de array_shift functie. Dat zal ons verlaten met:

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

Stap 9 - Stuur naar S3

Oké, nu we een reeks van alle bestanden hebben die geüpload moeten worden, laten we ons voordeel halen uit de S3-klasse! Laten we dit uitzoeken. We moeten:

  1. Maak een S3-bucket
  2. Filter door alle bestanden in de map "uploads"
  3. Verander de naam van het bestand in iets unieks. Misschien kunnen we PHP's gebruiken tijd functie hiervoor. Anders riskeren we het overschrijven van bestanden met dezelfde naam.
  4. Upload het bestand naar S3
  5. Verwijder het bestand uit onze tijdelijke map "uploads", want het is nu opgeslagen op S3.
 // maak een nieuwe bucket $ S3-> putBucket ("$ bucketName", S3 :: ACL_PUBLIC_READ); // filter door items in de "uploads /" map voor ($ 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)) // verwijder bestand ontkoppelen ($ uploadsDir. $ files [$ i]); // update bestandenArr $ filesArr [$ files [$ i]] = "http: //$bucketName.s3.amazonaws.com/$fileName"; 

Lijn bij lijn

Oké, laten we die code regel voor regel nemen, voor maximale duidelijkheid.

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

Met deze methode van de $ S3-klasse kunnen we een nieuwe bucket toevoegen aan ons S3-account. Het accepteert twee parameters: de naam van de bucket en de rechten. Hier hebben we "myUploadr" doorgegeven en hebben we de permissies ingesteld om alles te lezen.

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

Deze voor verklaring stelt ons in staat om door alle afbeeldingen in de. te bladeren uploads map.

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

Deze regel zorgt ervoor dat de bestandsnaam uniek is en niet botst met bestaande bestanden in de bucket op S3. De tijd() functie voegt een unieke tekenreeks toe aan onze bestandsnaam.

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

Deze regel behandelt het proces van het uploaden van het bestand naar S3, dankzij het behulpzame putObjectFile methode van de S3-klasse. Deze methode accepteert vier primaire parameters.

  • Het pad naar het bestand dat we willen uploaden naar S3
  • De naam van de bucket (map) waarnaar we uploaden
  • De gewenste bestandsnaam
  • Uw toegekende toegangsrechten
 ontkoppelen ($ uploadsDir. $ bestanden [$ i]);

Als het bestand met succes is geüpload, hebben we het niet langer lokaal opgeslagen nodig. We kunnen het bestand verwijderen met behulp van PHP's ontkoppelen functie en geeft een pad door aan het bestand dat moet worden verwijderd.

Wat gebeurt er als we meerdere bestanden uploaden naar S3, wat waarschijnlijk is? We hebben een plaats nodig om de paden op te slaan naar al deze bestanden, toch? Laten we met dat in gedachten een nieuwe array maken, genaamd $ filesArr.

 // een array met links naar alle geüploade afbeeldingen $ filesArr = array ();

Je kunt dit bovenaan je plaatsen als uitspraak. Met die array die we hebben gemaakt, hoeven we alleen maar het pad naar elk geüpload bestand ernaar te pushen.

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

Zodra de voor verklaring is voltooid, $ fileArr zal daarom een ​​lijst met paden bevatten voor elk geüpload bestand. Presto!

Voltooid index.php het dossier

Zie hieronder voor de ingevulde broncode voor onze eenvoudige "controller".

 putBucket ("$ bucketName", S3 :: ACL_PUBLIC_READ); // filter door items in de map uplaod voor ($ 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)) // verwijder bestand ontkoppelen ($ uploadsDir. $ files [$ i]); // update bestandenArr $ filesArr [$ files [$ i]] = "http: //$bucketName.s3.amazonaws.com/$fileName";  include 'index.tmpl.php';

Stap 11 - Uploads van bestanden met Uploadify


We hebben alle serverfunctionaliteit voor onze kleine webapp geschreven. Maar nu moeten we omgaan met het front-end proces van het uploaden van meerdere bestanden naar onze uploads / directory. Om dit te doen, zullen we gebruik maken van de handige Uploadify.

"Uploadify is een jQuery-invoegtoepassing die een volledig aanpasbaar hulpprogramma voor het uploaden van meerdere bestanden op uw website bevat. Het maakt gebruik van een combinatie van JavaScript, ActionScript en elke servertaal om dynamisch een instantie te maken voor elk DOM-element op een pagina."

Download

De eerste stap, bij het integreren van Uploadify, is om de benodigde bestanden te downloaden. Ze kunnen hier worden verkregen. Hernoem de gedownloade map naar "uploadify" en plaats deze in de hoofdmap van uw projectdirectory.

Scriptreferenties

Vervolgens moeten we verwijzen naar de noodzakelijke bestanden van onze mening. Terug keren naar index.tmpl.php, en, vlak voor de sluiting lichaam tag, toevoegen:

    

Hier verwijzen we naar de nieuwste versie van jQuery, swfobject, het kernscript van Uploadify en ons eigen scripts.js-bestand (u kunt dat bestand nu maken).

Scripts.js

Laten we nu Uploadify activeren.

 (function () var myUploadr = uploadify: function () $ ('# file_upload'). uploadify ('uploader': 'uploadify / uploadify.swf', 'script': 'uploadify / uploadify.php', 'cancelImg': 'uploadify / cancel.png', 'folder': 'uploads /', 'auto': true, 'multi': true, 'wmode': 'transparent', 'buttonText': 'Send to S3' , 'sizeLimit': 10485760, // 10 megs 'onAllComplete': function () // alle bestanden klaar met het uploaden van de locatie = "index.php? uploads = complete";);) ();

Het activeren van Uploadify is net zo eenvoudig als het aanroepen van een methode. Onthoud, Uploadify is gewoon een geweldige plug-in voor jQuery. Deze methode accepteert veel optionele parameters. Ik moedig je aan om ze hier te bekijken. Voor onze specifieke behoeften hebben we slechts een handvol nodig.

  • uploader: Het pad naar de swf bestand dat de verzendknop verwerkt
  • script: Het pad naar uploadify.php
  • cancelImg: Het pad naar de annuleerknop. (Eén wordt standaard meegeleverd)
  • map: Het pad naar de map waar de geüploade bestanden worden opgeslagen
  • auto: Een boolean, die aangeeft of uploads automatisch moeten worden uitgevoerd.
  • multi: Zijn meerdere bestandsuploads toegestaan?
  • wmode: Zet dit op transparant om ervoor te zorgen dat er geen problemen met het type "Z-index" zijn, waarbij de knop wordt weergegeven in een vervolgkeuzemenu of iets dergelijks.
  • buttonTxt: Wat moet de knop Verzenden zeggen??
  • sizeLimit: Wat is de maximale bestandsgrootte die we accepteren??
  • onAllComplete: Deze methode wordt uitgevoerd wanneer alle bestanden zijn geüpload. In ons geval laden we de pagina opnieuw en passeren we de = volledige uploads param in de querystring.

Dat zou het moeten doen! Zorg er wel voor dat u ons belt uploadify functie onderaan scripts.js.

 myUploadr.uploadify ();

Deze code past de aangepaste knop toe op uw formulier en verwerkt ook de logica van het uploaden en overbrengen van uw bestanden naar de benodigde map.





Stap 12 - De resultaten weergeven

Op dit punt hebben we het grootste deel van onze logica geschreven. Maar er is nog een laatste taak die we moeten voltooien. Weet je nog dat we de logica hebben geschreven van het verwerken van uploads naar ons S3-account? We hebben de links opgeslagen in een rangschikking, riep $ filesArr.

Wanneer ons formulier wordt geladen, moeten we bepalen of dit rangschikking bestaat en is niet leeg. Als dat het geval is, zijn de bestanden al geüpload. In dat geval hoeven we alleen links naar elk geüpload item weer te geven.

Terug keren naar index.tmpl.php, en voeg net onder het primaire formulier het volgende toe:

  

Links naar geüploade bestanden

    $ pad):?>
  • ">

Dit stukje code bepaalt eerst of $ filesArr bestaat. Als dat zo is, bevat het zowel de naam als de koppeling naar elk geüpload bestand. Om deze koppelingen weer te geven, is het proces net zo eenvoudig als het filteren van elk item in de array en het uiten van een ankertag, die linkt naar het bijbehorende bestand.



Voltooiing

Dat zou het moeten doen! Nu alle functionaliteit uit de weg is, is uw volgende stap om de pagina naar uw specifieke behoeften te stylen. We kunnen dat behandelen, maar het valt beslist buiten het bestek van deze tutorial. Gebruik je fantasie - dit is wat ik uiteindelijk heb bereikt.


Bedankt voor het lezen en laat me weten of je nog vragen hebt! Als delen van de geschreven tutorial je in de war brengen, let dan ook goed op de screencast!