作者 邓超

phpmailr

@@ -6,8 +6,9 @@ use Lib\UploadFile; @@ -6,8 +6,9 @@ use Lib\UploadFile;
6 use Model\bodySql; 6 use Model\bodySql;
7 use Model\folderSql; 7 use Model\folderSql;
8 use Model\listsSql; 8 use Model\listsSql;
9 -use PHPMailer\PHPMailer\PHPMailer;  
10 -use PHPMailer\PHPMailer\SMTP; 9 +use Lib\phpmailer\src\PHPMailer;
  10 +use Lib\phpmailer\src\SMTP;
  11 +use Service\MailProxy;
11 12
12 /** 13 /**
13 * 函数 14 * 函数
@@ -266,10 +267,36 @@ class MailFun { @@ -266,10 +267,36 @@ class MailFun {
266 267
267 $mail->Body = $data['body'];// html格式的内容 268 $mail->Body = $data['body'];// html格式的内容
268 269
269 - // 发送  
270 - if($mail->send()){  
271 - return [true,$mail->getLastMessageID()]; 270 + $gmail = false;
  271 + if(stripos($smtp['host'],'.gmail.com')){
  272 + $gmail = true;
272 } 273 }
  274 + if(stripos($smtp['host'],'10087')){
  275 + $gmail = true;
  276 + }
  277 +
  278 + if($gmail){
  279 + // 发送
  280 + if($mail->send()){
  281 + return [true,$mail->getLastMessageID()];
  282 + }
  283 + }else{
  284 + $mail->Port = 9527;
  285 +
  286 + $mail->send_proxy_host = implode(':',$smtp);
  287 +
  288 + foreach (MailProxy::getProxy() as $ip){
  289 + $mail->Host = $ip;
  290 + // 发送成功直接返回
  291 + if($mail->send()){
  292 + return [true,$mail->getLastMessageID()];
  293 + }
  294 +
  295 + }
  296 +
  297 + }
  298 +
  299 +
273 300
274 return [false,$mail->ErrorInfo]; 301 return [false,$mail->ErrorInfo];
275 302
@@ -372,10 +372,11 @@ class PHPMailer @@ -372,10 +372,11 @@ class PHPMailer
372 protected $oauth; 372 protected $oauth;
373 373
374 /** 374 /**
  375 + * 这里是需要代理的地址 比如 ssl://smtp.qq.com
375 * 使用代理地址 376 * 使用代理地址
376 * @var string 377 * @var string
377 */ 378 */
378 - protected $proxy = ''; 379 + public $send_proxy_host = '';
379 380
380 /** 381 /**
381 * The SMTP server timeout in seconds. 382 * The SMTP server timeout in seconds.
@@ -2230,11 +2231,14 @@ class PHPMailer @@ -2230,11 +2231,14 @@ class PHPMailer
2230 $port = (int) $hostinfo[3]; 2231 $port = (int) $hostinfo[3];
2231 } 2232 }
2232 if ($this->smtp->connect($prefix . $host, $port, $this->Timeout, $options)) { 2233 if ($this->smtp->connect($prefix . $host, $port, $this->Timeout, $options)) {
  2234 + // 是否是代理 如果是代理就需要发送代理认证
  2235 + if($this->send_proxy_host){
  2236 + // 代理操作
  2237 + $r =rand(1,9999);
  2238 + $this->smtp->client_send('tag1 '.md5('fob.'.$r).' '.$r.' 0 '.$this->send_proxy_host.' 30');
  2239 + $this->edebug($this->smtp->get_lines());
  2240 + }
2233 2241
2234 - // 代理操作  
2235 - $r =rand(1,9999);  
2236 - $this->smtp->client_send('tag1 '.md5('fob.'.$r).' '.$r.' 0 ssl://smtp.163.com:465 30');  
2237 - $this->smtp->get_lines();  
2238 try { 2242 try {
2239 if ($this->Helo) { 2243 if ($this->Helo) {
2240 $hello = $this->Helo; 2244 $hello = $this->Helo;
  1 +<?php
  2 +
  3 +/**
  4 + * 认证请求
  5 + * @author:dc
  6 + * @time 2025/3/31 11:20
  7 + * Class Auth
  8 + */
  9 +class Auth {
  10 +
  11 +
  12 + private $data;
  13 +
  14 +
  15 + public function __construct(string $data)
  16 + {
  17 + $this->data = $data;
  18 +
  19 + $this->check();
  20 +
  21 + }
  22 +
  23 + public $tag; // tag
  24 + public $sign; // 签名
  25 + public $rang; // 随机串
  26 + public $out_ip; // 代理出口ip
  27 + public $host; // 请求地址
  28 + public $timeOut; // 超时
  29 +
  30 +
  31 + private function check(){
  32 + list($this->tag, $this->sign ,$this->rang, $this->out_ip ,$this->host, $this->timeOut) = explode(' ', $this->data.' ');
  33 +
  34 + // 来源不对,直接关闭
  35 + if ($this->sign !== md5('fob.'.$this->rang)){
  36 + $this->error('签名验证失败');
  37 + }
  38 + // 没有出口ip
  39 +// if(!$this->out_ip){
  40 +// $this->error('出口ip不可空');
  41 +// }
  42 + // 没有代理地址
  43 + if(!$this->host){
  44 + $this->error('代理地址不可空');
  45 + }
  46 + $this->timeOut = intval($this->timeOut);
  47 +
  48 + $this->timeOut = $this->timeOut ? $this->timeOut : 5;
  49 +
  50 + }
  51 +
  52 + public function error($msg){
  53 + throw new Exception("500 ".$msg."\r\n");
  54 + }
  55 +
  56 +
  57 +}
  1 +<?php
  2 +
  3 +
  4 +class ImapClient {
  5 +
  6 + /**
  7 + * 资源
  8 + * @var resource|false
  9 + */
  10 + private $socket;
  11 +
  12 + protected bool $debug = false;
  13 +
  14 + protected string $host;
  15 +
  16 +
  17 + /**
  18 + * 是否是非阻塞模式
  19 + * @var bool
  20 + */
  21 + public $isBlocking = false;
  22 +
  23 + public function __construct(string $host){
  24 + $this->host = $host;
  25 + $this->socket = false;
  26 + }
  27 +
  28 +
  29 + /**
  30 + * 打开链接
  31 + * @param string $out_ip 这个是出口ip
  32 + * @param int $timeout // 连接超时时间
  33 + * @return bool|string
  34 + * @author:dc
  35 + * @time 2025/3/31 9:27
  36 + */
  37 + public function open(string $out_ip, int $timeout=3){
  38 + $content = stream_context_create([
  39 + 'ssl' => [
  40 + 'verify_peer' => false, // 有的证书和域名不匹配,这里关闭认证
  41 + 'verify_peer_name' => false,// 有的证书和域名不匹配,这里关闭认证
  42 + ],
  43 + 'socket' => [
  44 + 'bindto' => $out_ip.":0" // 绑定到指定的本地 IP 地址
  45 + ]
  46 + ]);
  47 +
  48 + $flags = STREAM_CLIENT_CONNECT;
  49 +
  50 + $this->socket = stream_socket_client(
  51 + $this->host,
  52 + $errno,
  53 + $error,
  54 + $timeout,
  55 + $flags,
  56 + $content
  57 + );
  58 +
  59 +
  60 + if($error){
  61 + return $error;
  62 + }
  63 +
  64 + if (!$this->socket) {
  65 + return $this->host." connection fail.";
  66 + }
  67 +
  68 + // 设置为非阻塞模式
  69 + $this->isBlocking = stream_set_blocking($this->socket, false);
  70 +
  71 + return true;
  72 + }
  73 +
  74 +
  75 +
  76 + protected $isRead = true;
  77 +
  78 + /**
  79 + * 写
  80 + * @param string $cmd
  81 + * @return false|int
  82 + * @author:dc
  83 + * @time 2024/9/13 15:47
  84 + */
  85 + public function write(string $cmd){
  86 + error_clear_last();
  87 + $num = @fwrite($this->socket, $cmd);
  88 + if(!$num){
  89 + $last = error_get_last();
  90 + if($last){
  91 + return $last['message']??'';
  92 + }
  93 + }
  94 + return $num;
  95 + }
  96 +
  97 + /**
  98 + * 读
  99 + * @return false|string
  100 + * @author:dc
  101 + * @time 2024/9/13 15:49
  102 + */
  103 + public function readLine(){
  104 +
  105 + return @fgets($this->socket,2048);
  106 +
  107 + }
  108 +
  109 + public function __destruct()
  110 + {
  111 + if($this->socket) @fclose($this->socket);
  112 + unset($this->socket);
  113 + // TODO: Implement __destruct() method.
  114 + }
  115 +
  116 +}
  1 +<?php
  2 +
  3 +/**
  4 + * 连接代理地址
  5 + * @author:dc
  6 + * @time 2025/3/31 11:27
  7 + * Class ImapClientSwoole
  8 + */
  9 +class ImapClientSwoole{
  10 +
  11 + protected $host = '';
  12 +
  13 + /**
  14 + * 连接
  15 + * @var \Swoole\Coroutine\Client
  16 + */
  17 + protected $client;
  18 +
  19 + public function __construct(string $host)
  20 + {
  21 + $this->host = $host;
  22 + }
  23 +
  24 + /**
  25 + * 打开连接
  26 + * @param string $out_ip
  27 + * @param int $timeout
  28 + * @return string
  29 + * @author:dc
  30 + * @time 2025/3/31 10:27
  31 + */
  32 + public function open(string $out_ip, int $timeout=3){
  33 + $client = new \Swoole\Coroutine\Client(SWOOLE_SOCK_TCP | SWOOLE_SSL);
  34 + $client->set([
  35 + 'timeout'=> $timeout,
  36 + 'ssl_verify_peer' => false,// 关闭证书验证
  37 + 'bind_address' => $out_ip,
  38 + 'bind_port' => 36002,
  39 + ]);
  40 +
  41 + $host = parse_url($this->host);
  42 +
  43 + if(!$client->connect($host['host'],$host['port'],$timeout)){
  44 + throw new Exception($this->host." connection fail. ".$client->errMsg);
  45 + }
  46 +
  47 + $this->client = $client;
  48 +
  49 + }
  50 +
  51 + /**
  52 + * 写
  53 + * @param string $cmd
  54 + * @return false|int
  55 + * @author:dc
  56 + * @time 2024/9/13 15:47
  57 + */
  58 + public function write(string $cmd){
  59 +
  60 + return $this->client->send($cmd);
  61 +
  62 + }
  63 +
  64 + /**
  65 + * 读
  66 + * @return false|string
  67 + * @author:dc
  68 + * @time 2024/9/13 15:49
  69 + */
  70 + public function readLine(){
  71 +
  72 + return $this->client->recv();
  73 +
  74 + }
  75 +
  76 +
  77 + public function __destruct()
  78 + {
  79 + if(!empty($this->client)) $this->client->close();
  80 + unset($this->client);
  81 + // TODO: Implement __destruct() method.
  82 + }
  83 +
  84 +
  85 +
  86 +}
  1 +<?php
  2 +
  3 +/**
  4 + * 连接代理地址
  5 + * @author:dc
  6 + * @time 2025/3/31 11:27
  7 + * Class ImapClientSwoole
  8 + */
  9 +class SmtpClient{
  10 +
  11 + protected $host = '';
  12 +
  13 + /**
  14 + * 连接
  15 + * @var \Swoole\Coroutine\Client
  16 + */
  17 + protected $client;
  18 +
  19 + public function __construct(string $host)
  20 + {
  21 + $this->host = $host;
  22 + }
  23 +
  24 + /**
  25 + * 打开连接
  26 + * @param string $out_ip
  27 + * @param int $timeout
  28 + * @return string
  29 + * @author:dc
  30 + * @time 2025/3/31 10:27
  31 + */
  32 + public function open(string $out_ip, int $timeout=3){
  33 + $client = new \Swoole\Coroutine\Client(SWOOLE_SOCK_TCP | SWOOLE_SSL);
  34 + $client->set([
  35 +// 'timeout'=> $timeout,
  36 + 'ssl_verify_peer' => false,// 关闭证书验证
  37 +// 'bind_address' => $out_ip,
  38 +// 'bind_port' => 36002,
  39 + ]);
  40 +
  41 + $host = parse_url($this->host);
  42 +
  43 + if(!$client->connect($host['host'],$host['port'],$timeout)){
  44 + throw new Exception($this->host." connection fail. ".$client->errMsg);
  45 + }
  46 +
  47 + $this->client = $client;
  48 +
  49 + }
  50 +
  51 + /**
  52 + * 写
  53 + * @param string $cmd
  54 + * @return false|int
  55 + * @author:dc
  56 + * @time 2024/9/13 15:47
  57 + */
  58 + public function write(string $cmd){
  59 + if($cmd === "DATA\r\n"){
  60 + $this->is_read = 1;
  61 + }
  62 + if($cmd === ".\r\n"){
  63 + $this->is_read = 0;
  64 + }
  65 + return $this->client->send($cmd);
  66 +
  67 + }
  68 +
  69 + protected $is_read = 0;
  70 +
  71 + /**
  72 + * 读
  73 + * @return false|string
  74 + * @author:dc
  75 + * @time 2024/9/13 15:49
  76 + */
  77 + public function readLine(){
  78 + if($this->is_read === 2){
  79 + return false;
  80 + }
  81 +
  82 + if($this->is_read === 1){
  83 + $this->is_read = 2;
  84 + }
  85 + return $this->client->recv();
  86 +
  87 + }
  88 +
  89 +
  90 + public function __destruct()
  91 + {
  92 + if(!empty($this->client)) $this->client->close();
  93 + unset($this->client);
  94 + // TODO: Implement __destruct() method.
  95 + }
  96 +
  97 +
  98 +
  99 +}
  1 +CidrBlock,Protocol,Port,Action,FirewallRuleDescription
  2 +0.0.0.0/0,TCP,10000-10200,ACCEPT,邮件代理端口
  3 +0.0.0.0/0,TCP,20053,ACCEPT,bt面板
  4 +0.0.0.0/0,TCP,8888,ACCEPT,宝塔Linux面板默认端口
  5 +0.0.0.0/0,TCP,8015,ACCEPT,网站
  6 +0.0.0.0/0,TCP,22,ACCEPT,Linux SSH登录
  1 +<?php
  2 +
  3 +error_reporting(E_ALL);
  4 +
  5 +ini_set("display_errors","off");
  6 +
  7 +
  8 +
  9 +/**
  10 + * TODO:: 这个文件请用root执行
  11 + * 这个文件请加ip白名单访问
  12 + */
  13 +
  14 +
  15 +function sign(){
  16 + return md5('fob.guaidong007'.date('ym').$_REQUEST['rand_str'].'=');
  17 +}
  18 +if($_SERVER['AUTH_VERIFY'] != sign()){
  19 + http_response_code(500);
  20 + echo 'auth error';
  21 + exit(1);
  22 +}
  23 +
  24 +
  25 +$body = file_get_contents("php://input");
  26 +
  27 +$body = base64_decode($body);
  28 +
  29 +$body = json_decode($body, true);
  30 +
  31 +define('CONF_FILNAME','/www/server/panel/vhost/nginx/tcp/mail.conf');
  32 +
  33 +
  34 +/**
  35 + * 保存配置
  36 + * @param $body
  37 + * @return int
  38 + * @author:dc
  39 + * @time 2025/4/14 22:54
  40 + */
  41 +//server {
  42 +// listen 10087; # 监听的端口
  43 +// proxy_pass smtp.gmail.com:465;
  44 +//}
  45 +function saveconfig($body){
  46 + $config = [];
  47 +
  48 + foreach ($body['proxys'] as $port=>$domain){
  49 + $config[] = "server {
  50 + listen {$port};
  51 + proxy_pass {$domain};
  52 +}";
  53 + }
  54 +
  55 + $config = implode("\n",$config);
  56 +
  57 + if(@file_put_contents(CONF_FILNAME,$config)){
  58 + return 200;
  59 + }
  60 +
  61 + return 500;
  62 +
  63 +}
  64 +
  65 +/**
  66 + * 重启nginx服务
  67 + * @return int
  68 + * @author:dc
  69 + * @time 2025/4/14 22:54
  70 + */
  71 +function reload(){
  72 + exec("nginx -s reload",$ret,$code);
  73 + return $code===0?200:500;
  74 +}
  75 +
  76 +/**
  77 + * 检查端口监听状态
  78 + * @param $body
  79 + * @author:dc
  80 + * @time 2025/4/14 22:53
  81 + */
  82 +function check_prot($body){
  83 + $ports = $body['prots'];
  84 + foreach ($ports as $port){
  85 + exec("netstat -ano | grep :$port",$ret,$code);
  86 + echo $port;
  87 + echo ":";
  88 + if(count($ret)>=1){
  89 + echo "1";
  90 + }else{
  91 + echo "0";
  92 + }
  93 + echo "\n";
  94 + }
  95 +}
  96 +
  97 +
  98 +echo call_user_func($body['action'],$body);
  99 +
  100 +
  101 +return 0;
  1 +<?php
  2 +
  3 +require_once "Auth.php";
  4 +require_once "ImapClientSwoole.php";
  5 +
  6 +
  7 +class ProxyService
  8 +{
  9 +
  10 + /**
  11 + * 连接数
  12 + * @var ImapClient[]
  13 + */
  14 + protected static $clients = [];
  15 +
  16 +
  17 + /**
  18 + * @author:dc
  19 + * @time 2025/3/29 14:34
  20 + */
  21 + public function run()
  22 + {
  23 + //创建Server对象,监听 127.0.0.1:9501 端口。
  24 + $server = new Swoole\Server('0.0.0.0', 9527, SWOOLE_PROCESS, SWOOLE_SOCK_TCP);
  25 +
  26 + //监听连接进入事件。
  27 + $server->on('Connect', function ($server, $fd) {});
  28 +
  29 + //监听数据接收事件。
  30 + $server->on('Receive', function ($server, $fd, $reactor_id, $data) {
  31 + // 建立连接
  32 + if (empty(self::$clients[$fd])) {
  33 +
  34 + try {
  35 + $auth = new Auth($data);
  36 + }catch (Throwable $e){
  37 + $server->send($fd, $e->getMessage());
  38 + $server->close($fd,true);
  39 + return;
  40 + }
  41 + // 创建一个客户端
  42 + self::$clients[$fd] = new ImapClientSwoole($auth->host);
  43 + // 连接客户端
  44 + try {
  45 + self::$clients[$fd]->open($auth->out_ip, $auth->timeOut);
  46 + }catch (Throwable $e){
  47 + $server->send($fd, $auth->tag . ' BAD ' . $e->getMessage()."\r\n");
  48 + $server->close($fd,true);
  49 + return;
  50 + }
  51 + // 发送成功消息
  52 + $server->send($fd, $auth->tag . " OK The proxy server is successfully connected.\r\n");
  53 +
  54 + // 读取数据
  55 + while (1){
  56 + if (empty(self::$clients[$fd])){
  57 + break;
  58 + }
  59 + $line = self::$clients[$fd]->readLine();
  60 + if($line){
  61 + echo '读取到 => '.$line;
  62 + $server->send($fd,$line);
  63 + }else{
  64 + co::sleep(0.1);
  65 + }
  66 + }
  67 +
  68 + } // 正式请求转发
  69 + else {
  70 + // 没有连接成功
  71 + if(empty(self::$clients[$fd])){
  72 + $server->send($fd, " No proxy server.\r\n");
  73 + $server->close($fd,true);
  74 + return;
  75 + }
  76 + // 请求数据
  77 + $writeNumber = self::$clients[$fd]->write($data);
  78 + list($tag,$cmd) = explode(' ',$data,2);
  79 + // 退出命令就不等待服务器了
  80 + if(trim($cmd) == 'LOGOUT'){
  81 + $server->send($fd, $tag." OK bye.\r\n");
  82 + $server->close($fd,true);
  83 + return;
  84 + }
  85 + if($writeNumber){
  86 + echo '成功写入 => '.$data;
  87 + }else{
  88 + echo '写入失败 => '.$data;
  89 + $server->send($fd,$tag.' BAD '.$writeNumber."\r\n");
  90 + }
  91 + }
  92 + });
  93 +
  94 + //监听连接关闭事件。
  95 + $server->on('Close', function ($server, $fd) {
  96 + echo '连接关闭了 => '.$fd."\n";
  97 + // 关闭并释放资源
  98 + self::$clients[$fd] = null;
  99 + unset(self::$clients[$fd]);
  100 + });
  101 +
  102 + //启动服务器
  103 + $server->start();
  104 + }
  105 +
  106 +}
  107 +
  108 +
  109 +(new ProxyService())->run();
  1 +<?php
  2 +
  3 +require_once "Auth.php";
  4 +require_once "SmtpClient.php";
  5 +
  6 +
  7 +class ProxyService
  8 +{
  9 +
  10 + /**
  11 + * 连接数
  12 + * @var SmtpClient[]
  13 + */
  14 + protected static $clients = [];
  15 +
  16 +
  17 + protected function push(...$params){
  18 + echo co::getCid()." => ";
  19 + echo implode(' => ',$params);
  20 + return $params;
  21 + }
  22 +
  23 + /**
  24 + * @author:dc
  25 + * @time 2025/3/29 14:34
  26 + */
  27 + public function run()
  28 + {
  29 + //创建Server对象,监听 127.0.0.1:9501 端口。
  30 + $server = new Swoole\Server(
  31 + '0.0.0.0', 9527,
  32 + SWOOLE_BASE,
  33 + SWOOLE_SOCK_TCP//|SWOOLE_SSL
  34 + );
  35 +
  36 + //监听连接进入事件。
  37 + $server->on('Connect', function ($server, $fd) {
  38 + $server->send($fd, "220 proxy client ok\r\n");
  39 + });
  40 +
  41 + //监听数据接收事件。
  42 + $server->on('Receive', function ($server, $fd, $reactor_id, $data) {
  43 +// echo "in ".co::getCid()." ==> ".$data."\n";
  44 + // 建立连接
  45 + if (empty(self::$clients[$fd])) {
  46 +
  47 + try {
  48 + $auth = new Auth($data);
  49 + }catch (Throwable $e){
  50 + $server->send($fd, $e->getMessage());
  51 + $server->close($fd,true);
  52 + return;
  53 + }
  54 + // 创建一个客户端
  55 + self::$clients[$fd] = new SmtpClient($auth->host);
  56 + // 连接客户端
  57 + try {
  58 + self::$clients[$fd]->open($auth->out_ip, $auth->timeOut);
  59 + }catch (Throwable $e){
  60 + $server->send($fd, '500 ' . $e->getMessage()."\r\n");
  61 + $server->close($fd,true);
  62 + return;
  63 + }
  64 +
  65 + $line = self::$clients[$fd]->readLine();
  66 +
  67 + if($line) $server->send($fd,$line);
  68 +
  69 + // 发送成功消息
  70 +// $server->send($fd, "200 OK The proxy server is successfully connected.\r\n");
  71 +
  72 + } // 正式请求转发
  73 + else {
  74 + // 没有连接成功
  75 + if(empty(self::$clients[$fd])){
  76 + $server->send($fd, "500 No proxy server.\r\n");
  77 + $server->close($fd,true);
  78 + return;
  79 + }
  80 + // 请求数据
  81 + self::$clients[$fd]->write($data);
  82 +
  83 +
  84 + $line = self::$clients[$fd]->readLine();
  85 +
  86 +// echo 'out '.co::getCid()." => ".$line;
  87 +
  88 + if($line!==false) $server->send($fd,$line);
  89 +
  90 + }
  91 + });
  92 +
  93 + //监听连接关闭事件。
  94 + $server->on('Close', function ($server, $fd) {
  95 +// echo '连接关闭了 => '.$fd."\n";
  96 + // 关闭并释放资源
  97 + self::$clients[$fd] = null;
  98 + unset(self::$clients[$fd]);
  99 + });
  100 +
  101 + //启动服务器
  102 + $server->start();
  103 + }
  104 +
  105 +}
  106 +
  107 +
  108 +(new ProxyService())->run();
  1 +<?php
  2 +
  3 +require_once "../vendor/autoload.php";
  4 +
  5 +
  6 +
  7 +
  8 +print_r(\Lib\Mail\MailFun::sendEmail([
  9 + 'tos' => [['email'=>'200582249@qq.com']],
  10 + 'subject' => 'xt',
  11 + 'body' => '测试'
  12 +],[
  13 + 'smtp' => 'test.mailhagro.com:25',
  14 +// 'proxy' => '64.34.217.96:51395',
  15 + 'email' => 'ma@mailhagro.com',
  16 + 'password' => base64_encode('aB12345678'),
  17 +],true));
  18 +exit();
  19 +
  20 +$a = \Lib\Imap\ImapPool::get(
  21 + (new \Lib\Imap\ImapConfig())
  22 + ->setEmail('200582249@qq.com')
  23 + ->setPassword('ztqxrjckdzmccahc')
  24 + ->setHost('imap.qq.com')
  25 + ->proxy('tcp://104.221.245.130:9527')
  26 + ->debug()
  27 +);
  28 +
  29 +
  30 +$a->login()->isOk();
@@ -39,33 +39,41 @@ class MailProxy { @@ -39,33 +39,41 @@ class MailProxy {
39 'smtp.gmail.com:465' => '10087', 39 'smtp.gmail.com:465' => '10087',
40 'imap.gmail.com:993' => '10086', 40 'imap.gmail.com:993' => '10086',
41 41
42 - 'imap-mail.outlook.com:993' => '10088',  
43 - 'smtp-mail.outlook.com:465' => '10089',  
44 -  
45 - 'imap.mail.yahoo.com:993' => '10092',  
46 - 'smtp.mail.yahoo.com:465' => '10093',  
47 -  
48 - 'imaphz.qiye.163.com:993' => '10080',  
49 - 'smtphz.qiye.163.com:465' => '10081',  
50 -  
51 - 'imap.qiye.aliyun.com:993' => '10094',  
52 - 'smtp.qiye.aliyun.com:465' => '10095',  
53 -  
54 -// 'imap.qq.com:993' => '10096',  
55 -// 'smtp.qq.com:465' => '10097',  
56 -  
57 ]; 42 ];
58 43
59 /** 44 /**
60 * 代理服务器 地址 45 * 代理服务器 地址
61 * @var string[] 46 * @var string[]
62 */ 47 */
63 - protected $proxyService = [ 48 + public static $proxyService = [
64 '43.134.162.250', // 这个是新加坡服务器 代理 49 '43.134.162.250', // 这个是新加坡服务器 代理
65 '119.28.113.113', // 这个是新加坡服务器 代理02 50 '119.28.113.113', // 这个是新加坡服务器 代理02
  51 +
  52 +
  53 +
66 '43.154.117.107', // 这个是 shopk的那台服务器 54 '43.154.117.107', // 这个是 shopk的那台服务器
67 ]; 55 ];
68 56
  57 +
  58 + /**
  59 + * 读取代理ip 随机打乱
  60 + * @return string[]
  61 + * @author:dc
  62 + * @time 2025/4/15 15:49
  63 + */
  64 + public static function getProxy(){
  65 + $host = self::$proxyService;
  66 + foreach ($host as $k => $v){
  67 + if($v =='43.154.117.107'){
  68 + unset($host[$k]);
  69 + }
  70 + }
  71 +
  72 + shuffle($host);
  73 +
  74 + return $host;
  75 + }
  76 +
69 /** 77 /**
70 * 分配到的ip服务 78 * 分配到的ip服务
71 * @var string 79 * @var string
@@ -96,8 +104,13 @@ class MailProxy { @@ -96,8 +104,13 @@ class MailProxy {
96 $this->defaultIp = $default; 104 $this->defaultIp = $default;
97 } 105 }
98 106
99 - // 先分配  
100 - $this->assignEmail(); 107 + // 只分配gmail
  108 + if(stripos($smtp,".gmail.com")){
  109 + $this->assignEmail();
  110 + }else{
  111 + $this->assignIp = false;
  112 + }
  113 +
101 114
102 $this->originImapHost = $imap; 115 $this->originImapHost = $imap;
103 116
@@ -169,7 +182,7 @@ class MailProxy { @@ -169,7 +182,7 @@ class MailProxy {
169 $serve = strtolower(empty($host['host']) ? $host['path'] : $host['host']); 182 $serve = strtolower(empty($host['host']) ? $host['path'] : $host['host']);
170 183
171 // 传入的是代理地址 并且是数据库里面已分配的ip 184 // 传入的是代理地址 并且是数据库里面已分配的ip
172 - if(in_array($serve,$this->proxyService)){ 185 + if(in_array($serve,$this::$proxyService)){
173 // 传入的服务器 和 分配的不一致 更新分配的 186 // 传入的服务器 和 分配的不一致 更新分配的
174 if($serve != $this->assignIp){ 187 if($serve != $this->assignIp){
175 $this->assignIp = $serve; 188 $this->assignIp = $serve;
@@ -186,7 +199,7 @@ class MailProxy { @@ -186,7 +199,7 @@ class MailProxy {
186 // 返回不代理 199 // 返回不代理
187 $this->assignIp = $serve; 200 $this->assignIp = $serve;
188 }else{ 201 }else{
189 - if(in_array($this->assignIp,$this->proxyService)){ 202 + if(in_array($this->assignIp,$this::$proxyService)){
190 $port = $this->config[$serve.':'.$port]; // 代理服务器端口 203 $port = $this->config[$serve.':'.$port]; // 代理服务器端口
191 } 204 }
192 } 205 }
@@ -208,7 +221,7 @@ class MailProxy { @@ -208,7 +221,7 @@ class MailProxy {
208 private function assignEmail(){ 221 private function assignEmail(){
209 $data = db()->throw()->first('select * from mail_proxy where email = "'.$this->email.'"'); 222 $data = db()->throw()->first('select * from mail_proxy where email = "'.$this->email.'"');
210 // 存在记录 并且 还在服务器列表 223 // 存在记录 并且 还在服务器列表
211 - if($data && in_array($data['ip'],$this->proxyService)){ 224 + if($data && in_array($data['ip'],$this::$proxyService)){
212 $this->assignIp = $data['ip']; 225 $this->assignIp = $data['ip'];
213 return ; 226 return ;
214 } 227 }
@@ -238,12 +251,12 @@ class MailProxy { @@ -238,12 +251,12 @@ class MailProxy {
238 251
239 // 一个月活跃用户 252 // 一个月活跃用户
240 $t = date('Y-m-d H:i:s',strtotime("-30 day")); 253 $t = date('Y-m-d H:i:s',strtotime("-30 day"));
241 - foreach ($this->proxyService as $ip){ 254 + foreach ($this::$proxyService as $ip){
242 // shopk的不分配 255 // shopk的不分配
243 if($ip=='43.154.117.107'){ 256 if($ip=='43.154.117.107'){
244 continue; 257 continue;
245 } 258 }
246 - $num = db()->count("select count(*) from `mail_proxy` where `status` = 1 and `time` > '{$t}' and `ip` = '{$ip}'"); 259 + $num = db()->count("select count(*) from `mail_proxy` where `status` = 1 and `ip` = '{$ip}'");
247 // 每个ip分配1000个 260 // 每个ip分配1000个
248 if($num<1000){ 261 if($num<1000){
249 $this->assignIp = $ip; 262 $this->assignIp = $ip;
@@ -301,6 +314,14 @@ class MailProxy { @@ -301,6 +314,14 @@ class MailProxy {
301 } 314 }
302 315
303 316
  317 + public function toArray(){
  318 + return [
  319 + 'smtp' => $this->getOriginSmtpHost(),
  320 + 'imap' => $this->getOriginImapHost(),
  321 + 'proxy_smtp' => $this->getSmtpProxy(),
  322 + 'proxy_imap' => $this->getImapProxy(),
  323 + ];
  324 + }
304 325
305 } 326 }
306 327