PHP code example of westng / doudian-sdk
1. Go to this page and download the library: Download westng/doudian-sdk library . Choose the download type require .
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
westng / doudian-sdk example snippets
DouDianSdk\Core\Client\DouDianSdk;
// 初始化SDK
$sdk = new DouDianSdk('your_app_key', 'your_app_secret');
// 获取访问令牌 (通过店铺ID)
$accessToken = $sdk->getAccessToken('your_shop_id', 2); // 2 = 店铺ID模式
// 检查令牌是否获取成功
if (!$accessToken->isSuccess()) {
throw new Exception('获取访问令牌失败: ' . $accessToken->getMessage());
}
// 调用API - 获取订单列表
$result = $sdk->callApi(
'order_searchList\OrderSearchListRequest',
'order_searchList\param\OrderSearchListParam',
[
'page' => 1,
'size' => 20,
'order_status' => 1,
'start_time' => date('Y-m-d H:i:s', strtotime('-7 days')),
'end_time' => date('Y-m-d H:i:s'),
],
$accessToken
);
// 处理结果
if (isset($result['code']) && $result['code'] === 10000) {
echo "获取订单成功\n";
print_r($result['data']);
}
use DouDianSdk\Core\Client\DouDianSdk;
$appASdk = new DouDianSdk($appAKey, $appASecret);
$appBSdk = new DouDianSdk($appBKey, $appBSecret);
$appAResult = $appASdk->callApi(
'order_searchList\OrderSearchListRequest',
'order_searchList\param\OrderSearchListParam',
['page' => 1, 'size' => 10],
$appAAccessToken
);
$appBResult = $appBSdk->callApi(
'order_searchList\OrderSearchListRequest',
'order_searchList\param\OrderSearchListParam',
['page' => 1, 'size' => 10],
$appBAccessToken
);
use DouDianSdk\Core\Client\DouDianSdk;
$sdk = new DouDianSdk('your_app_key', 'your_app_secret', [
'debug' => true,
'timeout' => [
'connect' => 5000, // 连接超时5秒
'read' => 10000 // 读取超时10秒
],
'retry' => [
'enable' => true,
'max_times' => 3,
'interval' => 1000
],
// Swoole 环境连接池配置
'pool' => [
'max_connections' => 50, // 最大连接数
'max_idle_time' => 60, // 空闲超时(秒)
'wait_timeout' => 3.0 // 等待超时(秒)
]
]);
// 每次 HTTP 请求
$client = $pool->get(); // 1. 从池获取连接(或等待)
try {
$response = $client->request(...); // 2. 发送请求
return $response;
} finally {
$pool->put($client); // 3. 归还连接(无论成功失败)
}
use DouDianSdk\Core\Client\DouDianSdk;
// 方式1:构造函数配置
$sdk = new DouDianSdk('your_app_key', 'your_app_secret', [
'pool' => [
'max_connections' => 50, // 最大连接数(默认50)
'max_idle_time' => 60, // 空闲超时秒数(默认60)
'wait_timeout' => 3.0 // 等待超时秒数(默认3.0)
]
]);
// 方式2:运行时配置
$sdk->setPoolConfig(100, 120, 5.0);
use DouDianSdk\Core\Client\DouDianSdk;
// 初始化 SDK(在 Worker 启动时)
$sdk = new DouDianSdk('your_app_key', 'your_app_secret', [
'pool' => ['max_connections' => 50]
]);
$count = 0;
while (true) {
$job = $queue->pop();
// 每个协程共享同一个连接池
go(function() use ($sdk, $job) {
$accessToken = getAccessTokenFromCache($job['shop_id']);
$result = $sdk->callApi(
'order_orderDetail\OrderOrderDetailRequest',
'order_orderDetail\param\OrderOrderDetailParam',
['order_id' => $job['order_id']],
$accessToken
);
// 处理结果...
// 请求完成,连接自动归还到池中
});
$count++;
// 定期查看连接池状态
if ($count % 1000 === 0) {
$stats = $sdk->getPoolStats();
echo sprintf(
"连接池: 活跃=%d, 空闲=%d, 等待=%d, 总请求=%d\n",
$stats['active_connections'],
$stats['idle_connections'],
$stats['wait_queue_size'],
$stats['total_requests']
);
}
}
$stats = $sdk->getPoolStats();
// 返回结构:
// [
// 'pool_size' => 50, // 池大小配置
// 'total_created' => 50, // 总创建连接数
// 'active_connections' => 30, // 正在使用的连接
// 'idle_connections' => 20, // 空闲可用的连接
// 'wait_queue_size' => 5, // 等待获取连接的协程数
// 'total_requests' => 10000, // 总请求数
// ]
// 调优建议:
// - wait_queue_size 经常 > 0 → 增加 max_connections
// - idle_connections 经常很高 → 减少 max_connections
// 在长时间运行的进程中,可以主动释放资源
$sdk->shutdown();
// 或者在 Worker 退出时调用
Swoole\Process::signal(SIGTERM, function() use ($sdk) {
$sdk->shutdown();
exit(0);
});
// 1. 安装 hyperf/guzzle(如果还没安装)
// composer e\Client\DouDianSdk::class => function() {
return new \DouDianSdk\Core\Client\DouDianSdk(
env('DOUDIAN_APP_KEY'),
env('DOUDIAN_APP_SECRET'),
[
'pool' => [
'max_connections' => 50, // Hyperf PoolHandler 会使用这个配置
'max_idle_time' => 60,
]
]
);
},
];
// 3. 在 Controller 或 Service 中使用
class OrderService
{
public function __construct(
private \DouDianSdk\Core\Client\DouDianSdk $sdk
) {}
public function getOrder(string $orderId, string $accessToken)
{
return $this->sdk->callApi(...);
// SDK 自动使用 Hyperf PoolHandler,无需额外配置
}
}
$stats = $sdk->getPoolStats();
echo $stats['mode'];
// 'hyperf-pool-handler' - 使用 Hyperf 内置连接池(最优)
// 'sdk-pool-with-hyperf-handler' - SDK 连接池 + Hyperf 协程
// 'sdk-pool-native' - SDK 连接池 + 原生 Swoole
// 检查当前环境
echo $sdk->getEnvironment();
// 'swoole-coroutine' - Swoole 协程环境
// 'swoole-sync' - Swoole 同步环境
// 'fpm' - PHP-FPM 环境
echo $sdk->isSwooleCoroutine() ? '协程环境' : '非协程环境';
use DouDianSdk\Core\Client\DouDianSdk;
$sdk = new DouDianSdk('your_app_key', 'your_app_secret');
// 获取令牌
$accessToken = $sdk->getAccessToken('your_shop_id', 2);
if ($accessToken->isSuccess()) {
echo "访问令牌: " . $accessToken->getAccessToken() . "\n";
echo "有效期: " . $accessToken->getExpireIn() . " 秒\n";
echo "店铺ID: " . $accessToken->getShopId() . "\n";
// 刷新令牌
if ($refreshToken = $accessToken->getRefreshToken()) {
$newToken = $sdk->refreshAccessToken($refreshToken);
}
} else {
echo "错误: " . $accessToken->getMessage() . "\n";
echo "子错误码: " . $accessToken->getSubCode() . "\n";
}
use DouDianSdk\Core\Client\DouDianSdk;
use DouDianSdk\Core\Exception\DouDianException;
use DouDianSdk\Core\Exception\ApiException;
use DouDianSdk\Core\Exception\HttpException;
try {
$result = $sdk->callApi(...);
} catch (HttpException $e) {
// HTTP 错误(网络问题、超时、连接池耗尽等)
echo "HTTP 错误: " . $e->getMessage() . "\n";
} catch (ApiException $e) {
// API 错误(参数错误、签名错误等)
echo "API 错误: " . $e->getMessage() . "\n";
} catch (DouDianException $e) {
// 其他 SDK 错误
echo "SDK 错误: " . $e->getMessage() . "\n";
}
text
tests/
├── Api/
│ ├── Product/
│ │ └── ProductGetRecommendCategoryApiTest.php
│ └── Shop/
│ ├── ShopGetShopCategoryApiTest.php
│ └── ShopCategory2PublishWorkflowTest.php
├── Support/
│ └── ProductPublishTestHelper.php
└── fixtures/
├── product_add_v2_payload.example.json
└── product_get_recommend_category_payload.example.json
bash
# 单独运行店铺类目测试
./vendor/bin/phpunit tests/Api/Shop/ShopGetShopCategoryApiTest.php
# 单独运行推荐类目测试
./vendor/bin/phpunit tests/Api/Product/ProductGetRecommendCategoryApiTest.php
# 单独运行商品发布链路测试
./vendor/bin/phpunit tests/Api/Shop/ShopCategory2PublishWorkflowTest.php