brown/longbridge-php

Lightweight PHP client for Longbridge OpenAPI HTTP and socket protocols.

Maintainers

Package info

github.com/BrownSweet/longbridge-php

pkg:composer/brown/longbridge-php

Statistics

Installs: 7

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v0.1.0 2026-05-28 05:30 UTC

This package is not auto-updated.

Last update: 2026-06-11 05:58:21 UTC


README

轻量级长桥 OpenAPI PHP 客户端,覆盖 HTTP API、OAuth、legacy 签名、WebSocket/protobuf 行情和交易推送。项目保持数组返回风格,不引入 DTO。

项目文档

环境要求

  • PHP >= 8.2
  • guzzlehttp/guzzle
  • google/protobuf
  • WebSocket 功能需要 ext-swoole

安装依赖:

composer install

客户端初始化

OAuth 2.0

OAuth access token 可以传明文 token,也可以传已经带 Bearer 前缀的字符串;SDK 请求时会统一使用 Authorization: Bearer xxx

use Brown\Longbridge\LongbridgeClient;

$client = LongbridgeClient::cnHttp('YOUR_OAUTH_ACCESS_TOKEN');
$client = LongbridgeClient::hkHttp('Bearer YOUR_OAUTH_ACCESS_TOKEN');

刷新 OAuth token 后:

$client->setAccessToken('NEW_OAUTH_ACCESS_TOKEN');

Legacy 签名

legacy 使用 app_key + app_secret + app_access_token 签名。这里的 app_access_token 不要带 Bearer,SDK 会自动生成 X-Api-KeyX-TimestampX-Api-Signature

$client = LongbridgeClient::cnLegacy(
    appKey: 'APP_KEY',
    appSecret: 'APP_SECRET',
    accessToken: 'LEGACY_APP_ACCESS_TOKEN',
);

$client = LongbridgeClient::hkLegacy(
    appKey: 'APP_KEY',
    appSecret: 'APP_SECRET',
    accessToken: 'LEGACY_APP_ACCESS_TOKEN',
);

Hybrid

同时传 OAuth 和 legacy 时,普通 HTTP API 默认优先 OAuth,不会在请求失败后自动切换 legacy,避免下单、创建、修改类接口被重复执行。WebSocket OTP 会优先用 OAuth 获取;没有 OAuth 时使用 legacy 签名。

$client = LongbridgeClient::cnHybrid(
    legacyAppKey: 'APP_KEY',
    legacyAppSecret: 'APP_SECRET',
    legacyAccessToken: 'LEGACY_APP_ACCESS_TOKEN',
    accessToken: 'OAUTH_ACCESS_TOKEN',
);

兼容旧入口:

$client = LongbridgeClient::cnOAuth(
    legacyAppKey: 'APP_KEY',
    legacyAppSecret: 'APP_SECRET',
    legacyAccessToken: 'LEGACY_APP_ACCESS_TOKEN',
    accessToken: 'OAUTH_ACCESS_TOKEN',
);

调用未封装接口:

$data = $client->http()->get('/v1/asset/account');      // hybrid 默认客户端
$data = $client->oauthHttp()->get('/v1/socket/token');  // 强制 OAuth
$data = $client->legacyHttp()->get('/v1/socket/token'); // 强制 legacy 签名

OAuth 获取 Token

生成授权地址:

php examples/oauth_authorize_url.php <client_id> <redirect_uri>

使用回调里的 code 换取 token:

php examples/exchange_code.php <client_id> <redirect_uri> <code> <code_verifier>

HTTP API 示例

资产:

$balance = $client->asset()->getAccountBalance(['USD', 'HKD']);
$stocks = $client->asset()->getStockPositions(['AAPL.US', '700.HK']);
$funds = $client->asset()->getFundPositions();

交易:

$order = $client->trade()->submitOrder([
    'symbol' => 'AAPL.US',
    'order_type' => 'LO',
    'side' => 'Buy',
    'submitted_quantity' => '1',
    'submitted_price' => '180',
    'time_in_force' => 'Day',
]);

$orders = $client->trade()->getTodayOrders(['symbol' => 'AAPL.US']);
$detail = $client->trade()->getOrderDetail((string)$order['order_id']);

账户、市场和基本面:

$plans = $client->dca()->listPlans(['status' => 'Active']);
$alerts = $client->alert()->listAlerts('AAPL.US');
$profit = $client->portfolio()->profitAnalysis([
    'start_date' => '2026-01-01',
    'end_date' => '2026-05-19',
]);

$status = $client->market()->marketStatus();
$earnings = $client->calendar()->earningsCalendar('2026-05-01', '2026-05-31');
$profile = $client->fundamental()->companyProfile('AAPL.US');

HTTP 行情辅助:

$groups = $client->quoteHttp()->watchlistGroups();
$filings = $client->quoteHttp()->filings('AAPL.US');
$securities = $client->quoteHttp()->securityList('US', 'stock');

WebSocket 行情

自动获取 OTP、连接并鉴权:

$quote = $client->quoteSocket();

如果你已经有 OTP 或底层连接:

$ws = $client->quoteWs('SOCKET_OTP');
$quote = $client->quoteSocket($ws);

拉取行情:

use Brown\Longbridge\Proto\Quote\CalcIndex;
use Brown\Longbridge\Proto\Quote\Period;

$profile = $quote->pull()->userQuoteProfile('zh-CN');
$quotes = $quote->pull()->quote(['AAPL.US', '700.HK']);
$depth = $quote->pull()->depth('AAPL.US');
$trades = $quote->pull()->trades('AAPL.US', 50);
$intraday = $quote->pull()->intraday('AAPL.US', ['trade_session' => 0]);
$klines = $quote->pull()->candlesticks('AAPL.US', Period::DAY, 100);
$history = $quote->pull()->historyCandlesticks('AAPL.US', Period::DAY, [
    'start_date' => '2026-01-01',
    'end_date' => '2026-05-20',
]);
$indexes = $quote->pull()->calcIndexes(['AAPL.US'], [
    CalcIndex::CALCINDEX_LAST_DONE,
    CalcIndex::CALCINDEX_VOLUME,
]);

订阅和等待推送:

$quote->subscribe()->subscribeQuote(['AAPL.US']);
$quote->subscribe()->subscribe(['AAPL.US'], ['quote', 'depth', 'trade']);

$push = $quote->push()->wait();
$quotePush = $quote->push()->waitQuote();
$depthPush = $quote->push()->waitDepth();

退订和查询订阅:

$current = $quote->subscribe()->subscriptions();
$quote->subscribe()->unsubscribe(['AAPL.US'], ['quote', 'depth']);
$quote->subscribe()->unsubscribe(unsubAll: true);

WebSocket 交易推送

交易推送连接使用 openapi-trade 网关:

$tradeSocket = $client->tradeSocket();
$tradeSocket->push()->subscribePrivate();

$notification = $tradeSocket->push()->waitNotification();
$payload = $notification['payload']['data_json'] ?? $notification['payload']['data'];

退订:

$tradeSocket->push()->unsubscribe(['private']);

异常处理

HTTP 错误抛出 Brown\Longbridge\Exception\LongbridgeException

use Brown\Longbridge\Exception\LongbridgeException;

try {
    $data = $client->asset()->getAccountBalance();
} catch (LongbridgeException $e) {
    echo $e->getMessage();
    echo $e->httpStatus;
    echo $e->responseBody;
}

WebSocket 连接、鉴权、超时和业务状态错误抛出 RuntimeException

开发检查

生成 protobuf:

protoc --proto_path=proto --php_out=generated proto/control.proto
protoc --proto_path=proto --php_out=generated proto/api.proto
protoc --proto_path=proto --php_out=generated proto/subscribe.proto

静态检查:

composer validate --no-check-publish
composer dump-autoload
Get-ChildItem src,generated,examples -Recurse -Filter *.php | ForEach-Object { php -l $_.FullName }

自动化测试:

composer install
composer test

WebSocket 集成测试需要真实 OAuth token 和 ext-swoole,默认不跑真实连接:

LONGBRIDGE_OAUTH_ACCESS_TOKEN=xxx LONGBRIDGE_REGION=cn composer test:integration

phpstudy Windows 环境如果 PHP 8.2 没有默认启用扩展,可以显式指定:

& 'G:\phpstudy_pro\Extensions\php\php8.2.9nts\php.exe' -d extension_dir='G:\phpstudy_pro\Extensions\php\php8.2.9nts\ext' -d extension=openssl -d extension=mbstring -d extension=zip vendor\bin\phpunit