楚狐在线 - 资讯杂烩
资讯杂烩   在线工具   益智游戏   影音娱乐   网站导航

Cloudflare域名云解析服务(DNS)API接口PHP封装


  目前互联网上提供免费的域名托管服务的厂家很多,如阿里云/万网、腾讯云、CloudFlare、华为云等等,我们将域名托管到这些云解析DNS服务商后,虽然服务商都提供了控制台用于域名及解析记录的管理,但是有时候如果我们需要自己实现DDNS动态域名解析等一些基于官网API接口能力的功能,就需要使用到官网提供的API能力,本文将针对Cloudflare的API接口,通过PHP封装了常用的函数类,用于托管域名、记录集等的管理。
  本文旨在帮助开发者快速使用集成Cloudflare域名云解析服务(DNS)的API接口,实现对域名(Zone)和解析记录(Record Set)的自动化管理,如域名托管、记录添加及修改等。
  阿里云API官方文档地址详见:https://developers.cloudflare.com/api/resources/dns/subresources/records
  下面是PHP实现的API封装类,代码如下:

//************************开始Cloudflare的解析处理******************************//
/**
 * Cloudflare的域名DNS云解析API封装类
 * api文档地址:https://developers.cloudflare.com/api/operations/dns-records-for-a-zone-list-dns-records
 * 引用或者使用本文,请注明来源:楚狐在线- https://chuhu.org
**/
class DNSCloudflare
{
	//x_api_token、x_auth_key 在request_post函数里面切换,当前用API 令牌x_api_token
	// API 令牌,获取步骤:我的个人资料 > API 令牌 > 上面的API 令牌 > 创建令牌 > 编辑区域 DNS	(使用模板)
	// API 密钥 Global API Key,获取步骤:My profile > API Tokens > 下面的API Keys > Global API Key > View
	private $x_api_token = '*************'; 
	private $x_account_id = '*********'; 
	private $x_email = 'example@example.com'; // 您的cf注册邮箱地址
	protected static $obj  = null;

	public static function Obj ()
	{
		//if(is_null(self::$obj))	//2025年4月27日
		if(is_null(static::$obj))
		{
			self::$obj = new self();
		}
		return self::$obj;
	}

	// 允许构造方法初始化 token 2025年4月27日增加
	protected function __construct($para = null) {
		if ($para === "OTHER_ACCOUNT") {
			$this->x_api_token = 'Gl*******************'; 
			$this->x_account_id = '***********';
			$this->x_email = 'OTHER_ACCOUNT@example.com';
		}
	}

	//列出当前用户名下所有域名,返回数组
	//数组内容包括:域名name,域名id,域名状态status
	//不翻页,默认显示100个
	//与ZonesList差异:只显示域名,id,状态三个内容,其他的不显示
	public function DomainListAll()
	{
		$curl_url = "https://api.cloudflare.com/client/v4/zones?page=1&per_page=100";
		$curl_request = "GET";
		$rtn = $this->request_post($curl_url,$curl_request);
		$dml = $rtn['result'];
		$final_list = array();
		foreach ($dml as $k => $oneZone) {
			$final_list[] = array(
			'domain' => strtolower($oneZone['name']),
			'id' => $oneZone['id'],
			'status' => $oneZone['status']
			);
		}
		return $final_list;
	}

	//查询域名的对应zond_id
	public function DomainIDQuery($domain)
	{
		$dmid = null;
		$curl_url = "https://api.cloudflare.com/client/v4/zones?page=1&per_page=100";
		$curl_request = "GET";
		$rtn = $this->request_post($curl_url,$curl_request);
		$dml = $rtn['result'];
		$final_list = array();
		foreach ($dml as $k => $oneZone) {
			if(strtolower($oneZone['name'])==strtolower($domain))
			{
				$dmid = $oneZone['id'];
			}
		}
		return $dmid;
	}

	//根据域名zone_id查询当前域名解析记录
	//返回数组
	public function DNSRecordsList($zone_id)
	{
		$curl_url = "https://api.cloudflare.com/client/v4/zones/".$zone_id."/dns_records";
		$curl_request = "GET";
		$rtn = $this->request_post($curl_url,$curl_request);
		//print_r($rtn);
		return $rtn;
	}

	//根据域名zone_id、记录ID查询当前域名解析记录
	//返回数组
	public function DNSRecordDetails($zone_id, $dns_record_id)
	{
		$curl_url = "https://api.cloudflare.com/client/v4/zones/".$zone_id."/dns_records/".$dns_record_id;
		$curl_request = "GET";
		$rtn = $this->request_post($curl_url,$curl_request);
		//print_r($rtn);
		return $rtn;
	}

	//创建新记录
	//$domain_name 完整的二级或三级域名
	//返回数组
	public function CreateDNSRecord($zone_id, $domain_name, $content, $type="A", $proxied=false, $ttl=60, $comment="")
	{
		$curl_url = "https://api.cloudflare.com/client/v4/zones/".$zone_id."/dns_records";
		$curl_request = "POST";
		$data = array(
			'comment' => $comment,
			'content' => $content,
			'name' => $domain_name,
			'proxied' => $proxied, // true启用代理,false禁用代理
			'type' => $type,
			'ttl' => $ttl  // 数字1代表自动ttl
		);
		$rtn = $this->request_post($curl_url,$curl_request,$data);
		return $rtn;
	}

	//删除DNS Record
	//$domain_name 完整的二级或三级域名
	//返回数组
	public function DeleteDNSRecord($zone_id, $dns_record_id)
	{
		$curl_url = "https://api.cloudflare.com/client/v4/zones/".$zone_id."/dns_records/".$dns_record_id;
		$curl_request = "DELETE";
		$rtn = $this->request_post($curl_url,$curl_request);
		return $rtn;
	}

	//DDNS更新处理,首先查询域名解析记录是否一致
	//$domain_name 完整的二级或三级域名
	//主要用于DDNS的更新
	//与UpdateDNSRecord传入参数一样,增加了记录值是否存在的判断。
	public function ModifyDynamicDNS($zone_id,$dns_record_id,$domain_name,$new_ip,$type,$proxied,$ttl)
	{
		$data = $this->DNSRecordDetails($zone_id, $dns_record_id);
		if($data['success'])
		{
			if($data['result']['content']==$new_ip)
			{
				echo "处理完成:".$domain_name."当前".$data['result']['type']."记录【".$data['result']['content']."】与新值【".$new_ip."】一致,无需修改。";
			}
			else 
			{
				$curl_url = "https://api.cloudflare.com/client/v4/zones/".$zone_id."/dns_records/".$dns_record_id;
				$curl_request = "PUT";
				$data1 = array(
					'content' => $new_ip,
					'name' => $domain_name,
					'proxied' => $proxied, // true启用代理,false禁用代理
					'type' => $type,
					'ttl' => $ttl  // 数字1代表自动ttl
				);
				$rtn = $this->request_post($curl_url,$curl_request,$data1);
				if($rtn['success'])
				{
					echo "处理完成:".$domain_name."的".$data['result']['type']."记录【".$data['result']['content']."】已修改为【".$new_ip."】。";
				}
				else
				{
					echo "处理失败:".$rtn['errors'][0]['message']."(code=".$rtn['errors'][0]['code'].")";
				}
			}
		} else {
			echo "错误:".$data['errors'][0]['message']."(code=".$data['errors'][0]['code'].")";
		}
	}

	//DDNS更新处理,若域名记录不存在,则直接创建 (DDNS主用)
	//$domain_name 完整的二级或三级域名
	//$sub_domain  只要名称,不需要完整的。
	//主要用于DDNS的更新
	//与UpdateDNSRecord传入参数一样,增加了记录值是否存在的判断。
	public function ModifyDynamicDNS2($sub_domain,$domain_name,$new_ip,$type="A",$proxied=false,$ttl=60)
	{
		if($sub_domain=="@"){
			$sub_domain = $domain_name;
		} else {
			$sub_domain = $sub_domain.".".$domain_name;
		}
		$zone_id = $this->DomainIDQuery($domain_name);
		$RecordsList = $this->DNSRecordsList($zone_id);
		$data = array_filter($RecordsList['result'], function($item) use ($sub_domain, $type) {
				return $item['name'] === $sub_domain && $item['type'] === $type;
		});
		$data = array_values($data); //重构数组,删除空
		$rc = count($data);
		if($rc==0)
		{
			//没有记录, 创建按记录。
			$rtn = $this->CreateDNSRecord($zone_id, $sub_domain, $new_ip, $type, $proxied, $ttl);
			if($rtn['success'])
			{
				echo "域名".$sub_domain."创建成功,并配置".$type."记录为:".$new_ip;
			}
		}
		else if($rc>1)
		{
			echo "域名".$sub_domain."的".$type."记录有".$rc."条,更新记录失败!";
		} else {
			$dns_record_id = $data[0]['id'];
			if($data[0]['content']==$new_ip){
				echo "处理完成:".$sub_domain."当前".$data[0]['type']."记录【".$data[0]['content']."】与新值【".$new_ip."】一致,无需修改。";
			} else {
				$curl_url = "https://api.cloudflare.com/client/v4/zones/".$zone_id."/dns_records/".$dns_record_id;
				$curl_request = "PUT";
				$data1 = array(
					'content' => $new_ip,
					'name' => $sub_domain,
					'proxied' => $proxied, // true启用代理,false禁用代理
					'type' => $type,
					'ttl' => $ttl  // 数字1代表自动ttl
				);
				$rtn = $this->request_post($curl_url,$curl_request,$data1);
				if($rtn['success'])
				{
					echo "处理完成:".$sub_domain."的".$data[0]['type']."记录【".$data[0]['content']."】已修改为【".$new_ip."】。";
				}
				else
				{
					echo "处理失败:".$rtn['errors'][0]['message']."(code=".$rtn['errors'][0]['code'].")";
				}
			}
		}
	}

	//查询当前账户下的所有域及每个域的详细信息,List Zones,返回数组
	//$zone_id 为空则输出当前账号下所有域名
	public function ZonesList($zone_id=null)
	{
		$curl_url = "https://api.cloudflare.com/client/v4/zones";
		if(!empty($zone_id))
		{
			$curl_url = $curl_url."/".$zone_id;
		} else
		{
			$curl_url = $curl_url."?page=1&per_page=100";
		}
		$curl_request = "GET";
		$rtn = $this->request_post($curl_url,$curl_request);
		return $rtn;
	}

	//查询当前账户下的所有域及每个域的详细信息,List Zones,输出为html
	public function ZonesListHtml()
	{
		$curl_url = "https://api.cloudflare.com/client/v4/zones";
		if(!empty($zone_id))
		{
			$curl_url = $curl_url."/".$zone_id;
		} else
		{
			$curl_url = $curl_url."?page=1&per_page=100";
		}
		$curl_request = "GET";
		$this->request_post_html($curl_url,$curl_request);
	}

	//根据$zone_id查询该域名下的所有DNS解析记录,List DNS Records,输出html
	public function DNSRecordsListHTML($zone_id)
	{
		$curl_url = "https://api.cloudflare.com/client/v4/zones/".$zone_id."/dns_records";
		$curl_request = "GET";
		$this->request_post_html($curl_url,$curl_request);
	}

	//Update DNS Record,输入为html
	//$domain_name 完整的二级或三级域名
	//根据传入的$new_ip,$type,$proxied,$ttl,更新域名记录
	public function UpdateDNSRecordHtml($zone_id,$dns_record_id,$domain_name,$new_ip,$type,$proxied,$ttl)
	{
		$curl_url = "https://api.cloudflare.com/client/v4/zones/".$zone_id."/dns_records/".$dns_record_id;
		$curl_request = "PUT";
		$data = array(
			'content' => $new_ip,
			'name' => $domain_name,
			'proxied' => $proxied, // true启用代理,false禁用代理
			'type' => $type,
			'ttl' => $ttl  // 数字1代表自动ttl
		);
		$this->request_post_html($curl_url,$curl_request,$data);
	}

	//Update DNS Record,返回数组
	//$domain_name 完整的二级或三级域名
	//根据传入的$new_ip,$type,$proxied,$ttl,更新域名记录
	public function UpdateDNSRecord($zone_id,$dns_record_id,$domain_name,$new_ip,$type,$proxied,$ttl)
	{
		$curl_url = "https://api.cloudflare.com/client/v4/zones/".$zone_id."/dns_records/".$dns_record_id;
		$curl_request = "PUT";
		$data = array(
			'content' => $new_ip,
			'name' => $domain_name,
			'proxied' => $proxied, // true启用代理,false禁用代理
			'type' => $type,
			'ttl' => $ttl  // 数字1代表自动ttl
		);
		$rtn = $this->request_post($curl_url,$curl_request,$data);
		return $rtn;
	}

	//增加域名 Create Zone
	public function CreateZone($domain)
	{
		$curl_url = "https://api.cloudflare.com/client/v4/zones";
		$curl_request = "POST";
		$accid = array( 'id' => "{$this->x_account_id}" );
		$data = array(
			'account' => $accid,
			'name' => $domain,
			'type' => "full"
		);
		$rtn = $this->request_post($curl_url,$curl_request,$data);
		return $rtn;
	}

	//删除域名 Delete Zone
	public function DeleteZone($zone_id)
	{
		$curl_url = "https://api.cloudflare.com/client/v4/zones/".$zone_id;
		$curl_request = "DELETE";
		$rtn = $this->request_post($curl_url,$curl_request);
		return $rtn;
	}

	//增加域名 Edit Zone
	//dns 为dns数组 $dns = array('ns1.nishui.com','ns2.nishui.com');
	public function EditZoneDNS($zone_id, $dns)
	{
		$curl_url = "https://api.cloudflare.com/client/v4/zones/".$zone_id;
		$curl_request = "PATCH";
		$data = array(
			'type' => "full",
			'vanity_name_servers' => $dns
		);
		$rtn = $this->request_post($curl_url,$curl_request,$data);
		return $rtn;
	}

	//域名激活检查 Activation Check
	//返回true or false
	//注意:每小时每个域名执行一次,否则返回false:You may only perform this action once per hour.
	public function ZoneActivationCheck($zone_id)
	{
		$curl_url = "https://api.cloudflare.com/client/v4/zones/".$zone_id."/activation_check";
		$curl_request = "PUT";
		$rtn = $this->request_post($curl_url,$curl_request);
		if($rtn['success'])
		{
			if($rtn['messages'][0]['code']=='10002') return true;
			else return false;
		}
		else
		{
			return false;
		}
	}

	/**
	 * 批量操作 DNS 记录 (创建、修改、删除)
	 * 调用方法如下
	 BatchDNSRecords($zone_id, $adds, $updates, $deletes);
	 BatchDNSRecords($zone_id, $adds, [], []);
	 BatchDNSRecords($zone_id, [], $updates, []);
	 BatchDNSRecords($zone_id, [], [], $deletes);
	 * 参考官方文档: https://developers.cloudflare.com/api/resources/dns/subresources/records/methods/batch
	 * * @param string $zone_id    区域ID ,可以用 DomainIDQuery($domain) 获取
	 * @param array  $adds       需要新增的记录数组,每项包含: name, type, content, ttl(可选), proxied(可选), comment(可选),格式参考如下:
		$adds = [
			[
				'name' => 'test1.truhoo.win',
				'type' => 'A',
				'content' => '1.1.1.1',
				'proxied' => false,
				'ttl' => 60
			],
		];
	 * @param array  $updates    需要修改的记录数组,每项包含: id, name, type, content, ttl(可选), proxied(可选), comment(可选) (在批量中官方底层通常对应 puts/patches),格式参考如下:
		$updates = [
			[
				'id' => 'c988db3fe4dab0b159ba1066f9bdc12f',  //除了ID其他的都可以修改。
				'name' => 't21.truhoo.win', 
				'type' => 'A', 
				'content' => '3.3.13.13',
				'proxied' => false,
				'comment' => 'comment',
				'ttl' => 60
			],
		];
	 * @param array  $deletes    需要删除的记录数组,每项包含: id,格式参考如下:
		$deletes = [
			['id' => '57ffb097803f56cf6653c1552b476411'],
			['id' => '8a46ced175ef3721819185a791a8b17e'],
		];
	 * @return array 返回 API 请求结果
	**/
	public function BatchDNSRecords($zone_id, $adds = [], $updates = [], $deletes = [])
	{
		$url = "https://api.cloudflare.com/client/v4/zones/".$zone_id."/dns_records/batch";
		
		$payload = array();

		// 1. 批量增加:官方最新文档规定的键名为 'posts' (注意不是 adds)
		if (is_array($adds) && !empty($adds)) {
			$payload['posts'] = array_values($adds);
		}

		// 2. 批量局部修改:官方键名为 'patches'
		if (is_array($updates) && !empty($updates)) {
			$payload['patches'] = array_values($updates);
		}

		// 3. 批量删除:官方键名为 'deletes'
		if (is_array($deletes) && !empty($deletes)) {
			$payload['deletes'] = array_values($deletes);
		}

		// 如果三个操作全是空的,直接拦截,不浪费 API 请求
		if (empty($payload)) {
			return array("success" => false, "errors" => [["code" => 0, "message" => "未传入任何操作数据"]]);
		}
		
		// 强行转换为严格的 JSON 字符串
		$json_data = json_encode($payload);
		
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); 
		curl_setopt($ch, CURLOPT_POSTFIELDS, $json_data);
		curl_setopt($ch, CURLOPT_TIMEOUT, 30);
		curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
		
		curl_setopt($ch, CURLOPT_HTTPHEADER, [
			"Content-Type: application/json",
			"Content-Length: " . strlen($json_data),
			"Authorization: Bearer {$this->x_api_token}",
			"X-Auth-Email: {$this->x_email}"
		]);
		
		$response = curl_exec($ch);
		$err = curl_error($ch);
		curl_close($ch);
		
		if ($err) {
			return array("success" => false, "errors" => [["code" => 0, "message" => "cURL 错误: " . $err]]);
		} else {
			return (array) json_decode($response, true);
		}
	}

	//构建cloudflare请求参数,返回数组
	//$url:请求的地址
	//$param:请求的方法:GET,PUT,PATCH
	//$data=null:请求参数,array,可以为null
	function request_post($url, $param, $data=null) 
	{
		if (empty($url) || empty($param))
		{
			return "缺少必要的URL地址或request参数!";
			exit;
		}
		$curl = curl_init();
		$setopts  = array(
			CURLOPT_URL => $url,
			CURLOPT_RETURNTRANSFER => true,
			CURLOPT_ENCODING => "",
			CURLOPT_MAXREDIRS => 10,
			CURLOPT_TIMEOUT => 30,
			CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
			CURLOPT_CUSTOMREQUEST => $param,
			CURLOPT_HTTPHEADER => [
				"Content-Type: application/json",
				//"X-Auth-Key: {$this->x_auth_key}",
				"Authorization: Bearer {$this->x_api_token}",
				"X-Auth-Email: {$this->x_email}"]
		);
		if(isset($data))
		{
			$setopts[CURLOPT_POSTFIELDS] = json_encode($data);
		}
		curl_setopt_array($curl, $setopts);		
		$response = curl_exec($curl);
		$err = curl_error($curl);
		curl_close($curl);
		if ($err) {
			return "发生错误#:" . $err;
		} else {
			return (array) json_decode($response,true);
		}
	}

	// 将request_post的方法结果输出为html文本
	function request_post_html($url, $param, $data=null)
	{
		$response = $this->request_post($url, $param, $data) ;
		$response = json_encode($response);
		echo printJsonToHTML($response);
	}
}

  下面提供一个简单的API调用示例,如下:

# 列出当前用户名下所有域名
$rtn = DNSCloudflare::Obj()->DomainListAll();
print_r($rtn);

# 根据域名zone_id查询当前域名解析记录
$zone_id = "****************";
$rtn = DNSCloudflare::Obj()->DNSRecordsList($zone_id);
print_r($rtn);

  通过这个PHP封装类,我就可以用自己的域名,在自己的家庭网络设备如NAS上实现家里宽带的动态域名解析了,您可以创建一个ddns.php文件,核心代码如下:

//引入前面的类文件
require_once($_SERVER['DOCUMENT_ROOT'].'/DNSCloudflare-inc.php');
#获取当前客户端的ip
$REMOTE_ADDR = $_SERVER['REMOTE_ADDR'];
//IPv4地址更新
if(filter_var($REMOTE_ADDR, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4))
{
	DNSCloudflare::Obj()->ModifyDynamicDNS2("","example.com",$REMOTE_ADDR,"A");
}

//IPv6地址更新
if(filter_var($REMOTE_ADDR, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6))
{
	DNSCloudflare::Obj()->ModifyDynamicDNS2("","example.com",$REMOTE_ADDR,"AAAA");
}

  如果您在使用该封装类有任何问题,可留言给我,我会尽快回复。

返回首页    发布日期:2026年06月09日

Copyright © 2026   楚狐在线   All Rights ReservedSG.   反馈留言