Laravel storage::disk [In-Depth Tutorial]


Laravel

Author: Steve Alila
Reviewer: Deepak Prasad

Laravel is a popular PHP framework for web development that comes with various built-in features, including a robust storage system. The storage system provides a simple and unified API for interacting with various storage systems such as local disk, Amazon S3, FTP, and more.

One of the essential features of Laravel's storage system is the disk method, which provides a way to work with different disks in your application. A disk represents a storage location, such as the local file system or a cloud storage service like Amazon S3.

The disk method is used to retrieve an instance of the file system from a specific disk. You can use this instance to perform various operations on files and directories stored on the disk, such as creating, reading, updating, and deleting files.

For example, to retrieve an instance of the local disk, you can use the following code:

$disk = Storage::disk('local');

This will return an instance of the local disk file system that you can use to perform file operations on the local disk.

 

Understand Laravel storage::disk

Laravel supports many storage options. For example, you can upload a file to a local disk or transfer it to a cloud storage like Amazon S3. 

The storage options are referred to as disks. You can inspect the available disks and their settings inside the config/filesystems.php file.

<?php

return [

    'default' => env('FILESYSTEM_DISK', 'local'),

    'disks' => [

        'local' => [
            'driver' => 'local',
            'root' => storage_path('app'),
            'throw' => false,
        ],

        'public' => [
            'driver' => 'local',
            'root' => storage_path('app/public'),
            'url' => env('APP_URL').'/storage',
            'visibility' => 'public',
            'throw' => false,
        ],

        's3' => [
            'driver' => 's3',
            'key' => env('AWS_ACCESS_KEY_ID'),
            'secret' => env('AWS_SECRET_ACCESS_KEY'),
            'region' => env('AWS_DEFAULT_REGION'),
            'bucket' => env('AWS_BUCKET'),
            'url' => env('AWS_URL'),
            'endpoint' => env('AWS_ENDPOINT'),
            'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false),
            'throw' => false,
        ],

    ],

    'links' => [
        public_path('storage') => storage_path('app/public'),
    ],

];

local is the default storage disk, but you can change it according to your needs.

The public disk is meant for files to be publicly accessible. Such files end up instorage/app/public file. If you use the destination for uploads, you should link to the root public folder using the following command.

php artisan storage:link

You can perform several actions on the disks using Laravel Storage facade. For instance, you can use the Laravel storage::disk to specify the disk when uploading a file.

Storage::disk('local')->put('explorers.txt', 'The first explorers to visit the moon and Mars');

Here, we create a file called explorers.txt with the content The first explorers to visit the moon and Mars in the local disk. 

Here is a more practical example of Laravel storage::disk.

 

Example-1: Upload file to local disk

This section shows you how to upload an image to public Laravel storage::disk before displaying the image on the browser. You can get the full code on GitHub.

We will focus on the files that relate to image upload.

Laravel Setup

laravel new laravel_demo_blog
cd laravel_demo_blog
php artisan make:model Blog -mcr
code .

We create a Laravel app called larave_demo_blog and navigate to the new project directory. We then make a model with a migration and controller with default functions.

 

Model

Database

Create a database with a name specified in the .env file.

mysql -u root -p
mysql> create database laravel_demo_blog;
mysql> exit;

We login to MySQL database service with the root user and create the laravel_demo_blog before quitting the the prompt.

Laravel storage::disk [In-Depth Tutorial]

Schema

Open the blogs table in the database/migrations folder and add the method of the titleimage, and body between the id() and timestamps() methods.

<?php

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

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('blogs', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->string('image');
            $table->text('body');
            $table->timestamps();
        });
    }

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

Laravel storage::disk [In-Depth Tutorial]

Migrations

Migrate the new changes to the MySQL database we just created.

php artisan migrate

Laravel storage::disk [In-Depth Tutorial]

 

View

We write the code to send the details to the server in the resources/views/create.blade.php file.

<x-layout>

<form action="{{ url('store') }}" method="post" enctype="multipart/form-data" class="w-2/4 mx-auto">
    @csrf 
    <div class="mb-4">
        <label for="title" class="block mb-2">Title:</label>
        <input type="text" name="title" class="w-full bg-gray-100 text-gray-700 p-2 rounded focus:outline-none sm:w-4/5">
    </div>
    <div class="w-full mb-4">
        <label for="body" class="block mb-2">Body:</label>
        <textarea name="body" id="body" rows="7" class="w-full bg-gray-100 text-gray-700 p-2 rounded focus:outline-none sm:w-4/5"></textarea>
    </div>
    <div class="mb-4">
        <input type="file" name="file">
    </div>
    <div class="mb-4">
        <button class="bg-cyan-800 hover:bg-cyan-900 rounded px-8 py-2 ">Store</button>
    </div>
</form>

</x-layout>

The form sends the details to the store route using the HTTP post method. The enctype attribute enables image upload.

The form grabs the data and attaches it to the respective name attribute on clicking the Store button. 

 

Controller

Laravel receives the form data via the routes/web.php file.

<?php

use App\Http\Controllers\BlogController;
use Illuminate\Support\Facades\Route;

Route::get('/', [BlogController::class, 'index']);
Route::get('create', [BlogController::class, 'create']);
Route::post('store', [BlogController::class, 'store']);
Route::get('show/{id}', [BlogController::class, 'show']);
Route::get('edit/{id}', [BlogController::class, 'edit']);
Route::patch('update/{id}', [BlogController::class, 'update']);
Route::delete('destroy/{id}', [BlogController::class, 'destroy']);

The form data is sent to the store route. The route looks for further instructions in the store function in the BlogController class, as defined in the app\Http\Controllers\BlogController folder. 

   public function store(Request $request)
    {
        $img = $request->file;
        $img_name = $img->getClientOriginalName();

        $blog = new Blog();

        $blog->title = $request->title;
        $blog->body = $request->body;
        $blog->image = $img_name;

        Storage::disk('public')->put('images/'.$img_name, file_get_contents($img));
        $blog->save();

        return redirect('/');

    }

As soon as the form details reach the store function, they are received by the $request object. From there, you can decide how to store the image in Laravel storage::disk as well in the database.

We hold the file object in the $img container. Next, we get the image name from the temporary container and store it in the $img_name.

We then create an instance of the Blog class and attach the $request->title, $request->body, and the $img_name to its title, body, and image attributes, respectively.

Before saving the new blog, we upload the image to the images folder in the public Storage::disk. Then, create a symbolic link in the (root) public folder. 

Input

php artisan storage:link

Output

steve@thisHostname:~/laravel_demo_blog$ php artisan storage:link
   INFO  The [public/storage] link has been connected to [storage/app/public].

In Layman's terms, we have said, "Hey, Laravel. Open the storage/app/public folder and store a new image in the images folder. Also, make it possible for us to access the images as a public asset. Do that by creating a link between the two file paths: storage/app/public and public/storage  folders."

Using public Laravel storage::disk

 

Finally, we save the details to the database and redirect the user to the landing page.

We should  then see all blogs or read a single blog as specified in the index and show views, respectively. 

Laravel storage::disk [In-Depth Tutorial]

 

Example-2: Upload file to Amazon S3 Storage

Here's an example that demonstrates how to use Laravel's storage::disk to upload a file to Amazon S3 and retrieve its public URL:

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;

public function uploadToS3(Request $request)
{
    $file = $request->file('file');
    
    // Get an instance of the S3 disk
    $s3 = Storage::disk('s3');
    
    // Generate a unique file name
    $filename = uniqid() . '.' . $file->getClientOriginalExtension();
    
    // Upload the file to S3
    $s3->putFileAs('uploads', $file, $filename);
    
    // Get the public URL of the uploaded file
    $url = $s3->url('uploads/' . $filename);
    
    // Return the URL to the client
    return response()->json(['url' => $url]);
}

In this example, we first retrieve the uploaded file from the request using the file method. We then get an instance of the S3 disk using Storage::disk('s3'). Next, we generate a unique file name and upload the file to the S3 bucket under the uploads directory using the putFileAs method.

Finally, we retrieve the public URL of the uploaded file using the url method and return it to the client as a JSON response.

 

Cheat Sheet Commands

Command Description
Storage::disk('local')->delete('example.txt') Delete a file on local disk
Storage::disk('local')->deleteDirectory('path/to/directory') Delete all files in a directory on the local disk
$files = Storage::disk('local')->files('path/to/directory') Retrieve a list of all files in a directory on the local disk
Storage::disk('local')->exists('example.txt') Check if a file exists on a specific disk
Storage::disk('s3')->exists('path/to/file') Check if a file exists on the S3 disk
Storage::disk('local')->copy('path/to/file', 'new/path/to/file') Copy a file from one disk to another
Storage::disk('s3')->move('path/to/file', 'new/path/to/file') Move a file from one disk to another
$contents = Storage::disk('local')->get('example.txt') Retrieve the contents of a file on a specific disk
$size = Storage::disk('local')->size('path/to/file'); Get the size of a file on the local disk
Storage::disk('local')->put('path/to/file', 'This is a test file.'); Write a string to a file on the local disk
$time = Storage::disk('local')->lastModified('path/to/file'); Retrieve the last modified time of a file on the local disk
$contents = Storage::disk('local')->get('path/to/file'); Get the contents of a file on the local disk
Storage::disk('local')->makeDirectory('path/to/new_directory'); Create a new directory on the local disk
$directories = Storage::disk('local')->directories('path/to/directory'); Retrieve a list of all directories in a directory on the local disk
$type = Storage::disk('local')->mimeType('path/to/file'); Get the MIME type of a file on the local disk
Storage::disk('local')->append('path/to/file', 'This is some new text.'); Append a string to a file on the local disk
Storage::disk('s3')->delete('path/to/file'); Delete a file on the S3 disk
if (Storage::disk('local')->allFiles('path/to/directory') === []) {
// The directory is empty
}
Check if a directory is empty on the local disk
$contents = Storage::disk('local')->allFiles('path/to/directory'); Retrieve a list of all files and directories in a directory on the local disk

 

Conclusion

Laravel's storage::disk provides a unified API for working with different storage systems in Laravel, including local disk, Amazon S3, and FTP. It allows developers to interact with these storage systems using a single, consistent syntax. You can use storage::disk to create, delete, check for the existence of, and retrieve the contents of files on a specific disk. Overall, it simplifies file system management in Laravel applications.

 

Further Reading

File Storage - Laravel - The PHP Framework For Web Artisans

 

Steve Alila

Steve Alila

He specializes in web design, WordPress development, and data analysis, with proficiency in Python, JavaScript, and data extraction tools. Additionally, he excels in web API development, AI integration, and data presentation using Matplotlib and Plotly. You can connect with him on his LinkedIn profile.

Can't find what you're searching for? Let us assist you.

Enter your query below, and we'll provide instant results tailored to your needs.

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can send mail to admin@golinuxcloud.com

Thank You for your support!!

Leave a Comment