使用SFTP在Laravel中删除一个目录(文件夹)。

huangapple go评论72阅读模式
英文:

Laravel php delete a directory (folder) via sftp

问题

我正在尝试通过SFTP在我的服务器上删除一个文件夹。我使用的是PHP 7.4.13和Laravel 7.30.4。

我已经设置好了我的SFTP驱动程序,一切都正常(上传、删除文件、创建目录)。

但唯一的问题是我无法删除一个文件夹。

我正在使用官方Laravel文档上写的deleteDirectory($directory)函数:
https://laravel.com/docs/7.x/filesystem

这是我的设置:
filesystem.php

'disks' => [
    'sftp' => [
        'driver' => 'sftp',
        'host' => env('SFTP_HOST'),
        'username' => env('SFTP_USERNAME'),
        'password' => env('SFTP_PASSWORD'),
        'timeout' => env('SFTP_TIMEOUT'),
        'port' => env('SFTP_PORT'),
    ]
]

这是我的代码:
Storage::disk('sftp')->deleteDirectory('path/to/folder')

但文件夹仍然存在,文件夹中的所有文件也仍然存在。没有错误消息。而且如果我使用dd()输出上面的代码,它会返回true

我在服务器上具有创建、写入和删除的所有权限。而且我可以使用WinSCP通过SFTP删除服务器上的文件夹。

是否有人可以告诉我我哪里做错了,或者我可以使用哪个函数来实现这个目标?

非常感谢,如果需要的话我可以提供更多信息。

简而言之:我尝试了Storage::disk('sftp')->deleteDirectory('path/to/folder'),但什么也没有发生。

编辑:文件权限

编辑2:尝试首先删除文件夹中的所有文件,然后再删除文件夹

编辑3:尝试删除deleteDirectory()函数的第二个参数

编辑4:我正在使用的整个方法以及在哪里使用它的上下文。

实际上,整个方法只有这几行代码,因为我想简化测试。目标是删除服务器上的testing_folder文件夹。FYI,我们使用的是Synology的服务。

以下是我的代码:
web.php 中:

Route::get('/InspectionDocument/test', 'InspectionDocumentController@test')->name('inspdoc.test');

InspectionDocumentController.php 中:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Controllers\RequestController;
use DB;
use Log;
use Auth;
use File;
use Storage;
use Response;
use ZipArchive;

class InspectionDocumentController extends Controller
{
    public function __construct()
    {
    }

    // 其他函数...

    public function test(Request $request)
    {
        $files = Storage::disk('sftp')->allFiles('QCS/test_folder');
        Storage::disk('sftp')->delete($files);
        Storage::disk('sftp')->delete('QCS/test_folder');
        try { Storage::disk('sftp')->deleteDirectory('QCS/test_folder', false); } catch (\Exception $e) { dd($e->getMessage()); }
    }

}

用于测试:首先,我转到页面 http://localhost:8000/InspectionDocument/test。然后页面加载,没有返回任何错误,如下图所示。

在运行代码之前:

在运行代码后:

修改日期已更改,文件夹内的文件已删除。

英文:

I am trying to delete a folder on my server via sftp. I am using php 7.4.13 and laravel 7.30.4

I have set up my sftp drive and everything (upload, delete files, create directory) works fine.

But the only problem is that I could not delete a folder.

I am using deleteDirectory($directory) function which is written on the official laravel documentation:
https://laravel.com/docs/7.x/filesystem

Here is my set up:
filesystem.php

&#39;disks&#39; =&gt; [
    &#39;sftp&#39; =&gt; [
        &#39;driver&#39; =&gt; &#39;sftp&#39;,
        &#39;host&#39; =&gt; env(&#39;SFTP_HOST&#39;),
        &#39;username&#39; =&gt; env(&#39;SFTP_USERNAME&#39;),
        &#39;password&#39; =&gt; env(&#39;SFTP_PASSWORD&#39;),
        &#39;timeout&#39; =&gt; env(&#39;SFTP_TIMEOUT&#39;),
        &#39;port&#39; =&gt; env(&#39;SFTP_PORT&#39;),
]

Here is my code:
Storage::disk(&#39;sftp&#39;)-&gt;deleteDirectory(&#39;path/to/folder&#39;)

But the folder still exists and all files inside the folder also still exist. There is no error message. And also if I dd() the code above, it returns true.

I have all permission to create, write and delete on this server. And also I can delete folder on this server using WinSCP via sftp.

Could anyone tell me which part I did wrong or what function I can use to achieve this?

Thanks a lot and I would provide more information if you need it.

TLDR:
I tried: Storage::disk(&#39;sftp&#39;)-&gt;deleteDirectory(&#39;path/to/folder&#39;) but nothing happend.

EDIT: File permission
使用SFTP在Laravel中删除一个目录(文件夹)。

EDIT 2: Tried to delete all files inside the folder first then delete the folder

$files = Storage::disk(&#39;sftp&#39;)-&gt;allFiles(&#39;QCS/test_folder&#39;);
Storage::disk(&#39;sftp&#39;)-&gt;delete($files);
try { Storage::disk(&#39;sftp&#39;)-&gt;deleteDirectory(&#39;QCS/test_folder&#39;, true); } catch (\Exception $e) { dd($e-&gt;getMessage()); }

EDIT 3: Tried to remove the second parameter of deleteDirectory() function

$files = Storage::disk(&#39;sftp&#39;)-&gt;allFiles(&#39;QCS/test_folder&#39;);
Storage::disk(&#39;sftp&#39;)-&gt;delete($files);
try { Storage::disk(&#39;sftp&#39;)-&gt;deleteDirectory(&#39;QCS/test_folder&#39;); } catch (\Exception $e) { dd($e-&gt;getMessage()); }

For both EDIT 2 and EDIT 3:
file inside the folder got deleted but the file still exist, and also no error ;(

EDIT 4: Whole method I am using and the context on where I using it.

Actually, the whole method is only these few line of codes since I want to make it simpler for testing. Goal is to delete the folder testing_folder on the server. FYI we are using Synlogy's service.

Here is my code:
In web.php:

Route::get(&#39;/InspectionDocument/test&#39;, &#39;InspectionDocumentController@test&#39;)-&gt;name(&#39;inspdoc.test&#39;);

In InspectionDocumentController.php:

&lt;?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Controllers\RequestController;
use DB;
use Log;
use Auth;
use File;
use Storage;
use Response;
use ZipArchive;

class InspectionDocumentController extends Controller
{
    public function __construct()
    {
    }

    // other functions...

    public function test(Request $request)
    {
        $files = Storage::disk(&#39;sftp&#39;)-&gt;allFiles(&#39;QCS/test_folder&#39;);
        Storage::disk(&#39;sftp&#39;)-&gt;delete($files);
        Storage::disk(&#39;sftp&#39;)-&gt;delete(&#39;QCS/test_folder&#39;);
        try { Storage::disk(&#39;sftp&#39;)-&gt;deleteDirectory(&#39;QCS/test_folder&#39;, false); } catch (\Exception $e) { dd($e-&gt;getMessage()); }
    }

}

For testing: First I go to the page http://localhost:8000/InspectionDocument/test. Then the page loads, without returning any error like this:
使用SFTP在Laravel中删除一个目录(文件夹)。

Before running the code:
使用SFTP在Laravel中删除一个目录(文件夹)。

使用SFTP在Laravel中删除一个目录(文件夹)。

After running the code:
使用SFTP在Laravel中删除一个目录(文件夹)。

使用SFTP在Laravel中删除一个目录(文件夹)。

Modified date changed and the file inside got deleted.

答案1

得分: 1

即使文档中没有显示,deleteDirectory() 接受第二个参数 $preserve

当第二个参数 $preservetrue 时,该方法会清空文件夹而不删除它。

在你的情况下,Storage::disk('sftp')->deleteDirectory('QCS/test_folder', true); 表示你要保留文件夹。

如果你想删除基础文件夹,请移除第二个参数:

Storage::disk('sftp')->deleteDirectory('QCS/test_folder');
英文:

Even if the documentation doesn't show it, deleteDirectory() accepts a second parameter $preserver

@src/Illuminate/Filesystem/Filesystem.php

public function deleteDirectory($directory, $preserve = false)
{
    if (! $this-&gt;isDirectory($directory)) {
        return false;
    }

    $items = new FilesystemIterator($directory);

    foreach ($items as $item) {

        if ($item-&gt;isDir() &amp;&amp; ! $item-&gt;isLink()) {
            $this-&gt;deleteDirectory($item-&gt;getPathname());
        }

        else {
            $this-&gt;delete($item-&gt;getPathname());
        }
    }

    if (! $preserve) {
        @rmdir($directory);
    }

    return true;
}

When the second Parameter $preserve is true, the method will empty the folder without deleting it.

In your case, Storage::disk(&#39;sftp&#39;)-&gt;deleteDirectory(&#39;QCS/test_folder&#39;, true); you are asking it to keep the folder.

If you want to delete the base folder too, remove the second parameter

 Storage::disk(&#39;sftp&#39;)-&gt;deleteDirectory(&#39;QCS/test_folder&#39;);

答案2

得分: 0

在POSIX系统上删除目录的语义是,如果目录不为空,则删除操作将失败(rmdir)。在您的PHP代码和远程文件系统之间存在许多抽象层,但我期望实现此功能的代码仍然应符合标准行为。然而,我注意到您提供的文档明确表示不同。我怀疑文档是错误的,实现是正确的。

您可以通过检查远程系统上的审计日志来验证这一点。

或者这可能只是一个权限问题。您有进行权限检查吗?

英文:

The semantics for deleting a directory on a POSIX system are that it fails if the directory is not empty (rmdir). There are a lot of layers of abstraction between your PHP code and the remote filesystem, but I would expect that code implementing the functionality would still conform to the standard behaviour. However I see that the documentation you linked explicitly says otherwise. I suspect the documentation is wrong and the implementation is correct.

You could very this by checking the audit logging on the remote system.

Or it may simply be a permissions issue. Did you check?

huangapple
  • 本文由 发表于 2023年6月1日 15:16:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/76379508.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定