Tenho avatares de usuários carregados no armazenamento do Laravel. Como posso acessá-los e renderizá-los em uma exibição?
O servidor está apontando para todas as solicitações /public
, então como posso mostrá-las se estiverem na /storage
pasta?
Tenho avatares de usuários carregados no armazenamento do Laravel. Como posso acessá-los e renderizá-los em uma exibição?
O servidor está apontando para todas as solicitações /public
, então como posso mostrá-las se estiverem na /storage
pasta?
Respostas:
A melhor abordagem é criar um link simbólico como @SlateEntropy muito bem apontado na resposta abaixo . Para ajudar com isso, desde a versão 5.3, o Laravel inclui um comando que facilita incrivelmente:
php artisan storage:link
Isso cria um link simbólico de public/storage
para storage/app/public
para você e é tudo o que existe. Agora qualquer arquivo /storage/app/public
pode ser acessado através de um link como:
http://somedomain.com/storage/image.jpg
Se, por qualquer motivo, você não puder criar links simbólicos (talvez você esteja em hospedagem compartilhada etc.) ou desejar proteger alguns arquivos atrás de alguma lógica de controle de acesso, existe a alternativa de ter uma rota especial que leia e serve a imagem. Por exemplo, uma rota de fechamento simples como esta:
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;
});
Agora você pode acessar seus arquivos exatamente como faria se tivesse um link simbólico:
http://somedomain.com/storage/image.jpg
Se você estiver usando a Biblioteca de Imagens de Intervenção, poderá usar seu response
método interno para tornar as coisas mais sucintas:
Route::get('storage/{filename}', function ($filename)
{
return Image::make(storage_path('public/' . $filename))->response();
});
AVISO
Lembre-se de que, ao exibir manualmente os arquivos, você está sujeito a uma penalidade de desempenho , porque está passando por todo o ciclo de vida das solicitações do Laravel para ler e enviar o conteúdo do arquivo, o que é consideravelmente mais lento do que o servidor HTTP.
public
diretório. Dessa forma, você evitará a sobrecarga de precisar compor uma resposta de imagem que possa ser tratada muito mais rapidamente pelo servidor HTTP.
Uma opção seria criar um link simbólico entre uma subpasta no diretório de armazenamento e no diretório público.
Por exemplo
ln -s /path/to/laravel/storage/avatars /path/to/laravel/public/avatars
Esse também é o método usado pelo Envoyer , um gerente de implantação criado por Taylor Otwell, desenvolvedor do Laravel.
storage
público, geralmente os avatares não exigem nenhum tipo de controle de acesso. Se nenhuma segurança for necessária, use qualquer tipo de middleware ou rota é apenas um golpe desperdiçado em seus recursos. Também é importante notar que, como o Laravel 5.2, existe um "disco" de arquivo separado para arquivos públicos ( laravel.com/docs/5.2/filesystem ) usando links simbólicos.
De acordo com os documentos do Laravel 5.2, seus arquivos acessíveis ao público devem ser colocados no diretório
storage/app/public
Para torná-los acessíveis na web, você deve criar um link simbólico de public/storage
para storage/app/public
.
ln -s /path/to/laravel/storage/app/public /path/to/laravel/public/storage
Agora você pode criar na sua visualização um URL para os arquivos usando o auxiliar de recursos:
echo asset('storage/file.txt');
Se você estiver no Windows, poderá executar este comando no cmd:
mklink /j /path/to/laravel/public/avatars /path/to/laravel/storage/avatars
de: http://www.sevenforums.com/tutorials/278262-mklink-create-use-links-windows.html
Antes de tudo, você precisa criar um link simbólico para o diretório de armazenamento usando o comando artisan
php artisan storage:link
Então, em qualquer visualização, você pode acessar sua imagem através do URL Helper como este.
url('storage/avatars/image.png');
É bom salvar todas as imagens e documentos particulares no diretório de armazenamento, para que você tenha controle total sobre o éter do arquivo, você pode permitir que determinado tipo de usuário acesse ou restrinja o arquivo.
Faça uma rota / documentos e aponte para qualquer método do controlador:
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']
);
}
Quando você vai bater o localhost:8000/docs
arquivo será baixado, se houver algum.
O arquivo deve estar no root/storage/app/users/documents
diretório de acordo com o código acima, isto foi testado Laravel 5.4
.
Se você deseja carregar um pequeno número de imagens Privadas Você pode codificar as imagens para base64 e fazer eco <img src="{{$image_data}}">
diretamente nelas :
$path = image.png
$full_path = Storage::path($path);
$base64 = base64_encode(Storage::get($path));
$image_data = 'data:'.mime_content_type($full_path) . ';base64,' . $base64;
Mencionei private porque você só deve usar esses métodos se não desejar armazenar imagens publicamente acessíveis por meio de url. Em vez disso, você deve sempre usar a maneira padrão (vincular armazenamento / pasta pública e servir imagens com o servidor HTTP).
Cuidado com a codificação para base64()
ter dois lados negativos importantes:
Se você estiver usando php, basta usar a função php symlink, como a seguir:
symlink('/home/username/projectname/storage/app/public', '/home/username/public_html/storage')
altere o nome de usuário e o nome do projeto para os nomes corretos.
sem nome do site
{{Storage::url($photoLink)}}
se você deseja adicionar o nome do site a ele, por exemplo, para anexar aos feltros JSON da API
public function getPhotoFullLinkAttribute()
{
return env('APP_URL', false).Storage::url($this->attributes['avatar']) ;
}
Se você é como eu e de alguma forma possui caminhos de arquivo completos (fiz alguns padrões glob () correspondentes nas fotos necessárias, acabo com caminhos de arquivos completos), e sua configuração de armazenamento está bem vinculada (ou seja, seus caminhos tem a string storage/app/public/
), então você pode usar meu pequeno truque sujo abaixo: 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 '';
}
Se o disco 'local' não estiver funcionando para você, tente o seguinte:
'default' => env('FILESYSTEM_DRIVER', 'public'),
deproject_folder/config/filesystem.php
php artisan config:clear
php artisan storage:link
Para obter o URL da imagem carregada, você pode usar este Storage::url('iamge_name.jpg');