PHPackages                             triginarsa/minio-storage-utils - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [File &amp; Storage](/categories/file-storage)
4. /
5. triginarsa/minio-storage-utils

ActiveLibrary[File &amp; Storage](/categories/file-storage)

triginarsa/minio-storage-utils
==============================

A comprehensive MinIO storage service package for Laravel with file processing capabilities

v1.0.18(1mo ago)1599MITPHPPHP ^8.2

Since Jul 14Pushed 3w agoCompare

[ Source](https://github.com/Triginarsa/minio-storage-utils)[ Packagist](https://packagist.org/packages/triginarsa/minio-storage-utils)[ RSS](/packages/triginarsa-minio-storage-utils/feed)WikiDiscussions main Synced today

READMEChangelog (10)Dependencies (16)Versions (21)Used By (0)

MinIO Storage Utils for Laravel
===============================

[](#minio-storage-utils-for-laravel)

A simple PHP library for secure file handling with MinIO object storage, designed for Laravel applications.

What it does
------------

[](#what-it-does)

- 🔒 **Secure file uploads** with virus/malware scanning
- 🖼️ **Image processing** (resize, compress, watermark, thumbnails)
- 🎬 **Video processing** (optional, requires FFmpeg)
- 📄 **Document security** scanning
- 🔗 **Flexible URLs** (public or private with expiration)
- 📝 **Smart file naming** (hash, slug, or original names)

Installation
------------

[](#installation)

### Step 1: Install via Composer

[](#step-1-install-via-composer)

```
composer require triginarsa/minio-storage-utils
```

### Step 2: Publish Configuration

[](#step-2-publish-configuration)

```
php artisan vendor:publish --provider="Triginarsa\MinioStorageUtils\Laravel\MinioStorageServiceProvider" --tag="config"
```

### Step 3: Configure MinIO Disk

[](#step-3-configure-minio-disk)

Add to `config/filesystems.php`:

```
'disks' => [
    // other disks

    'minio' => [
        'driver' => 's3',
        'key' => env('MINIO_ACCESS_KEY'),
        'secret' => env('MINIO_SECRET_KEY'),
        'region' => env('MINIO_REGION', 'us-east-1'),
        'bucket' => env('MINIO_BUCKET'),
        'endpoint' => env('MINIO_ENDPOINT', 'http://localhost:9000'),
        'use_path_style_endpoint' => env('MINIO_USE_PATH_STYLE_ENDPOINT', true),
        'throw' => false,
    ],
],
```

### Step 4: Environment Setup

[](#step-4-environment-setup)

Change this value on `.env` file:

```
FILESYSTEM_DISK=minio

```

Add to your `.env` file:

```
# MinIO Connection Settings
MINIO_ACCESS_KEY=your-access-key
MINIO_SECRET_KEY=your-secret-key
MINIO_BUCKET=your-bucket-name
MINIO_ENDPOINT=http://localhost:9000
MINIO_REGION=us-east-1
MINIO_USE_PATH_STYLE_ENDPOINT=true
```

**Important Notes:**

- Both `MINIO_STORAGE_DISK` and `MINIO_STORAGE_DISK_BACKUP` should be set to `minio` (matching your disk name in `config/filesystems.php`).
- By default, URLs are public (unsigned). To make signed URLs the default, set `MINIO_URL_SIGNED_BY_DEFAULT=true`.
- You can set a default expiration for signed URLs with `MINIO_URL_DEFAULT_EXPIRATION=3600` (in seconds).
- Set `MINIO_VIDEO_PROCESSING=true` only if you have FFmpeg installed.
- Files with the same name will automatically get a number suffix (e.g., `image_1.jpg`, `image_2.jpg`).
- For others env can check on .env.example.

Quick Start
-----------

[](#quick-start)

### Basic File Upload

[](#basic-file-upload)

```
use Triginarsa\MinioStorageUtils\Laravel\Facades\MinioStorage;

public function upload(Request $request)
{
    $request->validate(['file' => 'required|file|max:10240']);

    $result = MinioStorage::upload($request->file('file'), '/img/');

    return response()->json([
        'success' => true,
        'url' => $result['main']['url'],			// "http://your-minio-server/your-bucket/img/avatar-1.png"
        'path' => $result['main']['path'],			// "/img/avatar-1.png"
        'original_name' => $result['main']['original_name'],	// "avatar.png"
	'file_name' => $result['main']['file_name'],		// "avatar-1.png"
	'size' => $result['main']['size'],			// 102400
	'mime_type' => $result['mime_type']			// "image/jpeg"
    ]);
}
```

### Image Upload with Processing

[](#image-upload-with-processing)

```
public function uploadImage(Request $request)
{
    $request->validate(['image' => 'required|image|max:10240']);

    $result = MinioStorage::upload($request->file('image'), '/img/', [
        'image' => [
            'resize' => ['width' => 1024, 'height' => 768],
            'quality' => 85,
            'convert' => 'jpg'
        ],
        'thumbnail' => [
            'width' => 200,
            'height' => 200
        ]
    ]);

    return response()->json([
        'success' => true,
        'image' => $result['main']['url'],			// "http://your-minio-server/your-bucket/img/avatar-1.png"
	'image_path' => $result['main']['path'],		// "/img/avatar-1-thumb.png"
        'thumbnail' => $result['thumbnail']['url']		// "http://your-minio-server/your-bucket/img/thumbnails/avatar-1-thumb.png"
    ]);
}
```

### Get File URLs

[](#get-file-urls)

```
// Get URL for existing file (uses config defaults)
$url = MinioStorage::getUrl('path/to/file.jpg'); // result: "http://your-minio-server/your-bucket/img/avatar.png"

// Get signed URL with custom expiration
$signedUrl = MinioStorage::getUrl('path/to/file.jpg', 3600, true); // 1 hour, signed

// Get public URL (no expiration, no signature)
$publicUrl = MinioStorage::getUrl('path/to/file.jpg', null, false);
// or
$publicUrl = MinioStorage::getPublicUrl('path/to/file.jpg');
```

Example Usage:

```
use Triginarsa\MinioStorageUtils\Laravel\Facades\MinioStorage;

public function view(Request $request)
{
    $request->validate(['imagePath' => 'required|string']);

    $imagePath = urldecode($request->input('imagePath'))

    //check if the image available on storage
    if (!MinioStorage::fileExists($imagePath)){
	return response()->json(['success => false', 'message' => 'File not found'], 404)
    }

    $result = MinioStorage::getUrl($imagePath);

    return response()->json([
        'success' => true,
        'image_url' => $result,				// "http://your-minio-server/your-bucket/img/avatar-1.png"
    ]);
}
```

Laravel Example: `getUrlPublic` with fallback

```
use Triginarsa\MinioStorageUtils\Laravel\Facades\MinioStorage;

public function publicUrl(string $filePath)
{
    try {
        // Optionally disable existence check: getUrlPublic($filePath, false)
        $result = MinioStorage::getUrlPublic($filePath);
        return $result;
    } catch (\Throwable $e) {
        return 'img/default.png';
    }
}
```

Laravel Example: `getUrlPublic` from another bucket

```
use Triginarsa\MinioStorageUtils\Laravel\Facades\MinioStorage;

public function publicUrlFromOtherBucket(string $filePath, string $bucket)
{
    try {
        // Existence check works only on the default bucket; disable it for cross-bucket
        return MinioStorage::getUrlPublic($filePath, false, $bucket);
    } catch (\Throwable $e) {
        return 'img/default.png';
    }
}
```

### Get File Metadata

[](#get-file-metadata)

```
$url = MinioStorage::getUrl('path/to/file.jpg');

// Result if file is Image:
// "path":"/img/avatar-1.png",
// "file_name": "avatar-1.png",
// "size": 381422,
// "mime_type": "image/jpeg",
// "last_modified": 1752626650,
// "width": 1331,
// "height": 2000,
// "aspect_ratio": 0.67,
// "file_size": 381422,
// "megapixels": 2.66

// Result if file is Docs:
// "path":"/doc/documents.pdf",
// "file_name": "documents-1.pdf",
// "size": 381422,
// "mime_type": "application/pdf",
// "last_modified": 1752626650,

```

Example Usage:

```
use Triginarsa\MinioStorageUtils\Laravel\Facades\MinioStorage;

public function metadata(Request $request)
{
    $request->validate(['imagePath' => 'required|string']);

    $imagePath = urldecode($request->input('imagePath'))

    //check if the image available on storage
    if (!MinioStorage::fileExists($imagePath)){
	return response()->json(['success => false', 'message' => 'File not found'], 404)
    }

    $result = MinioStorage::getMetadata($imagePath);

    return response()->json([
        'success' => true,
        'path' => $result['path'],				// "/img/avatar-1.png"
	'file_name' => $result['main']['file_name'],		// "avatar-1.png"
	'size' => $result['main']['size'],			// 102400
	'mime_type' => $result['mime_type'],			// "image/jpeg"
	'last_modified' => $result['last_modified']		// "1752626650"
    ]);
}
```

### Delete Files

[](#delete-files)

```
// Delete a file
$deleted = MinioStorage::delete('path/to/file.jpg'); //true

// Check if file exists
$exists = MinioStorage::fileExists('path/to/file.jpg'); //true
```

Example Usage:

```
use Triginarsa\MinioStorageUtils\Laravel\Facades\MinioStorage;

public function delete(Request $request)
{
    $request->validate(['imagePath' => 'required|string']);

    $imagePath = urldecode($request->input('imagePath'))

    //check if the image available on storage
    if (!MinioStorage::fileExists($imagePath)){
	return response()->json(['success => false', 'message' => 'File not found'], 404)
    }

    $result = MinioStorage::delete($imagePath);

    return response()->json([
        'success' => true,
	'message' => 'Image deleted successfully'
    ]);
}
```

Examples
--------

[](#examples)

Check out the `examples/` folder for complete working examples:

### Basic Examples

[](#basic-examples)

- **[basic-usage.php](examples/basic-usage.php)** - Non-Laravel usage example
- **[laravel-basic-usage.php](examples/laravel-basic-usage.php)** - Simple Laravel file upload

### Image Processing Examples

[](#image-processing-examples)

- **[laravel-image-processing-example.php](examples/laravel-image-processing-example.php)** - Image resize, compress, and thumbnails
- **[laravel-watermark-example.php](examples/laravel-watermark-example.php)** - Add watermarks to images

### Advanced Examples

[](#advanced-examples)

- **[laravel-doc-example.php](examples/laravel-doc-example.php)** - Document upload with security scanning
- **[laravel-security-example.php](examples/laravel-security-example.php)** - Security scanning and threat detection
- **[laravel-video-usage.php](examples/laravel-video-usage.php)** - Video processing with FFmpeg

### API References

[](#api-references)

If you want to see the detailed API reference, check out this [API REFERENCE](API-REFERENCE.md) document.

Configuration Options
---------------------

[](#configuration-options)

### Optional env Variables

[](#optional-env-variables)

Optional `.env` variable:

```
# Storage Disk Configuration
MINIO_STORAGE_DISK=minio
MINIO_STORAGE_DISK_BACKUP=minio

# Security & File Handling
MINIO_SECURITY_SCAN=true
MINIO_NAMING_STRATEGY=hash
MINIO_MAX_FILE_SIZE=10240

# Image Processing Settings
MINIO_IMAGE_QUALITY=85
MINIO_IMAGE_MAX_WIDTH=2048
MINIO_IMAGE_MAX_HEIGHT=2048
MINIO_IMAGE_CONVERT_FORMAT=jpg

# Video Processing (Optional)
MINIO_VIDEO_PROCESSING=false
MINIO_VIDEO_MAX_SIZE=102400

# URL Configuration
MINIO_URL_DEFAULT_EXPIRATION=
MINIO_URL_SIGNED_BY_DEFAULT=false
MINIO_URL_FORCE_HTTPS=false
```

### Image Processing

[](#image-processing)

```
'image' => [
    'resize' => [
        'width' => 1024,
        'height' => 768,
        'method' => 'fit' // fit, crop, stretch
    ],
    'quality' => 85,
    'convert' => 'jpg',
    'watermark' => [
        'path' => public_path('watermark.png'),
        'position' => 'bottom-right',
        'opacity' => 70
    ]
]
```

### Thumbnail Generation

[](#thumbnail-generation)

```
'thumbnail' => [
    'width' => 200,
    'height' => 200,
    'method' => 'fit', // fit, crop, proportional
    'quality' => 75
]
```

### Security Scanning

[](#security-scanning)

```
'scan' => true, // Enable security scanning
'naming' => 'hash' // hash, slug, original
```

### Video Processing (Optional)

[](#video-processing-optional)

```
'video' => [
    'format' => 'mp4',
    'compression' => 'medium',
    'resize' => ['width' => 1280, 'height' => 720]
]
```

File Naming Strategies
----------------------

[](#file-naming-strategies)

- **hash**: `a1b2c3d4e5f6...123456789.jpg` (secure, prevents duplicates)
- **slug**: `my-vacation-photo-1704067200.jpg` (SEO-friendly)
- **original**: `My Vacation Photo.jpg` (keeps original name)

URL Generation
--------------

[](#url-generation)

The library generates two types of URLs, with **public (unsigned) URLs as the default**.

### Public URLs (Default Behavior)

[](#public-urls-default-behavior)

Public URLs provide direct, unsigned access to files, suitable for content in publicly accessible buckets.

- **Configuration**: `MINIO_URL_SIGNED_BY_DEFAULT=false` (in `.env`)
- **How to Generate**: ```
    // The default `getUrl()` call now returns a public URL
    $publicUrl = MinioStorage::getUrl('path/to/file.jpg');

    // You can also be explicit
    $publicUrl = MinioStorage::getUrl('path/to/file.jpg', null, false);
    $publicUrl = MinioStorage::getPublicUrl('path/to/file.jpg');
    ```
- **Use Case**: Public assets like images, stylesheets, or public documents. Requires your bucket to have a public access policy.

### Signed URLs (For Private Content)

[](#signed-urls-for-private-content)

Signed URLs are secure, temporary links to private files. They are ideal for sensitive or user-specific content that should not be publicly accessible.

- **How to Generate**: ```
    // Explicitly request a signed URL with a 1-hour expiration
    $signedUrl = MinioStorage::getUrl('path/to/file.jpg', 3600, true);
    ```
- **Making Signed URLs the Default**:
    - Set `MINIO_URL_SIGNED_BY_DEFAULT=true` in your `.env` file.
    - You can also set a default expiration for all signed URLs with `MINIO_URL_DEFAULT_EXPIRATION=3600` (in seconds).

Error Handling
--------------

[](#error-handling)

```
use Triginarsa\MinioStorageUtils\Exceptions\SecurityException;
use Triginarsa\MinioStorageUtils\Exceptions\UploadException;

try {
    $result = MinioStorage::upload($file);
} catch (SecurityException $e) {
    // Malicious file detected
    return response()->json(['error' => 'Security threat detected'], 403);
} catch (UploadException $e) {
    // Upload failed
    return response()->json(['error' => 'Upload failed'], 500);
}
```

Requirements
------------

[](#requirements)

- PHP 8.2+
- Laravel 9.0+ (including Laravel 13)
- MinIO server or S3-compatible storage
- GD extension (for image processing)
- FFmpeg (optional, for video processing)

FFmpeg Installation (Optional)
------------------------------

[](#ffmpeg-installation-optional)

For video processing features:

```
# Ubuntu/Debian
sudo apt-get install ffmpeg

# macOS
brew install ffmpeg

# Or skip video processing - uploads still work without it
```

Testing
-------

[](#testing)

```
composer test
```

Security Features
-----------------

[](#security-features)

The library automatically scans uploads for:

- Malicious code (PHP, JavaScript, etc.)
- Virus signatures
- Suspicious file types
- Embedded scripts in images
- Macro-enabled documents

Contributing
------------

[](#contributing)

Contributions welcome! Please check the [issues page](https://github.com/triginarsa/minio-storage-utils/issues).

License
-------

[](#license)

MIT License

###  Health Score

48

—

FairBetter than 93% of packages

Maintenance94

Actively maintained with recent releases

Popularity19

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity58

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 93.5% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~18 days

Recently: every ~64 days

Total

19

Last Release

32d ago

PHP version history (3 changes)v1.0.0PHP ^8.1

v1.0.1PHP ^8.0

v1.0.17PHP ^8.2

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/17276387?v=4)[Adi](/maintainers/Triginarsa)[@Triginarsa](https://github.com/Triginarsa)

---

Top Contributors

[![AdiTriginarsa](https://avatars.githubusercontent.com/u/62545364?v=4)](https://github.com/AdiTriginarsa "AdiTriginarsa (43 commits)")[![Triginarsa](https://avatars.githubusercontent.com/u/17276387?v=4)](https://github.com/Triginarsa "Triginarsa (3 commits)")

---

Tags

laravels3image processingstoragefile-uploadminio

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/triginarsa-minio-storage-utils/health.svg)

```
[![Health](https://phpackages.com/badges/triginarsa-minio-storage-utils/health.svg)](https://phpackages.com/packages/triginarsa-minio-storage-utils)
```

###  Alternatives

[unisharp/laravel-filemanager

A file upload/editor intended for use with Laravel 5 to 10 and CKEditor / TinyMCE

2.2k3.5M85](/packages/unisharp-laravel-filemanager)[league/flysystem-aws-s3-v3

AWS S3 filesystem adapter for Flysystem.

1.7k285.7M1.0k](/packages/league-flysystem-aws-s3-v3)[laravel/ai

The official AI SDK for Laravel.

1.0k3.2M194](/packages/laravel-ai)[kolay/xlsx-stream

Streaming XLSX reader and writer for PHP and Laravel. Constant memory regardless of file size, direct S3 multipart streaming, optional born-indexed random access.

437.9k](/packages/kolay-xlsx-stream)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
