by Devin Yang

建立于: 2年前 ( 更新: 2年前 )

SFTP的安装及设置不在本篇讨论范围,如果您想了解,建议可以看另一篇
https://www.ccc.tc/article/Laravel-SFTP-Driver-Configuration

本篇我要用极快速的Sample Demo我如何用自建的artisan的命令同步远程的数据到本地端。
或许有人会问为何不用rsync,呀本篇就是要介绍用Storage的方式同步文件。🤪

在这里,我们可以看到Laravel框架带来的好处,
像是Storage也可以换成自己的Google Drive,有机会我再来写一篇。
设计上,我让本地端文件上传时,也透过queue的机制,自动上传一份到云端(Google Drive),
本地端的文件上删除,同步删除云端文件,使用者下载文件时,会由云端下载,云端还没文件时由本地端下载。
但我自己的经验,用户也要登录Google才能下载我的Google Drive文件,好像扯远了,我们回到正题。

先直接看code吧,我在config/filesystems.php设置了一个sftp磁盘叫ccc。

'ccc' => [
    'driver' => 'sftp',
    'host' => '192.168.99.2',
    'username' => 'dlaravel',
    'privateKey' => '/home/dlaravel/.ssh/id_ed25519',
    'port' => 2258,
    'root' => '/var/www/html/storage/app/public',
    'url'=>'https://www.ccc.tc/storage',
],

然后我在routes/console.php新建了一个新的artisan命令

//同步远程数据
Artisan::command("fs:sync {disk} {directory}", function ($disk, $directory) {
    //指定磁盘,列出文件内容,在本篇文章会列出我远程主机的images目录内的文件。
    $files = Storage::disk($disk)->files($directory);
    foreach ($files as $file) {
        //因为文件从远程抓到本地端会有时间差,透过这个功能,下载文件,并把文件调整为远程主机的修改时间
        $download_to_local = function () use ($disk, $file) {
            $file_content = Storage::disk($disk)->get($file);//取得远程文件内容
            Storage::disk("local")->put('public/' . $file, $file_content); //把远程文件内容存用相同的档名存入本地端
            $lastModifiedTime = Storage::disk($disk)->lastModified($file); //远程文件最后修改时间
            $localFile  = Storage::disk("local")->path("public/" . $file); //取得本地端文件路径
            //调整修改时间与远程文件相同
            touch($localFile, $lastModifiedTime);
        };
		//同步处理        
        if (!Storage::disk("local")->exists('public/' . $file)) {
        	//上方条件,检查本地端的文件存不存在就下载在存档
            $download_to_local(); //下载并且修正时间
            echo sprintf("%s created.\n", $file);
        } elseif (Storage::disk($disk)->lastModified($file) > Storage::disk("local")->lastModified('public/' . $file)) {
            //上面的条件,因远程及本地都有相同文件,比较修改时间,如果远程主机的时间大於本地端,
            //代表远程的文件有更新了,就进行文件更新。
            $download_to_local(); //下载并且修正时间
            echo sprintf("%s updated.\n", $file);
        } else {
            //echo sprintf("sync skip %s, already up to date.\n", $file);
        }
    }
});

如果你们有注意到上面的进程码,我用Laravel的Storage提供的get及put功能,直接搞定远程主机的抓档及本地端主机的存档,真好用。😆

如下画面,同步完成罗

我们直接登到这两个网站查看,修改时间是一致的,这结果是我想要的。

如果我们在远程的文件随便touhc一下,更新修改时间,用来模拟远程文件被修改了.

我们再从本地端运行一次同步命令,因为我边打边贴图,所以下面的画面中多了上方我贴的三张图档created,
,但您可看到我touch的文件被更新了,后面显示updated.🤣

images/sqGaCIj8WkZFKvifC1TITn81QocunOyHYQq0m7Ae.png updated.

实际操作画面

不管怎么说,他真的有作用. 😁
 

Tags: laravel storage

Devin Yang

文章内容无法一一说明,如果您有什么不了解处,欢印提问哦:)

No Comment

Post your comment

需要登入才可留言!