Cómo construir un cargador de S3 personalizado

¿Alguna vez se ha preguntado cómo crear un formulario que pueda cargar varios archivos directamente a su grupo de S3 deseado? Si bien herramientas como S3Fox y Transmit ciertamente hacen el trabajo bastante bien, a veces necesitamos una interfaz más simple y de un solo clic para nuestros clientes. Vamos a construir uno hoy!


Producto final



El plan de juego

Vamos a averiguar nuestras metas primero.

Queremos crear una página de carga simple que proporcione a nuestros clientes / miembros del equipo la capacidad de cargar varios archivos (activos) a nuestra cuenta S3 con un solo clic. Esto hará que el proceso sea lo más sencillo posible para ellos, y también viene con la ventaja de restringir el acceso total a nuestra cuenta S3.


Paso 1 - No reinventar la rueda

Cuando trabaje con API, siempre tenga en cuenta que podría ser mucho más beneficioso utilizar las clases existentes, en lugar de perder horas y horas recorriendo la documentación de la API. Su tiempo es mejor gastado en otros lugares. Además, en el lado positivo, una clase de envoltura probada para la API deseada tendrá la ventaja de muchas más pruebas y depuración..

Con eso en mente, usaremos la excelente clase de PHP S3 de Amazon. Continúe, descargue el archivo zip y arrastre la carpeta a la raíz de su proyecto.


Paso 2 - Incluir la clase

Vamos a empezar a construir nuestro controlador simple. Crear un nuevo index.php archivo, y añadir:

 // Mostrar errores durante la producción ini_set ('display_errors', 1); // incluir la clase S3 si (! class_exists ('S3')) require_once 's3 / S3.php'; 

Primero nos aseguramos de que todos los errores se muestren en la página durante la producción..

A continuación, debemos incluir la clase de Amazon S3 que descargamos en el paso uno. El archivo específico que requerimos se llama S3.php. Ahora solo debe ser incluido en nuestro proyecto si el S3 La clase no existe ya. Técnicamente, como tenemos el control total sobre estos archivos, puede eliminar este chequeo, pero sigue siendo una buena práctica.


Screencast completo



Paso 3 - Credenciales de AWS

El siguiente paso es pasar nuestras credenciales de Amazon S3. Este tutorial asume que ya se ha registrado en una cuenta y tiene esas claves disponibles para usted. Como estos valores no deben cambiar a lo largo del ciclo de nuestra aplicación, deben ser declarados apropiadamente como constantes.

 // Información de acceso a AWS si (! Define ('awsAccessKey')) define ('awsAccessKey', 'your-access-key'); if (! defined ('awsSecretKey')) define ('awsSecretKey', 'your-secret-key');

Paso 4 - Instanciación

De acuerdo, requerimos el archivo de clase necesario y hemos declarado nuestras credenciales. Ahora es el momento de crear una nueva instancia de la clase S3. Esto nos proporcionará una gran cantidad de métodos de ayuda al acceder a S3.

 // crear una instancia de la clase $ S3 = nuevo S3 (awsAccessKey, awsSecretKey);

Esta clase aceptará inicialmente dos parámetros: la clave de acceso y la clave secreta, respectivamente. Arriba, estamos pasando las constantes que declaramos en el paso tres.


Paso 5 - Incluir la vista

Está bien, eso va a hacer por ahora. Avancemos y construyamos nuestra vista, o el formulario. En lugar de combinar todo este PHP y HTML, en lugar de eso, crearemos un archivo de plantilla y lo incluiremos. En el fondo de index.php, añadir:

 incluye 'index.tmpl.php';

Continúe y cree este nuevo archivo, y siéntase libre de almacenarlo en la raíz del directorio de su proyecto. Añadamos nuestro marcado inicial y la forma, en sí..

      Subir a S3     

Cargar un archivo

Todo esto debería parecerle familiar. Para señalar algunos detalles, sin embargo:

  • los Compatible con X-UA la metaetiqueta asegura que Internet Explorer, sin importar qué, utilice su último motor de renderización, en lugar de volver al modo IE7.
  • Usaremos JavaScript para permitir múltiples cargas de archivos, por lo que necesitamos un enlace en nuestro marcado. La solución más común es aplicar una clase de no-js al html elemento, y luego anularlo con JavaScript para js. Es una solucion facil!
  • Nuestra forma simple solo contiene un expediente entrada. Tenga en cuenta que hemos establecido el enctype a multipart / form-data. Esto es necesario para todas las cargas de archivos. El botón de envío se agregará más adelante en este tutorial, cuando integramos el complemento Uploadify.
  • Por el momento, hemos establecido la acción del formulario a la página actual, pero también hemos pasado el valor "cargas" en la cadena de consulta.


Paso 7 - Al subir

Entonces, ¿qué sucede cuando un usuario selecciona un archivo? Bueno, excluyendo el hecho de que aún no hemos integrado el enviar botón aún, los datos del archivo se almacenarán en la memoria temporal. Manejaremos el proceso de guardar realmente los archivos en nuestra carpeta local en un paso futuro. Por ahora, prosigamos, asumiendo que los archivos se han guardado en nuestra carpeta de "cargas".

Vamos a escuchar una subida con PHP. Volver a su index.php controlador. Inmediatamente después de crear una nueva instancia de la clase S3:

 // instancia la clase $ s3 = new S3 (awsAccessKey, awsSecretKey); // comprobar si se ha enviado un formulario. if (isset ($ _ GET ['uploads'])) 

Recuerda cómo configuramos el acción atributo de la forma para pasar ?subidas = completado en la cadena de consulta? Ese valor estará disponible para nosotros, a través de: $ _GET ['uploads']. Entonces, cuando la página se carga, si ese valor existe, entonces sabemos que el formulario ha sido enviado. Excelente!

A continuación, debemos declarar algunas variables, que hacen referencia a cómo y dónde queremos apoyar los archivos enviados. El siguiente código debe ser colocado dentro del Si declaración arriba.

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

Cuando lees "cangilón", pensar "carpeta."

S3 usa el término cangilón, pero esencialmente se refiere a un nombre de carpeta dentro de su cuenta. Siéntase libre de nombrar esto como desee. He llamado a mi balde, MyUploadr.

A continuación, necesitamos saber dónde se almacenaron los archivos cargados. Luego, usaremos esa ruta para cargar de forma secuencial los archivos de esa carpeta al contenedor S3. Crea una carpeta, llamada subidas, y colócalo dentro de la raíz de tu proyecto..

Por último, debemos designar los tipos de archivos que se pueden cargar o lo contrario. Esta opción dependerá de las necesidades específicas de su proyecto. En este caso, para mantener las cosas simples, negaremos todo exe archivos, pero siéntase libre de modificar esto como desee.

Tenga en cuenta que el $ reject_types array no hace nada en sí mismo. Es simplemente una matriz que conectaremos más tarde.


Paso 8 - Escaneando el Directorio de Subidas

Para determinar con qué archivos tenemos que trabajar, necesitamos escanear el directorio de subidas. PHP ofrece la ayuda scandir función para permitir esto.

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

¿Alguna vez has notado cómo scanDir La función siempre devuelve dos elementos: '.' y '? '? Estos se refieren a carpetas y, aunque podríamos ser un poco más técnicos al respecto, seamos perezosos y recortemos esos dos de nuestra lista usando el array_shift función. Eso nos dejará con:

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

Paso 9 - Enviar a S3

De acuerdo, ahora que tenemos una matriz de todos los archivos que se deben cargar, ¡aprovechemos la clase S3! Vamos a resolver esto. Necesitamos que:

  1. Crear un cubo S3
  2. Filtrar a través de todos los archivos en el directorio "uploads"
  3. Cambia el nombre del archivo a algo único. Tal vez podamos usar PHP's hora funciona para esto De lo contrario, corremos el riesgo de sobrescribir los archivos que tienen los mismos nombres.
  4. Sube el archivo a S3
  5. Elimine el archivo de nuestra carpeta temporal de "cargas", porque ahora está almacenado en S3.
 // crea un nuevo cubo $ S3-> putBucket ("$ bucketName", S3 :: ACL_PUBLIC_READ); // filtrar a través de los elementos en la carpeta "uploads /" para ($ 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)) // delete file unlink ($ uploadsDir. $ files [$ i]); // update filesArr $ filesArr [$ files [$ i]] = "http: //$bucketName.s3.amazonaws.com/$fileName"; 

Linea por linea

De acuerdo, tomemos ese código línea por línea, para mayor claridad..

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

Este método de la clase $ S3 nos permite agregar un nuevo grupo a nuestra cuenta S3. Acepta dos parámetros: el nombre del grupo y los permisos. Aquí, hemos pasado en "myUploadr", y hemos establecido los permisos para que el público lea todo.

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

Esta para declaración nos permitirá hacer un ciclo a través de todas las imágenes en el subidas carpeta.

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

Esta línea asegurará que el nombre del archivo sea único y que no coincida con los archivos existentes en el depósito en S3. los hora() La función prefijará una cadena de caracteres única a nuestro nombre de archivo.

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

Esta línea maneja el proceso de carga del archivo a S3, gracias a la ayuda putObjectFile Método de la clase S3. Este método aceptará cuatro parámetros primarios..

  • La ruta al archivo que deseamos subir a S3.
  • El nombre del cubo (carpeta) que estamos cargando
  • El nombre del archivo deseado
  • Sus privilegios de acceso asignados
 unlink ($ uploadsDir. $ files [$ i]);

Si el archivo se cargó correctamente, ya no lo necesitamos almacenado localmente. Podemos eliminar el archivo usando PHP's desconectar función, y pasar en una ruta al archivo que debe ser eliminado.

Ahora, ¿qué pasa si estamos cargando varios archivos a S3, lo que es probable? Necesitamos un lugar para almacenar las rutas a todos estos archivos, ¿verdad? Con eso en mente, vamos a crear una nueva matriz, llamada $ filesArr.

 // una matriz que contiene enlaces a todas las imágenes cargadas $ filesArr = array ();

Puede colocar esto en la parte superior de su Si declaración. Con la matriz que creamos, solo tenemos que insertar la ruta a cada archivo cargado.

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

Una vez el para declaración completa, $ fileArr en consecuencia, contendrá una lista de rutas a cada archivo cargado. Presto!

Terminado index.php Expediente

Consulte a continuación el código fuente completado para nuestro simple "controlador".

 putBucket ("$ bucketName", S3 :: ACL_PUBLIC_READ); // filtrar a través de elementos en la carpeta uplaod para ($ 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)) // delete file unlink ($ uploadsDir. $ files [$ i]); // update filesArr $ filesArr [$ files [$ i]] = "http: //$bucketName.s3.amazonaws.com/$fileName";  incluye 'index.tmpl.php';

Paso 11 - Cargar archivos con Uploadify


Hemos escrito toda la funcionalidad del lado del servidor para nuestra pequeña aplicación web. Pero ahora, necesitamos manejar el proceso de front-end de cargar múltiples archivos a nuestro subidas / directorio. Para ello, aprovecharemos el práctico Uploadify..

"Uploadify es un complemento de jQuery que integra una utilidad de carga de archivos múltiples totalmente personalizable en su sitio web. Utiliza una mezcla de Javascript, ActionScript y cualquier lenguaje del lado del servidor para crear dinámicamente una instancia sobre cualquier elemento DOM en una página".

Descargar

El primer paso, al integrar Uploadify, es descargar los archivos necesarios. Se pueden obtener aquí. Cambie el nombre de la carpeta descargada a "uploadify" y colóquela dentro de la raíz del directorio de su proyecto.

Referencias de guiones

A continuación, necesitamos hacer referencia a los archivos necesarios desde nuestro punto de vista. Volver a index.tmpl.php, Y, justo antes del cierre. cuerpo etiqueta, adjuntar

    

Aquí, hacemos referencia a la última versión de jQuery, swfobject, el script central de Uploadify y nuestro propio archivo scripts.js (puede crear ese archivo ahora).

Scripts.js

Ahora activemos Uploadify.

 (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 () // todos los archivos terminaron de cargar la ubicación = "index.php? uploads = complete";);) ();

Activar Uploadify es tan simple como llamar a un método. Recuerda, Uploadify es solo un complemento impresionante de jQuery. Este método acepta muchos parámetros opcionales. Te animo a que los mires aquí. Para nuestras necesidades particulares, solo requerimos un puñado.

  • cargador El camino a la swf archivo que maneja el botón de enviar
  • guión: El camino hacia uploadify.php
  • cancelImg: El camino al botón de cancelar. (Se proporciona uno por defecto)
  • carpeta: La ruta a la carpeta donde se almacenarán los archivos cargados
  • auto: Un booleano, que indica si las cargas deben realizarse automáticamente..
  • multi: ¿Se permiten múltiples cargas de archivos??
  • wmode: Establezca esto en transparente para asegurarse de que no haya problemas de tipo "índice z", donde el botón se muestra en un menú desplegable, o algo similar.
  • buttonTxt: ¿Qué debería decir el botón de enviar??
  • tamaño límite: ¿Cuál es el tamaño máximo de archivo que aceptaremos??
  • onAllComplete: Este método se ejecutará cuando todos los archivos hayan terminado de cargarse. En nuestro caso, estamos recargando la página, y estamos pasando el subidas = completado param en la cadena de consulta.

¡Deberias hacer eso! Solo asegúrate de llamar a nuestro subir función en la parte inferior de scripts.js.

 myUploadr.uploadify ();

Este código aplicará el botón personalizado a su formulario y también manejará la lógica de cargar y transferir sus archivos a la carpeta necesaria..





Paso 12 - Visualización de los resultados

En este punto, hemos escrito la mayor parte de nuestra lógica. Pero hay una última tarea que tenemos que terminar. ¿Recuerdas cuando escribimos la lógica que manejaba las cargas en nuestra cuenta S3? Almacenamos los enlaces en un formación, llamado $ filesArr.

Cuando nuestra forma se carga, debemos determinar si esto formación existe y no está vacío. Si ese es el caso, los archivos ya se han subido, en cuyo caso solo tenemos que mostrar enlaces a cada activo cargado.

Volver a index.tmpl.php, y, justo debajo de la forma primaria, agregue lo siguiente:

  

Enlaces a archivos subidos

    $ ruta):?>
  • ">

Este bit de código primero determina si $ filesArr existe Si lo hace, entonces contiene tanto el nombre como el enlace a cada archivo cargado. Para mostrar esos enlaces, el proceso es tan simple como filtrar a través de cada elemento de la matriz y hacer eco de una etiqueta de anclaje, que enlaza con el archivo asociado.



Terminación

¡Deberias hacer eso! Ahora que toda la funcionalidad está fuera del camino, su próximo paso es adaptar la página a sus necesidades específicas. Podríamos cubrir eso, pero está definitivamente fuera del alcance de este tutorial. Usa tu imaginación - esto es lo que terminé con.


Gracias por leer y avisarme si tiene alguna pregunta. Si partes del tutorial escrito te confundieron, asegúrate de ver el screencast también!