仰望星辰工作室

fix: 优化面板API调用错误处理与数据返回

Y yang1145 提交于 2026-08-14 04:26 · 180e591 ·父提交 195d61c
fix: 优化面板API调用错误处理与数据返回

1. 重构bt_api类的curl请求逻辑,添加跟随跳转支持并正确传递错误信息
2. 为PHP版本列表接口添加详细错误返回和原始响应数据
3. 修复删除节点时关联站点的查询逻辑
4. 在状态检测接口中透出面板真实错误原因
3 个文件变更 +35 -8 13172193298@163.com
•MPHX/bt_api.php +18 -1
•MPHX/bt_php.function.php +6 -2
•admin/api/bt.php +11 -5
变更内容
diff --git a/MPHX/bt_api.php b/MPHX/bt_api.php
index 26ccced..2c206a7 100644
--- a/MPHX/bt_api.php
+++ b/MPHX/bt_api.php
@@ -1413,6 +1413,20 @@ class bt_api
             }
         }
 
+        $output = $this->curlRequest($url, $data, $cookie_file, $timeout, $connectTimeout, $last_error);
+        if ($output === false) {
+            return '{"status":false,"msg":"连接面板失败:' . addslashes((string)$last_error) . '"}';
+        }
+        return $output;
+    }
+
+    /**
+     * 执行一次 cURL POST 请求。
+     * 跟随面板 http->https 跳转并保持 POST 方法,避免面板开启 SSL 后 http 方式无法对接。
+     * @return string|false 响应体;请求失败返回 false 并写入 $last_error
+     */
+    private function curlRequest($url, $data, $cookie_file, $timeout, $connectTimeout, &$last_error)
+    {
         $ch = curl_init();
         curl_setopt($ch, CURLOPT_URL, $url);
         curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
@@ -1423,11 +1437,14 @@ class bt_api
         curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);
         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
         curl_setopt($ch, CURLOPT_HEADER, 0);
+        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
+        curl_setopt($ch, CURLOPT_MAXREDIRS, 5);
+        curl_setopt($ch, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);
         curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
         curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
         $output = curl_exec($ch);
         if ($output === false) {
-            $output = '{"status":false,"msg":"连接面板失败:' . addslashes((string)curl_error($ch)) . '"}';
+            $last_error = (string)curl_error($ch);
         }
         curl_close($ch);
         return $output;
diff --git a/MPHX/bt_php.function.php b/MPHX/bt_php.function.php
index 99d56e8..d3e348b 100644
--- a/MPHX/bt_php.function.php
+++ b/MPHX/bt_php.function.php
@@ -31,7 +31,11 @@ function mnbt_node_php_list($btdh)
     $api = new bt_api($btipe, $node['btmy']);
     $result = $api->btapi_listphp();
     if (!is_array($result)) {
-        return ['ok' => false, 'msg' => '无法获取 PHP 版本列表'];
+        return ['ok' => false, 'msg' => '无法获取 PHP 版本列表', 'raw' => $result];
+    }
+    // 面板返回业务错误(连接失败/鉴权失败等),透出真实原因,避免误报为「未安装 PHP」
+    if (isset($result['status']) && ($result['status'] === false || $result['status'] === 0 || $result['status'] === '0')) {
+        return ['ok' => false, 'msg' => isset($result['msg']) ? $result['msg'] : '面板返回错误', 'raw' => $result];
     }
     // 移除纯静态(0)和自定义/其他(1),与用户端处理保持一致
     unset($result[0], $result[1]);
@@ -42,7 +46,7 @@ function mnbt_node_php_list($btdh)
         }
     }
     if (empty($versions)) {
-        return ['ok' => false, 'msg' => '该节点未安装任何 PHP 版本'];
+        return ['ok' => false, 'msg' => '该节点未安装任何 PHP 版本', 'raw' => $result];
     }
     usort($versions, function ($a, $b) {
         return strcmp($b['version'], $a['version']);
diff --git a/admin/api/bt.php b/admin/api/bt.php
index 9fc3ddf..939d384 100644
--- a/admin/api/bt.php
+++ b/admin/api/bt.php
@@ -34,10 +34,12 @@ if($egn=='btsc') {
 	$cres=$DB->get_row_prepare("SELECT * FROM MN_bt WHERE id=? limit 1", [$id]);
 	$ssbt=$cres['btdh'];
 	if($DB->query_prepare("DELETE FROM MN_bt WHERE id=? limit 1", [$id])) {
-		$rs=$DB->query_prepare("SELECT * FROM MN_zj WHERE ssbt=? order by id desc limit 9999", [$ssbt]);
-		while($res = $DB->fetch($rs)) {
-			$bjyr=$res['id'];
-			$DB->query_prepare("DELETE FROM MN_zj WHERE id=? limit 1", [$bjyr]);
+		$rs=$DB->get_all_prepare("SELECT * FROM MN_zj WHERE ssbt=? order by id desc limit 9999", [$ssbt]);
+		if (is_array($rs)) {
+			foreach($rs as $res) {
+				$bjyr=$res['id'];
+				$DB->query_prepare("DELETE FROM MN_zj WHERE id=? limit 1", [$bjyr]);
+			}
 		}
 		json_exit('删除成功');
 	} else {
@@ -119,6 +121,10 @@ if($egn=='btztjc') {
 	$api = new bt_api($bt_url, $cert['btmy']);
 	try {
 		$result = $api->btapi_listphp();
+		if(is_array($result) && isset($result['status']) && ($result['status'] === false || $result['status'] === 0 || $result['status'] === '0')) {
+			// 面板返回业务错误(连接失败/鉴权失败等),透出真实原因
+			exit(json_encode(['qk'=>0,'code'=>($result['msg'] ?? '面板返回错误'),'titco'=>'text-danger'], JSON_UNESCAPED_UNICODE));
+		}
 		if(is_array($result)) {
 			exit(json_encode(['qk'=>1,'code'=>'通信正常','titco'=>'text-success']));
 		} else {
@@ -139,7 +145,7 @@ if ($egn === 'list_node_php') {
 	require_once SYSTEM_ROOT . 'bt_php.function.php';
 	$result = mnbt_node_php_list($btdh);
 	if (!$result['ok']) {
-		exit(json_encode(['qk' => 0, 'msg' => $result['msg']]));
+		exit(json_encode(['qk' => 0, 'msg' => $result['msg'], 'raw' => $result['raw'] ?? null], JSON_UNESCAPED_UNICODE));
 	}
 	$currentDefault = mnbt_node_get_php($btdh);
 	exit(json_encode(['qk' => 1, 'versions' => $result['versions'], 'latest' => $result['latest'], 'current_default' => $currentDefault]));