Search code examples
phplaravellaravel-8file-structure

Laravel: Move the upload folder out of the public_html folder


The structure of my project folder is as follows:

.
└── /home (Inaccessible)
    └── user
        └── public_html
            ├── app
            ┊
            ├── public
            │   ├── css
            │   ┊
            │   └── upload
            ┊
            ├── .htaccess
            └── .env

As you can see, the project upload folder is in the public folder, and the following code shows the specifications of my public disk:

'disks' => [
        'public' => [
            'driver' => 'local',
            'root' => public_path('upload'),
            'url' => env('APP_URL').'/upload',
            'visibility' => 'public',
        ],
]

And because my project is on a shared host, I added an .htaccess file with the following content to public_html:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^(.*)$ public/$1 [L]
</IfModule>

And in the .env file I added the following line

ASSET_URL=/public

Now I want to move the upload folder out of public_html, I want the structure of the project folders to be as follows:

.
└── /home (Inaccessible)
    └── user
        ├── public_html
        └── upload

I did not get the answer by changing the root address of the public disk as follows, and when I try to display a photo, I get 404 error.

'root' => preg_replace("/^(.*\/).*$/", "$1" ,$_SERVER['DOCUMENT_ROOT']).'/upload'
// OR
'root' => base_path('../upload')
//OR
'root' => dirname(__DIR__,2) . '/upload',

Is this possible?

UPDATE
The links to my files are like http://example.com/upload/1611343402_Colors.png


Solution

  • The upload folder should be in /root/storage if you are using laravel.

    See docs of the storage facade https://laravel.com/docs/8.x/filesystem

    It works this way. The command Storage::disk('local')->put('file.txt', 'Contents'); will store the file on the disk "local" which is defined in the config file /root/config/filesystems.php. Thats where you tried to change the root paramter i guess. You can access any files from storage in your controller files, jobs and so on.

    If you want to use the storage for public assets which need to be delivered by the web server you need to do the following:

    Create a symlink between a folder /root/public/storage and /root/storage/app/publicby using the shell command php artisan storage:link

    enter image description here

    This way you can use the storage helper like this echo asset('storage/file.txt'); deliver the file /root/storage/app/public/file.txt.