AWS, PHP

Laravel 汎用 S3へのファイル一時アップロード、本アップロード処理

Laravel

何の参考にもならんと思うが🐱

一時ファイルアップロードしてから本ディレクトリにコミットする流れの汎用クラス

FileUploadToS3Service.php

 

<?php

namespace App\Services;

use App\Exceptions\FileUploadException;
use Prettus\Repository\Generators\FileAlreadyExistsException;
use Illuminate\Filesystem\FilesystemManager;
use Illuminate\Support\Str;

/**
 * 汎用ファイルアップロード処理
 *
 * @author masuda
 */
class FileUploadTo3Service
{
    protected $client_s3;

    public function __construct(
        FilesystemManager $file_system_manager
    ) {
        $this->client_s3 = $file_system_manager->disk('s3');
    }

    /**
     * 非公開一時ファイルアップロード
     *
     */
    public function privateTemporaryUpload(
        UploadedFile $upload_file,
        int $company_id,
        string $type,
        ?bool $is_original_name = true
    ):array {
        $temp_path = $path = config('const.PRIVATE_FILEUPLOAD_TEMP_PATH') . '/' . $company_id . '/';
        // ディレクトリチェック なかったらS3に保存領域を作成
        $this->_createDirectory($temp_path);
        $file_name = $upload_file->getClientOriginalName();
        $response = $this->_putFile($upload_file, $path, $file_name, $is_original_name);
        if (!$response) {
            throw new FileUploadException("テンポラリー登録に失敗しました。");
        }

        return [
            'file_name' => $file_name,
            'file_path' => $temp_path . $file_name,
            'mime' => $upload_file->getMimeType(),
            'size' => $upload_file->getSize(),
        ];
    }

    /**
     * 非公開一時ファイルを利用用途別の本ディレクトリに移動
     *
     * @param int $company_id,
     * @param string $now_file_path,
     * @param string $file_name,
     * @param string $usage,
     * @param bool $is_original_name = false
     * @return string
     */
    public function commitPrivateFile(
        int $company_id,
        string $now_file_path,
        string $file_name,
        string $usage,
        bool $is_original_name = false
    ):string {
        // 本ディレクトリを取得
        switch ($usage) {
            case 'SALES':
                $base_path = config('const.PRIVATE_FILEUPLOAD_USAGE.SALES.BASE_PATH');
                break;
            case 'SYSTEM':
                $base_path = config('const.PRIVATE_FILEUPLOAD_USAGE.SYSTEM.BASE_PATH');
                break;
            case 'ADMIN':
                $base_path = config('const.PRIVATE_FILEUPLOAD_USAGE.ADMIN.BASE_PATH');
                break;
            default:
                throw new FileUploadException("利用用途の指定が間違っています。");
        }
        // 本ディレクトリの組み立て
        $target_dir = $base_path . '/' . $company_id . '/';
        // S3にディレクトリ作成
        $this->_createDirectory($target_dir);
        // ファイル設置先パスの組み立て
        if ($is_original_name) {
            $target_path = $target_dir . $file_name;
        } else {
            // 同名ファイルアップロードでの上書きを防止
            $target_path = $target_dir . Str::uuid() . '-' . $file_name;
        }
        // 現在のファイルパスの先頭に'private/temp/'がパスに付いていなかったら、すでに本登録されたファイルであるので現在のパスを返却だけする
        $base_temp_path = preg_quote(config('const.PRIVATE_FILEUPLOAD_TEMP_PATH'), '/');
        if (preg_match('/^'. $base_temp_path . '\/(.*)/', $now_file_path) === 0) {
            return $now_file_path;
        }
        // 本ディレクトリにファイルを移動
        if ($this->client_s3->exists($now_file_path)) {
            $this->client_s3->move($now_file_path, $target_path);
            return $target_path;
        } else {
            throw new FileUploadException("本ディレクトリへの登録に失敗しました。改めて一時ファイルアップロードを行ってください。");
        }
    }

    /**
     * S3にディレクトリ作成
     *
     * @param string
     * @return void
     */
    private function _createDirectory(string $path):void
    {
        if (!$this->client_s3->exists($path)) {
            $this->client_s3->makeDirectory($path);
        }
    }

    /**
     * S3にディレクトリ作成
     *
     * @param string
     * @return void
     */
    private function _putFile(UploadedFile $upload_file, string $path, string $file_name, bool $is_original_name)
    {
        // $is_original_nameがtrueの場合は上書き可なので通過させる
        if ($is_original_name === false) {
            // ファイルの存在チェック
            if ($this->exists($path, $file_name)) {
                // すでに存在してたら例外エラー
                throw new FileAlreadyExistsException('すでにファイルが存在しています。');
            }
        }
        // ファイルをS3指定パスに保存
        $save_file_name = $path  . $file_name;
        $options = [
            'Tagging' => 'isTemp=1',
            'TaggingDirective' => 'REPLACE'
        ];
        return $this->clientS3->put($save_file_name, $this->fileSystem->get($upload_file), $options);
    }

    /**
     * ファイル存在チェック
     *
     * @param string $path
     * @param $file_name
     * @return bool
     */
    public function exists(string $path, string $file_name)
    {
        $check_file_name = $path . $file_name;
        return $this->clientS3->exists($check_file_name);
    }
}

 

 

 

関連

Laravel S3へのPDFファイルアップロード, ダウンロード

 

Amazonおすすめ

iPad 9世代 2021年最新作

iPad 9世代出たから買い替え。安いぞ!🐱 初めてならiPad。Kindleを外で見るならiPad mini。ほとんどの人には通常のiPadをおすすめします><

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)