/** * SakuraFrp API 客户端 * 仅实现了获取隧道列表的功能 * * @version 1.0 * @author AI Assistant */ class SakuraFrpApi { /** * API 基础 URL * @var string */ private const BASE_URL = 'https://api.natfrp.com/v4'; /** * 用户认证 Token * @var string */ private $userToken; /** * 构造函数 * @param string $userToken 您的 SakuraFrp 用户 Token */ public function __construct(string $userToken) { $this->userToken = $userToken; } /** * 获取隧道列表 * 对应 C# 中的 tunnels() 方法 * * @return array|null 成功时返回隧道列表数组,失败时返回 null * @throws Exception 如果请求失败或发生 cURL 错误 */ public function getTunnels(): ?array { $url = self::BASE_URL . '/tunnels'; //echo "请求 URL: " . $url . "\n"; return $this->makeRequest('GET', $url); } /** * 通用的请求方法 * * @param string $method HTTP 方法 (GET, POST, etc.) * @param string $url 请求的 URL * @param array|null $data 对于 POST 请求,要发送的 JSON 数据 * @return array|null 成功时返回解码后的 JSON 数组,失败时返回 null * @throws Exception */ private function makeRequest(string $method, string $url, ?array $data = null): ?array { // 1. 初始化 cURL $ch = curl_init(); // 2. 设置 cURL 选项 curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 将响应作为字符串返回,而不是直接输出 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 跟随重定向 // 添加 SSL 验证选项(开发环境可禁用,生产环境应启用) curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 禁用 SSL 证书验证 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 不检查证书中的主机名 // 3. 设置请求头 $headers = [ 'Accept: application/json', 'Authorization: Bearer ' . $this->userToken ]; curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); // 4. 如果是 POST 请求,设置 POST 数据 if ($method === 'POST' && $data !== null) { curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); $headers[] = 'Content-Type: application/json'; curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); } // 5. 执行请求 $response = curl_exec($ch); // 6. 检查错误 if (curl_errno($ch)) { $error_msg = curl_error($ch); curl_close($ch); throw new Exception("cURL Error: " . $error_msg); } // 7. 获取 HTTP 状态码 $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); // 8. 处理响应 if ($httpCode >= 200 && $httpCode < 300) { // 成功响应 $decodedResponse = json_decode($response, true); if (json_last_error() === JSON_ERROR_NONE) { return $decodedResponse; } throw new Exception("JSON Decode Error: " . json_last_error_msg()); } else { // 错误响应 $errorResponse = json_decode($response, true); $errorMessage = $errorResponse['message'] ?? $response; throw new Exception("API Request Failed with HTTP Code {$httpCode}: {$errorMessage}"); } return null; } }旧PHP版SakuraFrpApi
张小明
前端开发工程师
【贪嗔痴】低频量化周报(指数风险溢价比,配债完整数据集,可转债策略,上市公司礼品,交易总结)
低频量化周报(2026-01-30)指数风险溢价比小规模配债<5亿配债完整数据5 批文通过4 发哥通过3 交易所受理2 股东大会通过1 董事会预案可转债策略双低策略低溢价策略小盘低价格策略小盘低溢价策略溢价偏离策略上市公司实物礼品孚日股份(002083)2026-01-2…
Selenium常用于网页爬取 为了提高爬取效率,可以采取以下优化措施:合理使用无头模式
Selenium常用于网页爬取 为了提高爬取效率,可以采取以下优化措施:合理使用无头模式 Selenium常用于网页爬取 合理使用无头模式 如何优化 Selenium 的使用以提高爬取效率、数据清洗的具体步骤和常用工具 Selenium 的优化策略 Selenium 是一款功能强大…
Qwen3-ASR-0.6B实战:一键将音频转文字,隐私安全无忧
Qwen3-ASR-0.6B实战:一键将音频转文字,隐私安全无忧 你是否遇到过这些场景: 会议录音堆在文件夹里迟迟没整理,灵感闪现时语音备忘录听不清,采访素材要花半天手动打字,又或者——你根本不敢把客户会议、内部…
基于Flink CDC的企业级日志实时入湖入流解决方案
作者:徐榜江(雪尽) —— 阿里云Flink数据通团队负责人,Flink PMC成员,Flink CDC开源项目负责人李昊哲(米灵) —— 阿里云Flink高级产品经理,负责阿里云Flink稳定性、可观测性、数据摄入等企业级产品特性摘要本文主要介绍阿里云基于…
使用 Depth Anything V2 进行单目深度估计
原文:towardsdatascience.com/monocular-depth-estimation-with-depth-anything-v2-54b6775abc9f?sourcecollection_archive---------4-----------------------#2024-07-24 神经网络是如何从二维图像中学习估计深度的? https://medium.com/neural.avb?…
什么是住宅代理IP?
什么是住宅代理IP? 住宅代理IP是一种特殊类型的代理服务,采用的IP地址为居民住宅网络IP地址。这种特殊类型的代理服务可以模拟真实用户的上网行为和位置信息,从而更好地保护用户的隐私,并且比其他类型的代理服务更难被网站或应用…