<?php /** * 循环本地,验证远程是否存在 不存在则删除本地 */ //error_reporting(); use Swoole\Process; include_once __DIR__."/../vendor/autoload.php"; function start(){ swoole_set_process_name('php-email-sync-list-check'); $id = 0; $goNum = 0; // 循环阻塞 while (true){ $id = db()->value('select `id` from `'.\Model\emailSql::$table.'` where `id` > '.$id.' order by `id` asc limit 1'); if($id){ // 启动一个协程 go(function () use ($id,&$goNum){ $goNum++; // 开始同步 try { sync($id); }catch (\Throwable $e){ echo $e->getMessage(); } \Lib\Log::getInstance()->write(); co::defer(function () use (&$goNum){ $goNum--; }); }); }else{ break; } } while ($goNum>0){ co::sleep(1); } _echo('结束了'); } /** * 开始同步, 这里是主要的业务代码 * @param $email_id * @param $worker_id * @return int * @author:dc * @time 2023/3/10 10:19 */ function sync($email_id){ $email = db()->first(\Model\emailSql::first($email_id)); if(!$email || $email['pwd_error']){ // 密码错误,或者超过一个月没有更新的邮箱 清空数据 if($email['pwd_error'] && $email['updated_at'] && strtotime($email['updated_at']) < (time()-86400*30) ){ db()->delete(\Model\listsSql::$table,['email_id'=>$email['id']]); } return 0; } // 读取到邮箱中的文件夹 $folders = db()->all(\Model\folderSql::all($email['id'])); if(!$folders){ return 3; } $mailServer = new Lib\Mail\Mail($email['email'],base64_decode($email['password']),$email['imap']); // 登录服务器 if($mailServer->login()!==1){ return 2; } $call = function ($email_id,$folder_id,$origin_folder) use ($mailServer){ _echo('run e '.$email_id.' fn '.$origin_folder); // gmail 邮箱 这个是不可选的 if($origin_folder == '[Gmail]'){ return; } // 同步父文件夹 $mailServer->client->selectFolder($origin_folder); $page = 0; $db = db(); while (1){ $ids = $db->all("select `id`,`uid` from ".\Model\listsSql::$table." where `email_id` = {$email_id} and `folder_id` = {$folder_id} and `udate` < ".strtotime("-1 day")." limit 100 offset ".($page*100)); $page++; if($ids){ try { $result = $mailServer->client->fetch(array_column($ids,'uid'),'UID',true); $result = array_column($result,'UID','UID'); }catch (Throwable $e){ _echo($e->getMessage()); return; } foreach ($ids as $id){ $uid = $id['uid']; $id = $id['id']; if(!$result || !isset($result[$uid])){ // 删除 如果远程没有,就删除本地 _echo('删除 e '.$email_id.' f '.$folder_id.' u '.$uid.' id '.$id.' d '.$db->delete(\Model\listsSql::$table,['id'=>$id]).' fd '.$db->delete('fob_hot_mail',['lists_id'=>$id]).' body '.$db->delete(\Model\bodySql::$table,['lists_id'=>$id])); } } } // 结束了 if(count($ids) < 100){ break; } } }; // $folders = list_to_tree($folders); foreach ($folders as $folder){ try { if(empty($folder['_child'])){ $call($email_id,$folder['id'],$folder['origin_folder']); }else{ foreach ($folder['_child'] as $item){ // 同步子文件夹 $call($email_id,$item['id'],$item['origin_folder']); } } }catch (\Throwable $e){ echo $e->getMessage(); } } $email = null; $mailServer = null; } if(!function_exists("imap_8bit")){ echo '请安装imap扩展'; exit(0); } \Co\run(function (){ start(); });