Mam przesłane awatary użytkowników do magazynu Laravel. Jak mogę uzyskać do nich dostęp i wyświetlić je w widoku?
Serwer wskazuje na wszystkie żądania /public
, więc jak mogę je wyświetlić, jeśli znajdują się w /storage
folderze?
Mam przesłane awatary użytkowników do magazynu Laravel. Jak mogę uzyskać do nich dostęp i wyświetlić je w widoku?
Serwer wskazuje na wszystkie żądania /public
, więc jak mogę je wyświetlić, jeśli znajdują się w /storage
folderze?
Odpowiedzi:
Najlepszym rozwiązaniem jest utworzenie dowiązania symbolicznego jak @SlateEntropy bardzo dobrze wskazał w odpowiedzi poniżej . Aby w tym pomóc, od wersji 5.3 Laravel zawiera polecenie, które sprawia, że jest to niezwykle łatwe:
php artisan storage:link
To tworzy dla Ciebie link symboliczny od public/storage
do storage/app/public
i to wszystko. Teraz do każdego pliku /storage/app/public
można uzyskać dostęp za pośrednictwem linku takiego jak:
http://somedomain.com/storage/image.jpg
Jeśli z jakiegoś powodu nie możesz tworzyć dowiązań symbolicznych (może korzystasz z hostingu współdzielonego itp.) Lub chcesz zabezpieczyć niektóre pliki za pewną logiką kontroli dostępu, istnieje alternatywa posiadania specjalnej trasy, która czyta i służy obrazowi. Na przykład prosta trasa zamknięcia, taka jak ta:
Route::get('storage/{filename}', function ($filename)
{
$path = storage_path('public/' . $filename);
if (!File::exists($path)) {
abort(404);
}
$file = File::get($path);
$type = File::mimeType($path);
$response = Response::make($file, 200);
$response->header("Content-Type", $type);
return $response;
});
Możesz teraz uzyskać dostęp do swoich plików tak samo, jak gdybyś miał łącze symboliczne:
http://somedomain.com/storage/image.jpg
Jeśli korzystasz z interwencyjnej biblioteki obrazów , możesz użyć jej wbudowanej response
metody, aby uczynić rzeczy bardziej zwięzłymi:
Route::get('storage/{filename}', function ($filename)
{
return Image::make(storage_path('public/' . $filename))->response();
});
OSTRZEŻENIE
Pamiętaj, że ręcznie obsługując pliki, ponosisz spadek wydajności , ponieważ przechodzisz przez cały cykl życia żądania Laravel, aby odczytać i wysłać zawartość pliku, co jest znacznie wolniejsze niż obsługa serwera HTTP.
public
katalogu. W ten sposób unikniesz konieczności tworzenia odpowiedzi obrazu, którą serwer HTTP mógłby obsłużyć znacznie szybciej.
Jedną z opcji byłoby utworzenie dowiązania symbolicznego między podfolderem w katalogu magazynu a katalogiem publicznym.
Na przykład
ln -s /path/to/laravel/storage/avatars /path/to/laravel/public/avatars
Jest to również metoda stosowana przez Envoyer , menedżera wdrożeń zbudowanego przez Taylora Otwella, dewelopera Laravel.
storage
publicznie, zazwyczaj awatary nie wymagają żadnej kontroli dostępu. Jeśli żadne zabezpieczenia nie są wymagane, użycie jakiegokolwiek oprogramowania pośredniego lub trasy jest po prostu zmarnowanym uderzeniem w zasoby. Warto również zauważyć, ponieważ Laravel 5.2 istnieje oddzielny plik „dysk” dla plików publicznych ( laravel.com/docs/5.2/filesystem ) przy użyciu dowiązań symbolicznych.
Zgodnie z dokumentacją Laravel 5.2, Twoje publicznie dostępne pliki powinny być umieszczone w katalogu
storage/app/public
Aby udostępnić je w Internecie, należy utworzyć łącze symboliczne od public/storage
do storage/app/public
.
ln -s /path/to/laravel/storage/app/public /path/to/laravel/public/storage
Teraz możesz utworzyć w swoim widoku adresy URL do plików przy użyciu pomocnika zasobów:
echo asset('storage/file.txt');
Jeśli korzystasz z systemu Windows, możesz uruchomić to polecenie w cmd:
mklink /j /path/to/laravel/public/avatars /path/to/laravel/storage/avatars
z: http://www.sevenforums.com/tutorials/278262-mklink-create-use-links-windows.html
Przede wszystkim musisz utworzyć dowiązanie symboliczne do katalogu przechowywania za pomocą polecenia artisan
php artisan storage:link
Następnie w dowolnym widoku możesz uzyskać dostęp do obrazu za pomocą pomocnika adresu URL w ten sposób.
url('storage/avatars/image.png');
Dobrze jest zapisać wszystkie prywatne obrazy i dokumenty w katalogu przechowywania, wtedy będziesz mieć pełną kontrolę nad plikiem ether, możesz zezwolić określonemu typowi użytkownika na dostęp do pliku lub ograniczyć.
Utwórz trasę / docs i wskaż dowolną metodę kontrolera:
public function docs() {
//custom logic
//check if user is logged in or user have permission to download this file etc
return response()->download(
storage_path('app/users/documents/4YPa0bl0L01ey2jO2CTVzlfuBcrNyHE2TV8xakPk.png'),
'filename.png',
['Content-Type' => 'image/png']
);
}
Po trafieniu localhost:8000/docs
plik zostanie pobrany, jeśli taki istnieje.
Plik musi znajdować się w root/storage/app/users/documents
katalogu zgodnie z powyższym kodem, na którym został przetestowany Laravel 5.4
.
Jeśli chcesz załadować niewielką liczbę prywatnych obrazów, możesz zakodować obrazy do base64 i wywołać je <img src="{{$image_data}}">
bezpośrednio:
$path = image.png
$full_path = Storage::path($path);
$base64 = base64_encode(Storage::get($path));
$image_data = 'data:'.mime_content_type($full_path) . ';base64,' . $base64;
Wspomniałem o prywatnych, ponieważ powinieneś używać tych metod tylko wtedy, gdy nie chcesz przechowywać obrazów publicznie dostępnych przez url, zamiast tego musisz zawsze używać standardowego sposobu (przechowywanie linków / folder publiczny i serwowanie obrazów z serwerem HTTP).
Uważaj na kodowanie, aby base64()
mieć dwie ważne wady:
Jeśli używasz php, po prostu użyj funkcji linku symbolicznego php, na przykład:
symlink('/home/username/projectname/storage/app/public', '/home/username/public_html/storage')
zmień nazwę użytkownika i nazwę projektu na właściwe nazwy.
bez nazwy witryny
{{Storage::url($photoLink)}}
jeśli chcesz dodać do niego nazwę witryny, przykład, aby dołączyć do plików API JSON
public function getPhotoFullLinkAttribute()
{
return env('APP_URL', false).Storage::url($this->attributes['avatar']) ;
}
Jeśli jesteś podobny do mnie i jakoś masz pełne ścieżki do plików (zrobiłem trochę dopasowywania wzorców glob () na wymaganych zdjęciach, więc w zasadzie kończy się na pełnych ścieżkach plików), a twoja konfiguracja pamięci jest dobrze połączona (tj. mam ciąg storage/app/public/
), możesz użyć mojego małego brudnego hacka poniżej: p)
public static function hackoutFileFromStorageFolder($fullfilePath) {
if (strpos($fullfilePath, 'storage/app/public/')) {
$fileParts = explode('storage/app/public/', $fullfilePath);
if( count($fileParts) > 1){
return $fileParts[1];
}
}
return '';
}
Jeśli dysk „lokalny” nie działa, spróbuj tego:
'default' => env('FILESYSTEM_DRIVER', 'public'),
zproject_folder/config/filesystem.php
php artisan config:clear
php artisan storage:link
Aby uzyskać adres URL przesłanego obrazu, możesz użyć tego Storage::url('iamge_name.jpg');