Almacenamiento de archivos

  • Introducción
  • Configuración
    • El controlador local
    • El disco público
    • Requisitos previos del controlador
    • .

    • Caché
  • Obtención de instancias de disco
  • Recuperación de archivos
    • Descarga de archivos
    • Las URL de los archivos
    • Metadatos de los archivos
  • Almacenamiento de archivos
    • Cargas de archivos
    • Visibilidad de archivos
  • Borrar archivos
  • Directorios
  • Personalizados Filesystems

Introducción

Laravel proporciona una potente abstracción del sistema de archivos gracias al maravilloso paquete Flysystem PHP de Frank de Jonge. La integración de Laravel con Flysystem proporciona controladores sencillos para trabajar con sistemas de archivos locales, SFTP y Amazon S3. Incluso mejor, es increíblemente sencillo cambiar entre estas opciones de almacenamiento entre tu máquina de desarrollo local y el servidor de producción, ya que la API sigue siendo la misma para cada sistema.

Configuración

El archivo de configuración del sistema de archivos de Laravel se encuentra en config/filesystems.php. Dentro de este archivo, usted puede configurar todos sus «discos» del sistema de archivos. Cada disco representa un controlador de almacenamiento particular y una ubicación de almacenamiento. Las configuraciones de ejemplo para cada controlador soportado se incluyen en el archivo de configuración para que pueda modificar la configuración para reflejar sus preferencias de almacenamiento y credenciales.

El controlador local interactúa con los archivos almacenados localmente en el servidor que ejecuta la aplicación Laravel mientras que el controlador s3 se utiliza para escribir en el servicio de almacenamiento en la nube S3 de Amazon.

{tip} Puede configurar tantos discos como desee e incluso puede tener varios discos que utilicen el mismo controlador.

El controlador local

Cuando se utiliza el controlador local, todas las operaciones de archivo son relativas al directorio root definido en su archivo de configuración filesystems. Por defecto, este valor se establece en el directorio storage/app. Por lo tanto, el siguiente método escribiría en storage/app/example.txt:

use Illuminate\Support\Facades\Storage;Storage::disk('local')->put('example.txt', 'Contents');

El disco público

El disco public incluido en el archivo de configuración filesystems de su aplicación está destinado a los archivos que van a ser de acceso público. Por defecto, el disco public utiliza el controlador local y almacena sus archivos en storage/app/public.

Para que estos archivos sean accesibles desde la web, debe crear un enlace simbólico desde public/storage a storage/app/public. Utilizando esta convención de carpetas mantendrá sus archivos accesibles al público en un directorio que puede ser fácilmente compartido a través de despliegues cuando se utilizan sistemas de despliegue sin tiempo de inactividad como Envoyer.

Para crear el enlace simbólico, puede utilizar el comando storage:link de Artisan:

php artisan storage:link

Una vez que se ha almacenado un archivo y se ha creado el enlace simbólico, puede crear una URL a los archivos utilizando el ayudante asset:

echo asset('storage/file.txt');

Puede configurar enlaces simbólicos adicionales en su archivo de configuración filesystems. Cada uno de los enlaces configurados se creará cuando ejecute el comando storage:link:

'links' => ,

Requisitos previos del controlador

Paquetes de Composer

Antes de utilizar los controladores S3 o SFTP, deberá instalar el paquete correspondiente a través del gestor de paquetes de Composer:

  • Amazon S3: league/flysystem-aws-s3-v3 ~1.0
  • SFTP: league/flysystem-sftp ~1.0

Además, puede optar por instalar un adaptador en caché para aumentar el rendimiento:

  • CachedAdapter: league/flysystem-cached-adapter ~1.0

Configuración del controlador S3

La información de configuración del controlador S3 se encuentra en su archivo de configuración config/filesystems.php. Este archivo contiene una matriz de configuración de ejemplo para un controlador S3. Usted es libre de modificar esta matriz con su propia configuración y credenciales de S3. Para mayor comodidad, estas variables de entorno coinciden con la convención de nomenclatura utilizada por la CLI de AWS.

Configuración del controlador FTP

Las integraciones Flysystem de Laravel funcionan muy bien con FTP; sin embargo, no se incluye una configuración de ejemplo con el archivo de configuración filesystems.php por defecto del framework. Si necesita configurar un sistema de archivos FTP, puede utilizar el siguiente ejemplo de configuración:

'ftp' => ,

SFTP Driver Configuration

Las integraciones Flysystem de Laravel funcionan muy bien con SFTP; sin embargo, no se incluye una configuración de ejemplo con el fichero de configuración filesystems.php por defecto del framework. Si necesita configurar un sistema de archivos SFTP, puede utilizar el siguiente ejemplo de configuración:

'sftp' => ,

Caching

Para habilitar el almacenamiento en caché de un disco determinado, puede añadir una directiva cache a las opciones de configuración del disco. La opción cache debe ser un array de opciones de caché que contenga el nombre disk, el tiempo expire en segundos, y la caché prefix:

's3' => ,],

Obtención de instancias de disco

La fachada Storage puede utilizarse para interactuar con cualquiera de sus discos configurados. Por ejemplo, puede utilizar el método put de la fachada para almacenar un avatar en el disco predeterminado. Si llama a los métodos de la fachada Storage sin llamar primero al método disk, el método se pasará automáticamente al disco por defecto:

use Illuminate\Support\Facades\Storage;Storage::put('avatars/1', $content);

Si su aplicación interactúa con múltiples discos, puede utilizar el método disk en la fachada Storage para trabajar con los archivos en un disco en particular:

Storage::disk('s3')->put('avatars/1', $content);

Recuperación de archivos

El método get puede ser utilizado para recuperar el contenido de un archivo. El método devolverá el contenido en bruto del archivo. Recuerde que todas las rutas de archivos deben especificarse en relación con la ubicación «raíz» del disco:

$contents = Storage::get('file.jpg');

El método exists puede utilizarse para determinar si un archivo existe en el disco:

if (Storage::disk('s3')->exists('file.jpg')) { // ...}

El método missing puede usarse para determinar si un archivo falta en el disco:

if (Storage::disk('s3')->missing('file.jpg')) { // ...}

Descargar archivos

El método download puede usarse para generar una respuesta que obligue al navegador del usuario a descargar el archivo en la ruta dada. El método download acepta un nombre de archivo como segundo argumento del método, que determinará el nombre de archivo que verá el usuario que descargue el archivo. Por último, puede pasar una matriz de cabeceras HTTP como tercer argumento al método:

return Storage::download('file.jpg');return Storage::download('file.jpg', $name, $headers);

Las URL de los archivos

Puede utilizar el método url para obtener la URL de un archivo determinado. Si usted está usando el controlador local, esto típicamente sólo preagrega /storage a la ruta dada y devuelve una URL relativa al archivo. Si se utiliza el controlador s3, se devolverá la URL remota completa:

use Illuminate\Support\Facades\Storage;$url = Storage::url('file.jpg');

Cuando se utiliza el controlador local, todos los archivos que deben ser accesibles públicamente deben colocarse en el directorio storage/app/public. Además, debe crear un enlace simbólico en public/storage que apunte al directorio storage/app/public.

{nota} Cuando se utiliza el controlador local, el valor de retorno de url no está codificado como URL. Por esta razón, se recomienda siempre almacenar sus archivos utilizando nombres que crearán URLs válidos.

URLs temporales

Usando el método temporaryUrl, puede crear URLs temporales a los archivos almacenados utilizando el controlador s3. Este método acepta una ruta y una instancia DateTime que especifica cuándo debe expirar la URL:

use Illuminate\Support\Facades\Storage;$url = Storage::temporaryUrl( 'file.jpg', now()->addMinutes(5));

Si necesita especificar parámetros adicionales de solicitud de S3, puede pasar la matriz de parámetros de solicitud como tercer argumento al método temporaryUrl:

$url = Storage::temporaryUrl( 'file.jpg', now()->addMinutes(5), );

Personalización del host de la URL

Si quieres predefinir el host para las URLs generadas usando la fachada Storage, puedes añadir una opción url al array de configuración del disco:

'public' => ,

Metadatos de los ficheros

Además de leer y escribir ficheros, Laravel también puede proporcionar información sobre los propios ficheros. Por ejemplo, el método size puede usarse para obtener el tamaño de un archivo en bytes:

use Illuminate\Support\Facades\Storage;$size = Storage::size('file.jpg');

El método lastModified devuelve la marca de tiempo UNIX de la última vez que se modificó el archivo:

$time = Storage::lastModified('file.jpg');

Rutas de archivos

Puedes usar el método path para obtener la ruta de un archivo determinado. Si está utilizando el controlador local, esto devolverá la ruta absoluta al archivo. Si está utilizando el controlador s3, este método devolverá la ruta relativa al archivo en el cubo S3:

use Illuminate\Support\Facades\Storage;$path = Storage::path('file.jpg');

Almacenamiento de archivos

El método put puede utilizarse para almacenar el contenido de los archivos en un disco. También puede pasar un PHP resource al método put, que utilizará el soporte de flujo subyacente de Flysystem. Recuerde que todas las rutas de archivos deben especificarse en relación con la ubicación «raíz» configurada para el disco:

use Illuminate\Support\Facades\Storage;Storage::put('file.jpg', $contents);Storage::put('file.jpg', $resource);

Streaming automático

El streaming de archivos al almacenamiento ofrece un uso de memoria significativamente reducido. Si quieres que Laravel gestione automáticamente el streaming de un archivo determinado a su ubicación de almacenamiento, puedes utilizar el método putFile o putFileAs. Este método acepta una instancia Illuminate\Http\File o Illuminate\Http\UploadedFile y automáticamente transmitirá el archivo a la ubicación deseada:

use Illuminate\Http\File;use Illuminate\Support\Facades\Storage;// Automatically generate a unique ID for filename...$path = Storage::putFile('photos', new File('/path/to/photo'));// Manually specify a filename...$path = Storage::putFileAs('photos', new File('/path/to/photo'), 'photo.jpg');

Hay algunas cosas importantes a tener en cuenta sobre el método putFile. Tenga en cuenta que sólo especificamos un nombre de directorio y no un nombre de archivo. Por defecto, el método putFile generará un ID único que servirá como nombre de archivo. La extensión del archivo se determinará examinando el tipo MIME del archivo. El método putFile devolverá la ruta del archivo para que pueda almacenar la ruta, incluyendo el nombre del archivo generado, en su base de datos.

Los métodos putFile y putFileAs también aceptan un argumento para especificar la «visibilidad» del archivo almacenado. Esto es particularmente útil si está almacenando el archivo en un disco en la nube como Amazon S3 y desea que el archivo sea accesible públicamente a través de URLs generadas:

Storage::putFile('photos', new File('/path/to/photo'), 'public');

Preparación &Aplicación a archivos

Los métodos prepend y append le permiten escribir al principio o al final de un archivo:

Storage::prepend('file.log', 'Prepended Text');Storage::append('file.log', 'Appended Text');

Copiar & Mover archivos

El método copy puede utilizarse para copiar un archivo existente a una nueva ubicación en el disco, mientras que el método move puede utilizarse para renombrar o mover un archivo existente a una nueva ubicación:

Storage::copy('old/file.jpg', 'new/file.jpg');Storage::move('old/file.jpg', 'new/file.jpg');

Subidas de archivos

En las aplicaciones web, uno de los casos de uso más comunes para el almacenamiento de archivos es el almacenamiento de archivos subidos por el usuario, como fotos y documentos. Laravel hace que sea muy fácil de almacenar los archivos subidos utilizando el método store en una instancia de archivo subido. Llama al método store con la ruta en la que deseas almacenar el archivo subido:

<?phpnamespace App\Http\Controllers;use App\Http\Controllers\Controller;use Illuminate\Http\Request;class UserAvatarController extends Controller{ /** * Update the avatar for the user. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function update(Request $request) { $path = $request->file('avatar')->store('avatars'); return $path; }}

Hay algunas cosas importantes a tener en cuenta en este ejemplo. Observe que sólo especificamos un nombre de directorio, no un nombre de archivo. Por defecto, el método store generará un ID único que servirá como nombre de archivo. La extensión del archivo se determinará examinando el tipo MIME del archivo. El método store devolverá la ruta del archivo para que pueda almacenar la ruta, incluyendo el nombre del archivo generado, en su base de datos.

También puede llamar al método putFile de la fachada Storage para realizar la misma operación de almacenamiento de archivos que el ejemplo anterior:

$path = Storage::putFile('avatars', $request->file('avatar'));

Especificación de un nombre de archivo

Si no desea que se asigne automáticamente un nombre de archivo a su archivo almacenado, puede utilizar el método storeAs, que recibe la ruta, el nombre de archivo y el disco (opcional) como argumentos:

$path = $request->file('avatar')->storeAs( 'avatars', $request->user()->id);

También puede utilizar el método putFileAs en la fachada Storage, que realizará la misma operación de almacenamiento de archivos que el ejemplo anterior:

$path = Storage::putFileAs( 'avatars', $request->file('avatar'), $request->user()->id);

{nota} Los caracteres unicode no imprimibles y no válidos se eliminarán automáticamente de las rutas de los archivos. Por lo tanto, es posible que desee sanear sus rutas de archivo antes de pasarlos a los métodos de almacenamiento de archivos de Laravel. Las rutas de los archivos se normalizan utilizando el método League\Flysystem\Util::normalizePath.

Especificando un disco

Por defecto, el método store de este archivo subido utilizará su disco por defecto. Si desea especificar otro disco, pase el nombre del disco como segundo argumento al método store:

$path = $request->file('avatar')->store( 'avatars/'.$request->user()->id, 's3');

Si está utilizando el método storeAs, puede pasar el nombre del disco como tercer argumento al método:

$path = $request->file('avatar')->storeAs( 'avatars', $request->user()->id, 's3');

Otra información del archivo cargado

Si desea obtener el nombre original del archivo cargado, puede hacerlo utilizando el método getClientOriginalName:

$name = $request->file('avatar')->getClientOriginalName();

Se puede utilizar el método extension para obtener la extensión del archivo subido:

$extension = $request->file('avatar')->extension();

Visibilidad de los archivos

En la integración Flysystem de Laravel, la «visibilidad» es una abstracción de los permisos de los archivos en múltiples plataformas. Los archivos pueden ser declarados public o private. Cuando un archivo se declara public, se está indicando que el archivo debe ser generalmente accesible a los demás. Por ejemplo, cuando se utiliza el controlador S3, puede recuperar las URL de los archivos public.

Se puede establecer la visibilidad al escribir el archivo a través del método put:

use Illuminate\Support\Facades\Storage;Storage::put('file.jpg', $contents, 'public');

Si el archivo ya ha sido almacenado, su visibilidad puede ser recuperada y establecida a través de los métodos getVisibility y setVisibility:

$visibility = Storage::getVisibility('file.jpg');Storage::setVisibility('file.jpg', 'public');

Cuando se interactúa con archivos subidos, se pueden utilizar los métodos storePublicly y storePubliclyAs para almacenar el archivo subido con public visibilidad:

$path = $request->file('avatar')->storePublicly('avatars', 's3');$path = $request->file('avatar')->storePubliclyAs( 'avatars', $request->user()->id, 's3');

Archivos Locales & Visibilidad

Cuando se utiliza el controlador local, public visibilidad se traduce en 0755 permisos para los directorios y 0644 permisos para los archivos. Puede modificar las asignaciones de permisos en el archivo de configuración filesystems de su aplicación:

'local' => , 'dir' => , ],],

Eliminación de archivos

El método delete acepta un solo nombre de archivo o una matriz de archivos para eliminar:

use Illuminate\Support\Facades\Storage;Storage::delete('file.jpg');Storage::delete();

Si es necesario, puede especificar el disco del que debe borrarse el archivo:

use Illuminate\Support\Facades\Storage;Storage::disk('s3')->delete('path/file.jpg');

Directorios

Obtener todos los archivos de un directorio

El método files devuelve una matriz de todos los archivos de un directorio determinado. Si desea obtener una lista de todos los archivos dentro de un directorio determinado, incluyendo todos los subdirectorios, puede utilizar el método allFiles:

use Illuminate\Support\Facades\Storage;$files = Storage::files($directory);$files = Storage::allFiles($directory);

Obtener todos los directorios dentro de un directorio

El método directories devuelve una matriz de todos los directorios dentro de un directorio determinado. Además, puede utilizar el método allDirectories para obtener una lista de todos los directorios dentro de un directorio dado y todos sus subdirectorios:

$directories = Storage::directories($directory);$directories = Storage::allDirectories($directory);

Crear un directorio

El método makeDirectorycreará el directorio dado, incluyendo cualquier subdirectorio necesario:

Storage::makeDirectory($directory);

Borrar un directorio

Por último, el método deleteDirectory se puede utilizar para eliminar un directorio y todos sus archivos:

Storage::deleteDirectory($directory);

Sistemas de archivos personalizados

La integración de Flysystem de Laravel proporciona soporte para varios «drivers» fuera de la caja; sin embargo, Flysystem no se limita a estos y tiene adaptadores para muchos otros sistemas de almacenamiento. Puedes crear un controlador personalizado si quieres utilizar uno de estos adaptadores adicionales en tu aplicación Laravel.

Para definir un sistema de archivos personalizado necesitarás un adaptador Flysystem. Vamos a añadir un adaptador de Dropbox mantenido por la comunidad a nuestro proyecto:

composer require spatie/flysystem-dropbox

Luego, puedes registrar el controlador dentro del método boot de uno de los proveedores de servicios de tu aplicación. Para lograr esto, debes usar el método extend de la fachada Storage:

<?phpnamespace App\Providers;use Illuminate\Support\Facades\Storage;use Illuminate\Support\ServiceProvider;use League\Flysystem\Filesystem;use Spatie\Dropbox\Client as DropboxClient;use Spatie\FlysystemDropbox\DropboxAdapter;class AppServiceProvider extends ServiceProvider{ /** * Register any application services. * * @return void */ public function register() { // } /** * Bootstrap any application services. * * @return void */ public function boot() { Storage::extend('dropbox', function ($app, $config) { $client = new DropboxClient( $config ); return new Filesystem(new DropboxAdapter($client)); }); }}

El primer argumento del método extend es el nombre del controlador y el segundo es un cierre que recibe las variables $app y $config. El cierre debe devolver una instancia de League\Flysystem\Filesystem. La variable $config contiene los valores definidos en config/filesystems.php para el disco especificado.

Una vez que haya creado y registrado el proveedor de servicios de la extensión, puede utilizar el controlador dropbox en su archivo de configuración config/filesystems.php.

Leave a Reply