把图片存到MySQL中

场景

当有多台服务器时,用户上传的图片不能保存在服务器上,比较好的选择是使用阿里云OSS、亚马逊S3等云存储服务。

如果你不想使用这些云服务,也可以将图片存储在数据库MySQL中,虽然不是一个好的做法。

实验原理

直接将图片文件的二进制字符串存入MySQL即可。

实验步骤

以下实验基于 Laravel 框架。

创建数据库迁移

php artisan make:migration create_uploaded_images_table --create=uploaed_images
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateUploadedImagesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('uploaded_images', function (Blueprint $table) {
            $table->id();
            $table->binary('content')->comment('图片的二进制内容');
            $table->string('type', 64)->comment('图片类型');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('uploaded_images');
    }
}

创建模型

php artisan make:model UploadedImage
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class UploadedImage extends Model
{
    use HasFactory;


    protected $fillable = [
        'content',
        'type',
    ];
}

存入一个图片

$image = new UploadedImage();
$image->content = file_get_contents($this->file);
$image->save();

其中$this->file是用户上传的图片。

在数据库客户端中查看

输出图片


    /**
     * 获取图片
     *
     * @param Request $request
     * @return Application|ResponseFactory|Response|BinaryFileResponse
     */
    public function getImage(Request $request, $id)
    {
        $image = UploadedImage::query()->find($id);

        if (!$image) {
            // 图片不存在时,输出默认图片
            return response()->file(public_path('images/empty.jpg'));
        }

        return response($image->content)->header('Content-Type', $image->type);
    }