Digging Deeper - 06. File Storage
Einführung
Laravel bietet eine mächtige Dateisystem-Abstraktion dank des wunderbaren Flysystem PHP-Pakets von Frank de Jonge. Die Laravel Flysystem Integration bietet einfach zu benutzende Treiber für die Arbeit mit lokalen Dateisystemen, Amazon S3 und Rackspace Cloud Storage. Noch besser, es ist erstaunlich einfach, zwischen diesen Speicheroptionen zu wechseln, da die API für jedes System gleich bleibt.
more themes about Digging Deeper [TaskID] - Click for open
Configuration
Die Konfigurationsdatei für das Dateisystem befindet sich in der Datei config/filesystems.php. In dieser Datei können Sie alle Ihre "Platten" konfigurieren. Jede Platte repräsentiert einen bestimmten Speichertreiber und Speicherort. Beispielkonfigurationen für jeden unterstützten Treiber sind in der Konfigurationsdatei enthalten. Passen Sie die Konfiguration also an Ihre Speicherpräferenzen und Ihre Zugangsdaten an.
Sie können so viele Datenträger konfigurieren, wie Sie möchten, und sogar mehrere Datenträger haben, die denselben Treiber verwenden.
The Public Disk
Die public Festplatte ist für Dateien gedacht, die öffentlich zugänglich sein werden. Standardmäßig verwendet der public Datenträger den local Treiber und speichert diese Dateien in storage/app/public. Um sie über das Web zugänglich zu machen, sollten Sie einen symbolischen Link von public/storage zu storage/app/public erstellen. Diese Konvention hält Ihre öffentlich zugänglichen Dateien in einem Verzeichnis, das bei der Verwendung von Zero-Downtime-Bereitstellungssystemen wie Envoyer einfach über die gesamte Bereitstellung hinweg gemeinsam genutzt werden kann.
Um den symbolischen Link zu erstellen, können Sie den Befehl storage:link Artisan verwenden:
php artisan storage:link
Sobald eine Datei gespeichert und der symbolische Link erstellt wurde, können Sie mit dem asset-Helper eine URL zu den Dateien erstellen:
echo asset('storage/file.txt');
The Local Driver
Wenn Sie den local Treiber verwenden, sind alle Dateioperationen relativ zum root Directory, das in Ihrer Konfigurationsdatei des Dateisystems definiert ist. Standardmäßig ist dieser Wert auf das Verzeichnis storage/app gesetzt. Daher würde die folgende Methode eine Datei in storage/app/file.txt speichern:
Storage::disk('local')->put('file.txt', 'Contents');
Permissions
Die public Sichtbarkeit beträgt 0755 für Verzeichnisse und 0644 für Dateien. Sie können die Berechtigungszuordnungen in Ihrer Dateisystem-Konfigurationsdatei ändern:
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
'permissions' => [
'file' => [
'public' => 0664,
'private' => 0600,
],
'dir' => [
'public' => 0775,
'private' => 0700,
],
],
],
Driver Prerequisites
Composer Packages
Bevor Sie die SFTP-, S3- oder Rackspace-Treiber verwenden können, müssen Sie das entsprechende Paket über den Composer installieren:
- SFTP: league/flysystem-sftp ~1.0
- Amazon S3: league/flysystem-aws-s3-v3 ~1.0
- Rackspace: league/flysystem-rackspace ~1.0
Ein absolutes Muss für die Leistung ist die Verwendung eines Cache-adapters. Hierfür benötigen Sie ein zusätzliches Paket:
- CachedAdapter: league/flysystem-cached-adapter ~1.0
S3 Driver Configuration
Die Informationen zur Konfiguration des S3-Treibers finden Sie in Ihrer Konfigurationsdatei config/filesystems.php. Diese Datei enthält ein Beispiel-Konfigurationsarray für einen S3-Treiber. Es steht Ihnen frei, dieses Array mit Ihrer eigenen S3-Konfiguration und Ihren Zugangsdaten zu modifizieren. Der Einfachheit halber entsprechen diese Umgebungsvariablen der von der AWS CLI verwendeten Namenskonvention.
FTP Driver Configuration
Laravel's Flysystem Integrationen funktionieren großartig mit FTP; allerdings ist eine Beispielkonfiguration nicht in der Standardkonfigurationsdatei filesystems.php des Frameworks enthalten. Wenn Sie ein FTP-Dateisystem konfigurieren müssen, können Sie die folgende Beispielkonfiguration verwenden:
'ftp' => [
'driver' => 'ftp',
'host' => 'ftp.example.com',
'username' => 'your-username',
'password' => 'your-password',
// Optional FTP Settings...
// 'port' => 21,
// 'root' => '',
// 'passive' => true,
// 'ssl' => true,
// 'timeout' => 30,
],
SFTP Driver Configuration
Laravel's Flysystem Integrationen funktionieren großartig mit SFTP; eine Beispielkonfiguration ist jedoch nicht in der Standardkonfigurationsdatei filesystems.php des Frameworks enthalten. Wenn Sie ein SFTP-Dateisystem konfigurieren müssen, können Sie die folgende Beispielkonfiguration verwenden:
'sftp' => [
'driver' => 'sftp',
'host' => 'example.com',
'username' => 'your-username',
'password' => 'your-password',
// Settings for SSH key based authentication...
// 'privateKey' => '/path/to/privateKey',
// 'password' => 'encryption-password',
// Optional SFTP Settings...
// 'port' => 22,
// 'root' => '',
// 'timeout' => 30,
],
Rackspace Driver Configuration
Laravel's Flysystem Integrationen funktionieren großartig mit Rackspace; allerdings ist eine Beispielkonfiguration nicht in der Standardkonfigurationsdatei filesystems.php des Frameworks enthalten. Wenn Sie ein Rackspace-Dateisystem konfigurieren müssen, können Sie die folgende Beispielkonfiguration verwenden:
'rackspace' => [
'driver' => 'rackspace',
'username' => 'your-username',
'key' => 'your-key',
'container' => 'your-container',
'endpoint' => 'https://identity.api.rackspacecloud.com/v2.0/',
'region' => 'IAD',
'url_type' => 'publicURL',
],
Caching
Um das Caching für eine bestimmte Festplatte zu aktivieren, können Sie eine cache-Direktive zu den Konfigurationsoptionen der Festplatte hinzufügen. Die cache-Option sollte ein Array von Cache-Optionen sein, das den disk name, die expire time in Sekunden und das Cache-Prefix enthält:
's3' => [
'driver' => 's3',
// Other Disk Options...
'cache' => [
'store' => 'memcached',
'expire' => 600,
'prefix' => 'cache-prefix',
],
],
Obtaining Disk Instances
Die storage-Fassade kann zur Interaktion mit jeder Ihrer konfigurierten Festplatten verwendet werden. Beispielsweise können Sie die put-Methode auf der Fassade verwenden, um einen Avatar auf der Standarddiskette zu speichern. Wenn Sie Methoden auf der storage-Fassade aufrufen, ohne zuvor die disk-Methode aufzurufen, wird der Methodenaufruf automatisch an die Standardplatte übergeben:
use Illuminate\Support\Facades\Storage;
Storage::put('avatars/1', $fileContents);
Wenn Ihre Anwendung mit mehreren Datenträgern interagiert, können Sie die disk-Methode auf der storage-Fassade verwenden, um mit Dateien auf einem bestimmten Datenträger zu arbeiten:
Storage::disk('s3')->put('avatars/1', $fileContents);
Retrieving Files
Die get-Methode kann verwendet werden, um den Inhalt einer Datei abzurufen. Der rohe Stringinhalt der Datei wird von der Methode zurückgegeben. Denken Sie daran, dass alle Dateipfade relativ zu dem für die Festplatte konfigurierten "Root"-Speicherort angegeben werden sollten:
$contents = Storage::get('file.jpg');
Die exists-Methode kann verwendet werden, um festzustellen, ob eine Datei auf der Festplatte existiert:
$exists = Storage::disk('s3')->exists('file.jpg');
Downloading Files
Die download-Methode kann verwendet werden, um eine Antwort zu generieren, die den Browser des Benutzers zwingt, die Datei unter dem angegebenen Pfad herunterzuladen. Die download-Methode akzeptiert einen Dateinamen als zweites Argument der Methode, der den Dateinamen bestimmt, den der Benutzer beim Herunterladen der Datei sieht. Schließlich können Sie ein Array von HTTP-Headern als drittes Argument an die Methode übergeben:
return Storage::download('file.jpg');
return Storage::download('file.jpg', $name, $headers);
File URLs
Sie können die url-Methode verwenden, um die URL für die angegebene Datei zu erhalten. Wenn Sie den local Treiber verwenden, wird dieser normalerweise einfach /storage dem angegebenen Pfad voranstellen und eine relative URL zu der Datei zurückgeben. Wenn Sie den s3- oder rackspace-Treiber verwenden, wird die voll qualifizierte Remote-URL zurückgegeben:
use Illuminate\Support\Facades\Storage;
$url = Storage::url('file.jpg');
Temporary URLs
Für Dateien, die mit dem s3- oder rackspace-Treiber gespeichert werden, können Sie mit der Methode temporaryUrl eine temporäre URL zu einer bestimmten Datei erstellen. Diese Methode akzeptiert einen Pfad und eine DateTime-Instanz, die angeben, wann der URL ablaufen soll:
$url = Storage::temporaryUrl(
'file.jpg', now()->addMinutes(5)
);
Wenn Sie zusätzliche S3-Anforderungsparameter angeben müssen, können Sie das Array der Anforderungsparameter als drittes Argument an die Methode temporaryUrl übergeben:
$url = Storage::temporaryUrl(
'file.jpg',
now()->addMinutes(5),
['ResponseContentType' => 'application/octet-stream']
);
Local URL Host Customization
Wenn Sie den Host für Dateien, die auf einer Festplatte gespeichert sind, mit dem local Treiber vordefinieren möchten, können Sie eine url-Option zum Konfigurationsarray der Festplatte hinzufügen:
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
File Metadata
Zusätzlich zum Lesen und Schreiben von Dateien, kann Laravel auch Informationen über die Dateien selbst liefern. Zum Beispiel kann die size-Methode verwendet werden, um die Größe der Datei in Bytes zu erhalten:
use Illuminate\Support\Facades\Storage;
$size = Storage::size('file.jpg');
Die lastModified-Methodegibt den UNIX-Zeitstempel der letzten Änderung der Datei zurück:
$time = Storage::lastModified('file.jpg');
Storing Files
Die put-Methode kann verwendet werden, um den Inhalt von Rohdaten auf einer Festplatte zu speichern. Sie können auch eine PHP-Ressource an die put-Methode übergeben, die dann Flysystems zugrunde liegende Stream-Unterstützung nutzt. Die Verwendung von Streams wird sehr empfohlen, wenn es sich um große Dateien handelt:
use Illuminate\Support\Facades\Storage;
Storage::put('file.jpg', $contents);
Storage::put('file.jpg', $resource);
Automatic Streaming
Wenn Sie möchten, dass Laravel automatisch das Streaming einer bestimmten Datei an Ihren Speicherort verwaltet, können Sie die putFile oder putFileAs Methode verwenden. Diese Methode akzeptiert entweder eine Illuminate\Http\File oder Illuminate\Http\UploadedFile Instanz und wird die Datei automatisch an den gewünschten Speicherort streamen:
use Illuminate\Http\File;
use Illuminate\Support\Facades\Storage;
// Automatically generate a unique ID for file name...
Storage::putFile('photos', new File('/path/to/photo'));
// Manually specify a file name...
Storage::putFileAs('photos', new File('/path/to/photo'), 'photo.jpg');
Es gibt ein paar wichtige Dinge über die putFile-Methode zu beachten. Beachten Sie, dass wir nur einen Verzeichnisnamen, nicht aber einen Dateinamen angegeben haben. Standardmäßig generiert die putFile-Methode eine eindeutige ID, die als Dateiname dient. Die Dateierweiterung wird durch Untersuchung des MIME-Typs der Datei ermittelt. Der Pfad zu der Datei wird von der putFile-Methode zurückgegeben, so dass Sie den Pfad, einschließlich des generierten Dateinamens, in Ihrer Datenbank speichern können.
Die putFile- und putFileAs-Methoden akzeptieren auch ein Argument, um die "Sichtbarkeit" der gespeicherten Datei festzulegen. Dies ist besonders nützlich, wenn Sie die Datei auf einer Cloud-Disk wie z.B. S3 speichern und möchten, dass die Datei öffentlich zugänglich ist:
Storage::putFile('photos', new File('/path/to/photo'), 'public');
Prepending & Appending To Files
Die Prepend- und Append-Methoden erlauben es Ihnen, an den Anfang oder das Ende einer Datei zu schreiben:
Storage::prepend('file.log', 'Prepended Text');
Storage::append('file.log', 'Appended Text');
Copying & Moving Files
Die copy-Methode kann verwendet werden, um eine vorhandene Datei an einen neuen Ort auf der Festplatte zu kopieren, während die move-Methode verwendet werden kann, um eine vorhandene Datei umzubenennen oder an einen neuen Ort zu verschieben:
Storage::copy('old/file.jpg', 'new/file.jpg');
Storage::move('old/file.jpg', 'new/file.jpg');
File Uploads
In Webanwendungen ist einer der häufigsten Anwendungsfälle für die Speicherung von Dateien das Speichern von vom Benutzer hochgeladenen Dateien wie Profilbildern, Fotos und Dokumenten. Laravel macht es sehr einfach, hochgeladene Dateien mit der store-Methode auf einer hochgeladenen Dateiinstanz zu speichern. Rufen Sie die store-Methode mit dem Pfad auf, unter dem Sie die hochgeladene Datei speichern möchten:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class UserAvatarController extends Controller
{
/**
* Update the avatar for the user.
*
* @param Request $request
* @return Response
*/
public function update(Request $request)
{
$path = $request->file('avatar')->store('avatars');
return $path;
}
}
Es gibt einige wichtige Dinge zu diesem Beispiel zu beachten. Beachten Sie, dass wir nur einen Verzeichnisnamen, nicht aber einen Dateinamen angegeben haben. Standardmäßig generiert die store-Methode eine eindeutige ID, die als Dateiname dient. Die Dateierweiterung wird durch Untersuchung des MIME-Typs der Datei ermittelt. Der Pfad zu der Datei wird von der store-Methode zurückgegeben, so dass Sie den Pfad, einschließlich des generierten Dateinamens, in Ihrer Datenbank speichern können.
Sie können auch die putFile-Methode auf der Storage-Fassade aufrufen, um die gleiche Dateibearbeitung wie im obigen Beispiel durchzuführen:
$path = Storage::putFile('avatars', $request->file('avatar'));
Specifying A File Name
Wenn Sie nicht möchten, dass Ihrer gespeicherten Datei automatisch ein Dateiname zugewiesen wird, können Sie die storeAs-Methode verwenden, die den Pfad, den Dateinamen und den (optionalen) Datenträger als Argumente erhält:
$path = $request->file('avatar')->storeAs(
'avatars', $request->user()->id
);
Sie können auch die putFileAs-Methode auf der Storage-Fassade verwenden, die die gleiche Dateimanipulation wie im obigen Beispiel durchführt:
$path = Storage::putFileAs(
'avatars', $request->file('avatar'), $request->user()->id
);
Specifying A Disk
Standardmäßig wird diese Methode Ihre Standard-Diskette verwenden. Wenn Sie ein anderes Laufwerk angeben möchten, übergeben Sie den Laufwerksnamen als zweites Argument an die store-Methode:
$path = $request->file('avatar')->store(
'avatars/'.$request->user()->id, 's3'
);
File Visibility
In Laravel's Flysystem Integration ist "Sichtbarkeit" eine Abstraktion von Dateiberechtigungen über mehrere Plattformen hinweg. Dateien können entweder als public oder private deklariert werden. Wenn eine Datei als public deklariert wird, geben Sie damit an, dass die Datei generell für andere zugänglich sein soll. Wenn Sie z.B. den S3-Treiber verwenden, können Sie URLs für public Dateien abrufen.
Sie können die Sichtbarkeit beim Setzen der Datei über die put-Methode einstellen:
use Illuminate\Support\Facades\Storage;
Storage::put('file.jpg', $contents, 'public');
Wenn die Datei bereits gespeichert wurde, kann ihre Sichtbarkeit über die Methoden getVisibility und setVisibility abgerufen und eingestellt werden:
$visibility = Storage::getVisibility('file.jpg');
Storage::setVisibility('file.jpg', 'public')
Deleting Files
Die delete-Methode akzeptiert einen einzelnen Dateinamen oder ein Array von Dateien, die von der Festplatte entfernt werden sollen:
use Illuminate\Support\Facades\Storage;
Storage::delete('file.jpg');
Storage::delete(['file.jpg', 'file2.jpg']);
Falls nötig, können Sie den Datenträger angeben, von dem die Datei gelöscht werden soll:
use Illuminate\Support\Facades\Storage;
Storage::disk('s3')->delete('folder_path/file_name.jpg');
Directories
Get All Files Within A Directory
Die files-Methode gibt ein Array aller Dateien in einem bestimmten Verzeichnis zurück. Wenn Sie eine Liste aller Dateien in einem bestimmten Verzeichnis einschließlich aller Unterverzeichnisse erhalten möchten, können Sie die allFiles-Methode verwenden:
use Illuminate\Support\Facades\Storage;
$files = Storage::files($directory);
$files = Storage::allFiles($directory);
Get All Directories Within A Directory
Die directories-Methode gibt ein Array aller Verzeichnisse innerhalb eines gegebenen Verzeichnisses zurück. Zusätzlich können Sie die allDirectories-Methode verwenden, um eine Liste aller Verzeichnisse innerhalb eines gegebenen Verzeichnisses und aller seiner Unterverzeichnisse zu erhalten:
$directories = Storage::directories($directory);
// Recursive...
$directories = Storage::allDirectories($directory);
Create A Directory
Die makeDirectory-Methode erstellt das angegebene Verzeichnis, einschließlich aller benötigten Unterverzeichnisse:
Storage::makeDirectory($directory);
Delete A Directory
Schließlich kann die deleteDirectory-Methode verwendet werden, um ein Verzeichnis und alle seine Dateien zu entfernen:
Storage::deleteDirectory($directory);
Custom Filesystems
Laravel's Flysystem Integration stellt Treiber für mehrere "Treiber" out of the box zur Verfügung; Flysystem ist jedoch nicht auf diese beschränkt und hat Adapter für viele andere Speichersysteme. Sie können einen benutzerdefinierten Treiber erstellen, wenn Sie einen dieser zusätzlichen Adapter in Ihrer Laravel-Anwendung verwenden wollen.
Um das angepasste Dateisystem einzurichten, benötigen Sie einen Flysystem-Adapter. Lassen Sie uns einen von der Gemeinschaft gewarteten Dropbox Adapter zu unserem Projekt hinzufügen:
composer require spatie/flysystem-dropbox
Als nächstes sollten Sie einen Service Provider wie z.B. DropboxServiceProvider anlegen. In der boot-Methode des Providers können Sie die extend-Methode der Storage-Fassade verwenden, um den benutzerdefinierten Treiber zu definieren:
<?php
namespace App\Providers;
use Storage;
use League\Flysystem\Filesystem;
use Illuminate\Support\ServiceProvider;
use Spatie\Dropbox\Client as DropboxClient;
use Spatie\FlysystemDropbox\DropboxAdapter;
class DropboxServiceProvider extends ServiceProvider
{
/**
* Register bindings in the container.
*
* @return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Storage::extend('dropbox', function ($app, $config) {
$client = new DropboxClient(
$config['authorization_token']
);
return new Filesystem(new DropboxAdapter($client));
});
}
}
Das erste Argument der extend-Methode ist der Name des Treibers und das zweite ist ein Closure, das die Variablen $app und $config erhält. Der Resolver Closure muss eine Instanz von League\Flysystem\Filesystem zurückgeben. Die Variable $config enthält die in config/filesystems.php definierten Werte für die angegebene Platte.
Als nächstes müssen Sie den Service Provider in der Konfigurationsdatei config/app.php registrieren:
'providers' => [
// ...
App\Providers\DropboxServiceProvider::class,
];
Nachdem Sie den Service Provider der Erweiterung erstellt und registriert haben, können Sie den Dropbox-Treiber in Ihrer Konfigurationsdatei config/filesystems.php verwenden.