Skip to content

Instantly share code, notes, and snippets.

@atomjoy
Created March 28, 2025 12:56
Show Gist options
  • Save atomjoy/27fa6e13f8e353315d1f6695f262126f to your computer and use it in GitHub Desktop.
Save atomjoy/27fa6e13f8e353315d1f6695f262126f to your computer and use it in GitHub Desktop.
Laravel FTP Storage image upload.

Ftp Storage Laravel

Dtorage docs https://laravel.com/docs/12.x/filesystem#sftp-driver-configuration

composer require league/flysystem-ftp "^3.0"

Provider

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

/**
 * Ftp storage class
 *
 * https://laravel.com/docs/12.x/filesystem#sftp-driver-configuration
 * composer require league/flysystem-ftp "^3.0"
 */
class StorageFtpProvider extends ServiceProvider
{
 /**
  * Register services.
  */
 public function register(): void
 {
	// Change storage disk to ftp (or in .env FILESYSTEM_DISK=ftp)
	if (
		config('filesystems.default') == 'local' ||
		config('filesystems.default') == 'public'
	) {
		config(['filesystems.default' => 'ftp']);
	}

	// Add storage ftp
	$this->app->config['filesystems.disks.ftp'] = [
		'driver' => 'ftp',
		'username' => env('FTP_USERNAME', 'laravel'),
		'password' => env('FTP_PASSWORD', 'password'),
		'host' => env('FTP_HOST', 'localhost'),
		'port' => (int) env('FTP_PORT', 21),
		'ssl' => env('FTP_SSL', true),

		// Optional FTP Settings...
		// 'root' => env('FTP_ROOT'),
		// 'passive' => true,
		// 'timeout' => 30,
	];
	}

	/**
	 * Bootstrap services.
	*/
	public function boot(): void
	{
		//
	}
}

Save images with Storage

// Save files
if($request->hasFile('image')){
	$path = Storage::putFile('photos', new File('/path/to/photo'));
	$path = Storage::putFileAs('photos', new File('/path/to/photo'), 'photo.webp');

	$path = $request->file('image')->store('media/avatars');
	$path = Storage::putFileAs('media/avatars', $request->file('image'), 'photo.webp');
}

// Url with storage/ or https://
$url = Storage::url('media/avatars/photo.webp');

// Temp url
$imgurl = Storage::temporaryUrl('media/avatars/photo.webp', now()->addMinutes(5));

// Base64
<img src="data:image/jpeg;base64,{{
	base64_encode(Storage::get('media/avatars/photo.webp'))
}}" alt="Example image">

Display images with Storage

<?php

use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Storage;

// Js onerror url fetch
Route::get('/img/url', function () {
	try {
		$path = request('path');
		if (Storage::exists($path)) {
			return Storage::url($path);
		}
	} catch (\Throwable $e) {
		return '/default/avatar.webp';
	}
});

// Image response
Route::get('/img/show', function () {
	try {
		$path = request('path');
		if (Storage::exists($path)) {
			return Storage::response($path);
		}
	} catch (\Throwable $e) {
		return response()->file(public_path('/default/avatar.webp'));
	}
});

// Use image response
Route::get('/img', function () {
	return '<img src="/img/show?path=avatars/1.webp">';
});

Custom driver

<?php

use Illuminate\Support\Facades\Storage;

try {
	$ftp = Storage::createFtpDriver([
		'driver'   => 'ftp',
		'host'     => $web->server_ip,
		'port'     => $web->server_port,
		'username' => $web->server_username,
		'password' => $web->server_password,
		'passive'  => false,
		'ignorePassiveAddress' => true,
	]);

	$ftp->put(
		'/default/welcome.webp',
		Storage::disk('local')->get('sample.webp')
	);

} catch (\Throwable $e) {
	report($e->getMessage());
	return 'Something went wrong with the ftp connection.';
}

Links

# Storage
https://laravel.com/docs/12.x/filesystem#sftp-driver-configuration
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment