From b1b0655cc078c655893fb9f63a4949d1135d53f4 Mon Sep 17 00:00:00 2001 From: Formerly 3Kmfi6HP <3kmfi6hp@rtt.icu> Date: Fri, 27 Mar 2026 12:28:55 +0700 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20Cloudflare=20=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=20Emoji/IDN=20=E5=9F=9F=E5=90=8D=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=E4=B8=BB=E6=9C=BA=E5=90=8D=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E9=94=99=E8=AF=AF=20(#420)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/lib/dns/cloudflare.php | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/app/lib/dns/cloudflare.php b/app/lib/dns/cloudflare.php index 9c9a8df..03d972b 100644 --- a/app/lib/dns/cloudflare.php +++ b/app/lib/dns/cloudflare.php @@ -25,6 +25,27 @@ class cloudflare implements DnsInterface $this->auth = isset($config['auth']) ? intval($config['auth']) : (preg_match('/^[0-9a-f]+$/i', $this->ApiKey) ? 0 : 1); } + /** + * 从 Cloudflare API 返回的完整域名中提取子域名(主机记录) + * 兼容 Emoji/IDN 域名:Cloudflare API 返回 Punycode 格式,数据库存储 UTF-8 + */ + private function extractName($fullName) + { + $domainAscii = idn_to_ascii($this->domain, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46); + if ($domainAscii === false) $domainAscii = $this->domain; + + if ($fullName === $domainAscii || $fullName === $this->domain) { + return '@'; + } + if (str_ends_with($fullName, '.' . $domainAscii)) { + return substr($fullName, 0, -(strlen($domainAscii) + 1)); + } + if (str_ends_with($fullName, '.' . $this->domain)) { + return substr($fullName, 0, -(strlen($this->domain) + 1)); + } + return $fullName; + } + public function getError() { return $this->error; @@ -66,8 +87,9 @@ class cloudflare implements DnsInterface if (!isNullOrEmpty($Value)) $KeyWord = $Value; $param = ['type' => $Type, 'search' => $KeyWord, 'page' => $PageNumber, 'per_page' => $PageSize]; if (!isNullOrEmpty($SubDomain)) { - if ($SubDomain == '@') $SubDomain = $this->domain; - else $SubDomain .= '.' . $this->domain; + $domainAscii = idn_to_ascii($this->domain, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46) ?: $this->domain; + if ($SubDomain == '@') $SubDomain = $domainAscii; + else $SubDomain .= '.' . $domainAscii; $param['name'] = $SubDomain; } if (!isNullOrEmpty($Line)) { @@ -77,7 +99,7 @@ class cloudflare implements DnsInterface if ($data) { $list = []; foreach ($data['result'] as $row) { - $name = $this->domain == $row['name'] ? '@' : substr($row['name'], 0, -(strlen($this->domain) + 1)); + $name = $this->extractName($row['name']); $status = str_ends_with($name, '_pause') ? '0' : '1'; $name = $name == '__root__' ? '@' : $name; $name = $status == '0' ? substr($name, 0, -6) : $name; @@ -115,7 +137,7 @@ class cloudflare implements DnsInterface { $data = $this->send_reuqest('GET', '/zones/'.$this->domainid.'/dns_records/'.$RecordId); if ($data) { - $name = $this->domain == $data['result']['name'] ? '@' : substr($data['result']['name'], 0, -(strlen($this->domain) + 1)); + $name = $this->extractName($data['result']['name']); $status = str_ends_with($name, '_pause') ? '0' : '1'; $name = $status == '0' ? substr($name, 0, -6) : $name; $name = $name == '__root__' ? '@' : $name;