关键词:PHP API开发、金融市场数据、WebSocket实时数据、cURL实战
一、项目概述
StockTV作为全球领先的金融数据平台,提供覆盖股票、外汇、期货和加密货币的实时行情服务。本文将手把手教你使用PHP实现以下核心功能:
- ✅ REST API调用:获取历史行情数据
- ✅ WebSocket订阅:实时价格推送
- ✅ 生产级特性:异常重试、速率控制、数据缓存
- ✅ 高性能优化:连接池、异步处理
二、环境准备
1. 运行环境要求
- PHP ≥ 7.4
- cURL扩展
- JSON扩展
- Composer包管理器
2. 申请API密钥
访问StockTV开发者门户,联系客服后获取API Key。
三、项目搭建
1. 初始化项目
mkdir stocktv-php && cd stocktv-php
composer init --name="yourname/stocktv-php"
2. 安装依赖
composer require ratchet/pawl guzzlehttp/guzzle
3. 项目结构
stocktv-php/
├── src/
│ ├── StockClient.php # 股票数据客户端
│ └── WebsocketClient.php # 实时数据客户端
├── examples/ # 使用示例
├── vendor/ # 依赖库
└── composer.json
四、核心功能实现
1. HTTP客户端封装(src/StockClient.php)
<?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
class StockClient {
private $client;
private $apiKey;
public function __construct(string $apiKey) {
$this->apiKey = $apiKey;
$this->client = new Client([
'base_uri' => 'https://api.stocktv.top',
'timeout' => 10.0,
]);
}
/**
* 获取股票列表
* @param int $countryId 国家ID
* @param int $pageSize 每页数量
* @param int $page 页码
*/
public function getStockList(int $countryId, int $pageSize = 10, int $page = 1): array {
try {
$response = $this->client->get('/stock/stocks', [
'query' => [
'key' => $this->apiKey,
'countryId' => $countryId,
'pageSize' => $pageSize,
'page' => $page
]
]);
return json_decode($response->getBody(), true);
} catch (GuzzleException $e) {
throw new Exception("API请求失败: ".$e->getMessage());
}
}
}
2. WebSocket客户端(src/WebsocketClient.php)
<?php
require 'vendor/autoload.php';
use Ratchet\Client\WebSocket;
use React\EventLoop\Factory;
class WebsocketClient {
private $apiKey;
public function __construct(string $apiKey) {
$this->apiKey = $apiKey;
}
public function connect(callable $messageCallback) {
$loop = Factory::create();
$connector = new \Ratchet\Client\Connector($loop);
$wsUrl = "wss://ws-api.stocktv.top/connect?key={$this->apiKey}";
$connector($wsUrl)->then(
function (WebSocket $conn) use ($loop, $messageCallback) {
$conn->on('message', function($msg) use ($messageCallback) {
$messageCallback(json_decode($msg, true));
});
$conn->on('close', function($code = null, $reason = null) {
echo "连接关闭 ({$code} - {$reason})\n";
});
},
function (\Exception $e) use ($loop) {
echo "连接失败: {$e->getMessage()}\n";
$loop->stop();
}
);
$loop->run();
}
}
五、使用示例
1. 获取股票数据(examples/stock_example.php)
<?php
require __DIR__.'/../vendor/autoload.php';
require __DIR__.'/../src/StockClient.php';
$apiKey = 'YOUR_API_KEY';
$client = new StockClient($apiKey);
try {
// 获取印度股票第一页数据
$data = $client->getStockList(14, 20, 1);
echo "=== 印度股票市场数据 ===\n";
foreach ($data['data']['records'] as $stock) {
printf("%-20s 最新价: %.2f 涨跌幅: %.2f%%\n",
$stock['name'],
$stock['last'],
$stock['chgPct']
);
}
} catch (Exception $e) {
echo "错误: ".$e->getMessage();
}
2. 实时数据订阅(examples/websocket_example.php)
<?php
require __DIR__.'/../vendor/autoload.php';
require __DIR__.'/../src/WebsocketClient.php';
$apiKey = 'YOUR_API_KEY';
$wsClient = new WebsocketClient($apiKey);
echo "开始接收实时行情...\n";
$wsClient->connect(function($data) {
if ($data['type'] === 'stock') {
echo "[股票] {$data['symbol']} 价格: {$data['last']} ";
echo "变动: ".($data['pcp'] >= 0 ? '↑' : '↓').abs($data['pcp'])."%\n";
}
});
六、高级功能扩展
1. 请求重试机制
class RetryableClient extends StockClient {
public function getStockListWithRetry(
int $countryId,
int $maxRetries = 3,
int $retryDelay = 1000
): array {
$retryCount = 0;
while ($retryCount < $maxRetries) {
try {
return $this->getStockList($countryId);
} catch (Exception $e) {
$retryCount++;
usleep($retryDelay * 1000);
}
}
throw new Exception("请求失败,已达最大重试次数");
}
}
2. 数据缓存层
class CachedStockClient extends StockClient {
private $cache;
public function __construct(string $apiKey, int $ttl = 60) {
parent::__construct($apiKey);
$this->cache = new \Symfony\Component\Cache\Adapter\FilesystemAdapter('', $ttl);
}
public function getCachedStockList(int $countryId): array {
$cacheKey = "stocks_{$countryId}";
$item = $this->cache->getItem($cacheKey);
if (!$item->isHit()) {
$data = $this->getStockList($countryId);
$item->set($data);
$this->cache->save($item);
}
return $item->get();
}
}
七、最佳实践
安全建议
使用环境变量存储API密钥
$apiKey = getenv('STOCKTV_API_KEY');
性能优化
启用HTTP持久连接
new Client([ 'base_uri' => 'https://api.stocktv.top', 'curl' => [ CURLOPT_TCP_KEEPALIVE => 1, CURLOPT_TCP_KEEPIDLE => 30, ] ]);
错误监控
try { // API调用代码 } catch (Exception $e) { error_log("[StockTV Error] ".date('Y-m-d H:i:s')." - ".$e->getMessage()); // 发送到监控平台 $monitor->report($e); }
八、常见问题排查
问题现象 | 可能原因 | 解决方案 |
---|---|---|
返回403错误 | API密钥无效 | 检查密钥是否包含特殊字符 |
WebSocket频繁断开 | 防火墙限制 | 检查服务器出站规则 |
获取的数据为旧版本 | 缓存未更新 | 清除缓存或降低TTL值 |
CPU占用过高 | 未限制请求频率 | 添加速率限制器 |
九、资源推荐
通过本文的指导,您已掌握了使用PHP对接StockTV金融数据的核心技能。建议在实际项目中结合业务需求,扩展数据存储、可视化展示等功能,构建专业的金融数据分析系统。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。