【问题标题】:Can't get images from storage laravel 5无法从存储 laravel 5 中获取图像
【发布时间】:2015-09-01 17:13:37
【问题描述】:

嘿,所以我正在尝试将我的图像放入我索引中的幻灯片中。 图像保存在 storage/app 上,然后是我从数据库中检索的其余路径。

我设法在<img src> 标签上输出了正确的路径,并且标题得到了应有的输出,但图像不会。

我从控制器发送和排列,然后在我的视图中循环遍历它:

控制器:

public function index()
{
    $projects = Project::all()->take(4);
    return view('index' , compact('projects'));

}

索引视图

@foreach($projects as $project)
{{$storagePath  = Storage::disk('local')->getDriver()->getAdapter()->getPathPrefix()}}
<li><img src="{{$storagePath.$project->fetchMedia->first()->public_name}}"    title=" {{$project->name}}"></li>
        @endforeach

HTML 输出是正确的路径:“/home/vagrant/project/storage/app/projects/Domaa6.jpg”

但它不显示图像。

我已经尝试使用 HTML::image 帮助器,但也没有成功。

有没有办法让它像现在这样工作,还是我需要创建一个新的控制器来操作我的图像?

fetchMedia 是我模型上返回媒体的函数。

public function fetchMedia()
{
    return $this->hasMany('App\Media');
}

【问题讨论】:

    标签: php image laravel


    【解决方案1】:

    您尝试做的事情在存储目录中是不可能的,而只能在公共目录中进行,同时暴露您的 laravel 存储目录的路径或 URL 会产生一些漏洞及其不良做法

    但是有一种解决方法:

    首先,你需要一个Image包来在引用某个路由时动态生成图片,我推荐intervention/image,它有很多方法让图片管理变得轻而易举。

    要实现这一点,请执行以下步骤:

    1.安装干预图片:

    将干预图像添加到您的 composer.json 和 do composer update

    "require": {
            "php": ">=5.5.9",
            "laravel/framework": "5.1.*",
            "intervention/image": "2.*",
            "intervention/imagecache": "2.*"
    
            .....
    

    在 $providers 数组中添加这个包的服务提供者。

    'Intervention\Image\ImageServiceProvider'
    

    将此包的外观添加到 $aliases 数组中。

    'Image' =&gt; 'Intervention\Image\Facades\Image'

    在 Laravel 5 中配置干预图像

    $ php artisan vendor:publish --provider="Intervention\Image\ImageServiceProviderLaravel5"
    

    在 Laravel 4 中发布配置

    $ php artisan config:publish intervention/image
    

    更多安装详情https://github.com/Intervention/image

    安装干预/图像后,您可以执行以下操作:

    Image::make($path=storage_path('stock-photos/image1.jpg'));

    2。设置处理图片请求的路由

    Route::get('stock-photos/{image}', function($image){
    
        //do so other checks here if you wish
    
        if(!File::exists( $image=storage_path("stock-photos/{$image}") )) abort(404);
    
        return Image::make($image)->response('jpg'); //will ensure a jpg is always returned
    });
    

    3.然后稍后在视图中您可以执行以下操作:

    @foreach($projects as $project)
        <li>
            <img src="{{url('stock-photos/'. $project->fetchMedia->first()->public_name)}}" title="{{$project->name}}">
        </li>
    @endforeach
    

    【讨论】:

    • 你不认为它会给服务器带来负担吗?
    【解决方案2】:

    很遗憾,我无法对 Digitlimit 的帖子发表评论(因为我的声誉还不够高),但他们的回应对我有用,但有一个变化。我没有返回Image::make($image),而是使用了response() 方法,因为这似乎为我生成了标题内容。比如

    Route::get('stock-photos/{image}', function($image){
    
    if(!File::exists( $image=storage_path("stock-photos/{$image}") )) abort(404);
    
    $returnImage = Image::make($image);
    
    return $returnImage->response();
    });
    

    希望能帮助遇到类似问题的其他人。

    【讨论】:

    • 我以为你可以用 49 个代表发表评论?我想如果你完成你的个人资料或者你可以发表评论。 Intervention Image 有很多方法,response() 也很好,我错误地省略了它。将编辑我的答案。谢谢。给你一票
    • 感谢您的支持,因为现在我可以发表评论了 :) 但您的回答很棒,对我很有帮助,所以谢谢。
    【解决方案3】:

    在显示图像时,您不需要引用文件路径。 img 标签中的内容是您要显示的图像的 URL。所以,在你的情况下,这将是

    @foreach($projects as $project)
        {{$storagePath  = Storage::disk('local')->getDriver()->getAdapter()->getPathPrefix()}}
        <li><img src="/{{$project->fetchMedia->first()->public_name}}"    title=" {{$project->name}}"></li>
    @endforeach
    

    但是。这也不起作用,因为您发出http 请求的资源应该是可公开访问的。 (如 css、js 脚本、图像)。话虽如此,您需要将图像存储在不同的位置,公共文件夹是完美的地方。例如,如果您将图像保存在 public/images/projects 中,那么在您的视图中,您会像这样引用它们

    <img src="/images/projects/{{$project->fetchMedia->first()->public_name}}" />
    

    【讨论】:

    • @AndrewMalinnkovi 让它在公用文件夹上工作的方式与您所说的完全相同,但我的客户要求图像必须存储在 storage/app/ImageName 上,这就是我挣扎的原因。
    • 您的客户会感到失望,但这无法实现。服务器根目录是公用文件夹,浏览器无法访问除此之外的所有内容。您可以在服务器端随意操作图像,但不能在“前端”操作。您可以建议您的客户端将资源存储在 Amazon s3 服务器上,这非常好且更灵活,而不是保留在本地
    • 是的,这是一种误导,因为它暗示存储文件夹是存储文件的首选简便方法 [link]laravel.com/docs/5.0/filesystem#basic-usage
    【解决方案4】:

    虽然我已经使用 Laravel 大约 2 年了,但我最近才开始使用它处理图像上传(使用版本 5.3.16)。图像处理疑难解答将我带到了这篇 Stack Overflow 帖子......最初接受的答案几乎解决了我遇到的问题,并进行了一些小的更改,如下所示:

    Route::get('images/books/{book_id}/{image}', function($book_id, $image){
    
        $storagePath  = Storage::disk('public')->getDriver()->getAdapter()->getPathPrefix();
        $imageFilePath = $storagePath . "images/books/{$book_id}/{$image}";
        if(!File::exists($imageFilePath)) abort(404);
    
        return Image::make($imageFilePath)->response();
    });
    

    在这个特定的示例中,我想检索一本书的特定上传图像。对于给定的书,我创建了一个与书的 ID 匹配的目录,并将图像上传到那里。

    为了检索图像,我首先获取公共存储目录。这通常在 config/app 目录中的“filesystems.php”配置文件中定义。我的示例如下(省略了此答案不需要的额外内容):

    <?php
    
    return [
    
        /*
        |--------------------------------------------------------------------------
        | Default Filesystem Disk
        |--------------------------------------------------------------------------
        |
        | Here you may specify the default filesystem disk that should be used
        | by the framework. A "local" driver, as well as a variety of cloud
        | based drivers are available for your choosing. Just store away!
        |
        | Supported: "local", "ftp", "s3", "rackspace"
        |
        */
    
        'default' => 'local',
    
        .
        .
        .
    
        'disks' => [
    
            'public' => [
                'driver' => 'local',
                'root' => storage_path('app/public'),
                'visibility' => 'public',
            ],
    
        ],
    
    ];
    

    其余的路线信息遵循与第一个接受的答案相同的模式。渲染图像也遵循接受的答案。

    【讨论】:

      【解决方案5】:

      存储路径() storage_path 函数返回应用程序存储目录的完全限定路径。您还可以使用 storage_path 函数生成存储目录中给定文件的完全限定路径:

       $path = storage_path();
      
       $path = storage_path('app/file.txt');
      

      https://laravel.com/docs/8.x/helpers#method-storage-path

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-03
        • 1970-01-01
        • 1970-01-01
        • 2019-11-29
        • 1970-01-01
        • 2020-10-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多