使用PHP对接宝塔面板Web API完整指南
前言
宝塔面板是一款强大的服务器管理软件,提供了丰富的Web API接口供开发者调用。本文将详细介绍如何使用PHP对接宝塔API,并封装成可复用的公共方法。无论您是需要自动化部署、批量管理站点,还是监控服务器状态,这些方法都能大大提高效率。
环境准备
1. 获取宝塔API配置信息
登录宝塔面板 → 面板设置 → API接口,开启API并获取以下信息:
-
API密钥(API Key)
-
API地址(通常为面板地址 + /api)
2. PHP环境要求
-
PHP 7.0及以上
-
开启cURL扩展
完整的PHP宝塔API封装类
<?php
/**
* 宝塔面板API接口封装类
* 作者:技术分享 | 来源:uudwc.com
* 创建时间:2026年
* 版本:1.2
*/
class BtApiClient
{
// API基础配置
private $bt_url; // 宝塔面板地址
private $bt_key; // API密钥
private $debug; // 调试模式
private $timeout; // 请求超时时间
/**
* 构造函数
* @param string $bt_url 宝塔面板地址
* @param string $bt_key API密钥
* @param bool $debug 是否开启调试模式
*/
public function __construct($bt_url, $bt_key, $debug = false)
{
$this->bt_url = rtrim($bt_url, '/');
$this->bt_key = $bt_key;
$this->debug = $debug;
$this->timeout = 30;
// 验证参数
if (empty($this->bt_url) || empty($this->bt_key)) {
throw new Exception('宝塔API配置参数不能为空');
}
}
/**
* 通用API请求方法
* @param string $api_path API路径
* @param array $data 请求参数
* @param string $method 请求方法 (GET/POST)
* @return array
*/
public function request($api_path, $data = [], $method = 'POST')
{
// 准备请求URL
$url = $this->bt_url . '/' . ltrim($api_path, '/');
// 生成签名
$request_time = time();
$request_token = $this->generateToken($request_time);
// 构建请求数据
$post_data = array_merge($data, [
'request_token' => $request_token,
'request_time' => $request_time
]);
// 初始化cURL
$ch = curl_init();
// 设置cURL选项
$options = [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HEADER => false,
CURLOPT_TIMEOUT => $this->timeout,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_HTTPHEADER => [
'Content-Type: application/x-www-form-urlencoded',
'User-Agent: BT-API-PHP-Client/1.0'
]
];
// 根据请求方法设置参数
if (strtoupper($method) === 'POST') {
$options[CURLOPT_POST] = true;
$options[CURLOPT_POSTFIELDS] = http_build_query($post_data);
} else {
// GET请求将参数附加到URL
$url .= '?' . http_build_query($post_data);
$options[CURLOPT_URL] = $url;
}
curl_setopt_array($ch, $options);
// 执行请求
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);
// 调试信息
if ($this->debug) {
$this->logDebug([
'url' => $url,
'method' => $method,
'request_data' => $post_data,
'response' => $response,
'http_code' => $http_code,
'error' => $error
]);
}
// 处理错误
if ($error) {
return $this->formatResponse(false, "cURL请求失败: {$error}");
}
// 解析响应
$result = json_decode($response, true);
if (json_last_error() !== JSON_ERROR_NONE) {
return $this->formatResponse(false, "JSON解析失败: " . json_last_error_msg());
}
// 检查HTTP状态码
if ($http_code !== 200) {
return $this->formatResponse(false, "HTTP请求失败,状态码: {$http_code}");
}
return $this->formatResponse(true, "请求成功", $result);
}
/**
* 生成请求令牌
* @param int $request_time 请求时间戳
* @return string
*/
private function generateToken($request_time)
{
// 宝塔API签名算法
$md5_key = md5($request_time . $this->bt_key);
$token = md5(substr($md5_key, 0, 8) . $request_time);
return $token;
}
/**
* 格式化响应数据
* @param bool $status 状态
* @param string $message 消息
* @param mixed $data 数据
* @return array
*/
private function formatResponse($status, $message, $data = null)
{
return [
'status' => $status,
'message' => $message,
'data' => $data,
'timestamp' => time()
];
}
/**
* 记录调试信息
* @param array $data 调试数据
*/
private function logDebug($data)
{
$log_file = dirname(__FILE__) . '/bt_api_debug.log';
$log_content = "[" . date('Y-m-d H:i:s') . "] " . print_r($data, true) . "\n";
file_put_contents($log_file, $log_content, FILE_APPEND);
}
/**
* 设置超时时间
* @param int $seconds 秒数
*/
public function setTimeout($seconds)
{
$this->timeout = (int)$seconds;
}
// ==================== 常用API封装方法 ====================
/**
* 获取系统状态
* @return array
*/
public function getSystemStatus()
{
return $this->request('system?action=GetSystemTotal', [], 'GET');
}
/**
* 获取网站列表
* @param int $page 页码
* @param int $page_size 每页数量
* @return array
*/
public function getWebsites($page = 1, $page_size = 100)
{
$data = [
'p' => $page,
'limit' => $page_size,
'type' => -1,
'order' => 'id desc'
];
return $this->request('data?action=getData', $data);
}
/**
* 创建网站
* @param array $site_info 网站信息
* @return array
*/
public function createWebsite($site_info)
{
$required_fields = ['webname', 'path', 'type_id', 'port', 'ps'];
foreach ($required_fields as $field) {
if (!isset($site_info[$field])) {
return $this->formatResponse(false, "缺少必要参数: {$field}");
}
}
return $this->request('site?action=AddSite', $site_info);
}
/**
* 删除网站
* @param int $id 网站ID
* @param string $webname 网站名称
* @return array
*/
public function deleteWebsite($id, $webname)
{
$data = [
'id' => $id,
'webname' => $webname
];
return $this->request('site?action=DeleteSite', $data);
}
/**
* 获取SSL证书信息
* @param string $site_name 网站名称
* @return array
*/
public function getSSLInfo($site_name)
{
$data = ['siteName' => $site_name];
return $this->request('site?action=GetSiteSSL', $data);
}
/**
* 设置SSL证书
* @param string $site_name 网站名称
* @param string $key 私钥内容
* @param string $cert 证书内容
* @return array
*/
public function setSSL($site_name, $key, $cert)
{
$data = [
'siteName' => $site_name,
'key' => $key,
'csr' => $cert
];
return $this->request('site?action=SetSSL', $data);
}
/**
* 获取防火墙状态
* @return array
*/
public function getFirewallStatus()
{
return $this->request('firewall?action=GetFirewallStatus', [], 'GET');
}
/**
* 添加防火墙规则
* @param string $port 端口
* @param string $protocol 协议 (tcp/udp)
* @param string $ps 备注
* @return array
*/
public function addFirewallRule($port, $protocol = 'tcp', $ps = '')
{
$data = [
'port' => $port,
'protocol' => $protocol,
'ps' => $ps ?: "API添加 - " . date('Y-m-d H:i:s')
];
return $this->request('firewall?action=AddFirewallRule', $data);
}
/**
* 获取数据库列表
* @param int $page 页码
* @param int $page_size 每页数量
* @return array
*/
public function getDatabases($page = 1, $page_size = 100)
{
$data = [
'p' => $page,
'limit' => $page_size
];
return $this->request('database?action=getData', $data);
}
/**
* 创建数据库
* @param string $name 数据库名
* @param string $user 用户名
* @param string $password 密码
* @param string $ps 备注
* @return array
*/
public function createDatabase($name, $user, $password, $ps = '')
{
$data = [
'name' => $name,
'db_user' => $user,
'password' => $password,
'dtype' => 'mysql',
'dataAccess' => '127.0.0.1',
'address' => '%',
'ps' => $ps ?: "API创建 - " . date('Y-m-d H:i:s')
];
return $this->request('database?action=AddDatabase', $data);
}
}
使用示例
基础使用方法
<?php
/**
* 宝塔API使用示例
* 更多示例请参考:https://www.uudwc.com/bt-api-examples
*/
// 引入类文件
require_once 'BtApiClient.php';
// 初始化客户端
try {
// 替换为您的宝塔面板地址和API密钥
$bt_url = 'https://your-bt-panel.com';
$bt_key = 'your_api_key_here';
$bt_client = new BtApiClient($bt_url, $bt_key, true); // 开启调试模式
// 示例1:获取系统状态
echo "=== 获取系统状态 ===\n";
$system_status = $bt_client->getSystemStatus();
if ($system_status['status']) {
echo "系统负载: " . $system_status['data']['load'] . "\n";
echo "内存使用: " . $system_status['data']['mem'] . "\n";
echo "磁盘使用: " . $system_status['data']['disk'] . "\n";
} else {
echo "获取失败: " . $system_status['message'] . "\n";
}
// 示例2:获取网站列表
echo "\n=== 获取网站列表 ===\n";
$websites = $bt_client->getWebsites(1, 10);
if ($websites['status']) {
foreach ($websites['data']['data'] as $site) {
echo "网站ID: {$site['id']}, 名称: {$site['name']}, 域名: {$site['domain']}\n";
}
}
// 示例3:创建网站
echo "\n=== 创建网站示例 ===\n";
$site_info = [
'webname' => 'test_site',
'path' => '/www/wwwroot/test_site',
'type_id' => 0,
'port' => 80,
'ps' => '测试网站 - API创建',
'ftp' => false,
'sql' => false
];
// $result = $bt_client->createWebsite($site_info);
// print_r($result);
// 示例4:设置SSL证书
echo "\n=== SSL证书管理 ===\n";
$ssl_info = $bt_client->getSSLInfo('your_domain.com');
print_r($ssl_info);
} catch (Exception $e) {
echo "初始化失败: " . $e->getMessage() . "\n";
}
实战应用:批量创建网站
<?php
/**
* 批量创建网站示例
* 适用于批量部署环境
*/
require_once 'BtApiClient.php';
class BatchSiteManager
{
private $bt_client;
public function __construct($bt_url, $bt_key)
{
$this->bt_client = new BtApiClient($bt_url, $bt_key);
}
/**
* 从CSV文件批量创建网站
* @param string $csv_file CSV文件路径
* @return array 创建结果
*/
public function batchCreateFromCsv($csv_file)
{
if (!file_exists($csv_file)) {
return ['status' => false, 'message' => 'CSV文件不存在'];
}
$results = [];
$handle = fopen($csv_file, 'r');
// 跳过标题行
fgetc($handle);
while (($data = fgetcsv($handle)) !== false) {
$site_name = $data[0];
$domain = $data[1];
$path = $data[2];
$site_info = [
'webname' => "{$site_name}|{$domain}",
'path' => "/www/wwwroot/{$path}",
'type_id' => 0,
'port' => 80,
'ps' => "批量创建 - {$site_name}",
'ftp' => false,
'sql' => false
];
$result = $this->bt_client->createWebsite($site_info);
$results[] = [
'site_name' => $site_name,
'status' => $result['status'],
'message' => $result['message']
];
// 避免请求过于频繁
sleep(1);
}
fclose($handle);
return [
'status' => true,
'message' => '批量创建完成',
'data' => $results
];
}
}
// 使用示例
$manager = new BatchSiteManager('https://your-bt-panel.com', 'your_api_key');
$result = $manager->batchCreateFromCsv('sites.csv');
print_r($result);
错误处理与优化建议
1. 错误处理策略
<?php
/**
* 增强的错误处理示例
*/
class BtApiEnhanced extends BtApiClient
{
private $retry_count = 3;
private $retry_delay = 2; // 秒
/**
* 带重试机制的请求
*/
public function requestWithRetry($api_path, $data = [], $method = 'POST')
{
$attempt = 0;
while ($attempt < $this->retry_count) {
$result = parent::request($api_path, $data, $method);
if ($result['status']) {
return $result;
}
// 如果是网络错误,重试
if (strpos($result['message'], 'cURL请求失败') !== false) {
$attempt++;
sleep($this->retry_delay);
continue;
}
// 其他错误直接返回
return $result;
}
return $this->formatResponse(false, "请求失败,已达到最大重试次数");
}
/**
* 验证API连接
*/
public function validateConnection()
{
$test_result = $this->requestWithRetry('system?action=GetSystemTotal', [], 'GET');
if (!$test_result['status']) {
// 记录到监控系统
$this->sendAlert("宝塔API连接失败: " . $test_result['message']);
}
return $test_result;
}
/**
* 发送告警(示例)
*/
private function sendAlert($message)
{
// 这里可以集成到您的监控系统
error_log("宝塔API告警: " . $message);
// 或者发送邮件/钉钉通知
// mail('admin@example.com', '宝塔API异常', $message);
}
}
2. 安全建议
<?php /** * 安全增强的API客户端 */ class SecureBtApiClient extends BtApiClient { /** * 安全地存储和获取API密钥 */ public static function getSecureConfig() { // 建议从环境变量或加密存储中读取配置 $config_file = dirname(__FILE__) . '/config/bt_api_config.enc'; if (file_exists($config_file)) { // 解密配置(示例) $encrypted = file_get_contents($config_file); $config = json_decode($this->decrypt($encrypted), true); return [ 'url' => $config['url'], 'key' => $config['key'] ]; } return null; } /** * 简单的加密示例(实际项目请使用更安全的加密方式) */ private function decrypt($data) { // 这里使用简单的base64解码,实际项目请使用openssl等 return base64_decode($data); } /** * 验证请求参数 */ private function validateRequestParams($api_path, $data) { // 检查API路径是否在白名单中 $allowed_apis = [ 'system?action=GetSystemTotal', 'data?action=getData', 'site?action=AddSite' // ... 其他允许的API ]; if (!in_array($api_path, $allowed_apis)) { throw new Exception("未授权的API访问: {$api_path}"); } // 检查数据大小 if (strlen(json_encode($data)) > 1024 * 1024) { // 1MB限制 throw new Exception("请求数据过大"); } return true; } }
最佳实践
1. 配置文件管理
创建 config/bt_api_config.php:
<?php // 宝塔API配置文件 // 注意:不要将此文件提交到版本控制系统 return [ // 开发环境 'development' => [ 'url' => 'https://dev-bt.example.com', 'key' => 'dev_api_key_here', 'timeout' => 30 ], // 生产环境 'production' => [ 'url' => 'https://bt.example.com', 'key' => 'prod_api_key_here', 'timeout' => 60 ] ];
2. 使用工厂模式创建客户端
<?php /** * API客户端工厂 */ class BtApiClientFactory { private static $instances = []; public static function getClient($environment = 'production') { if (!isset(self::$instances[$environment])) { $config = require 'config/bt_api_config.php'; if (!isset($config[$environment])) { throw new Exception("环境配置不存在: {$environment}"); } $client = new BtApiClient( $config[$environment]['url'], $config[$environment]['key'] ); if (isset($config[$environment]['timeout'])) { $client->setTimeout($config[$environment]['timeout']); } self::$instances[$environment] = $client; } return self::$instances[$environment]; } } // 使用工厂 $client = BtApiClientFactory::getClient('production'); $status = $client->getSystemStatus();
常见问题解答
Q1: API请求返回"权限不足"怎么办?
A: 检查宝塔面板的API接口是否已开启,API密钥是否正确,以及IP白名单设置。
Q2: 如何提高API请求的安全性?
A: 建议:
-
定期更换API密钥
-
设置IP白名单限制
-
使用HTTPS连接
-
将API密钥存储在环境变量中
Q3: 请求超时如何处理?
A: 可以增加超时时间:
$client->setTimeout(60); // 设置为60秒
Q4: 如何获取更多API接口信息?
A: 访问宝塔官方文档
技术分享之余,这个就是通过全接口生成的独立网站:uudwc.com

浙公网安备 33010602011771号