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.
實際操作畫面
不管怎麼說,他真的有作用. 😁
No Comment
Post your comment