porkbun-php/client
Composer 安装命令:
composer require porkbun-php/client
包简介
PHP client for the Porkbun API v3 with domain-centric design, typed DTOs, and complete endpoint coverage
README 文档
README
Porkbun PHP API Client
A community-maintained PHP 8.4+ client for the Porkbun API v3 with complete endpoint coverage, domain-centric design, and Laravel integration.
Features
- Complete API coverage — all 27 Porkbun API v3 endpoints: DNS, DNSSEC, SSL, nameservers, URL forwarding, glue records, domains, pricing, and more
- Domain-centric design — fluent API:
$client->domain('example.com')->dns()->all() - Typed everything — immutable DTOs, backed enums, strict return types throughout
- Fluent builders — validated DNS record construction with convenience methods
- Structured errors — typed exception hierarchy with request/response context
- Laravel integration — service provider, facade, and config publishing out of the box
- PSR-18 compatible — works with any HTTP client (Guzzle, Symfony, curl, etc.)
- Strict quality — Pint, Pest, PHPStan, PHP 8.4+ with Rector
Requirements
- PHP 8.4+
- A PSR-18 HTTP client (Guzzle, Symfony HttpClient, or any other)
Installation
composer require porkbun-php/client
If you don't already have a PSR-18 HTTP client installed, add one:
composer require guzzlehttp/guzzle
# or
composer require symfony/http-client nyholm/psr7
Tip
Most frameworks already ship with a PSR-18 client — Laravel includes Guzzle, Symfony includes its HttpClient. The package auto-discovers it, so new Porkbun\Client() just works.
Quick Start
Generate your API key and secret on the API Access page. To manage a specific domain via API, enable API Access for that domain in your Porkbun control panel.
$client = new Porkbun\Client(); $client->authenticate('pk1_your_api_key', 'sk1_your_secret_key'); // Test connectivity $ping = $client->ping(); echo "Your IP: {$ping->resolvedIp}"; // Domain pricing (no auth required) $pricing = $client->pricing()->all(); echo "COM: $" . $pricing->find('com')?->registrationPrice; // Domain-centric operations $domain = $client->domain('example.com'); // List DNS records foreach ($domain->dns()->all() as $record) { echo "{$record->name} {$record->type->value} {$record->content}\n"; } // Get SSL certificate $cert = $domain->ssl(); echo $cert->certificateChain;
Advanced configuration
// Custom PSR-18 HTTP client $client = new Porkbun\Client($myPsr18Client); // IPv4-only endpoint (useful for dynamic DNS) $client->useIpv4Endpoint(); $client->useDefaultEndpoint(); // back to dual-stack // Switch accounts at runtime $client->authenticate($account2Key, $account2Secret); $client->clearAuth(); // back to unauthenticated
API Reference
Note
All endpoints require authentication except Pricing — you can query TLD pricing without API keys.
Pricing (No Auth Required)
$pricing = $client->pricing()->all(); $pricing->find('com')?->registrationPrice; // float $pricing->find('com')?->renewalPrice; // float $pricing->cheapest(10); // Top 10 cheapest TLDs $pricing->tlds(); // All available TLD keys
Ping (Auth Test)
$ping = $client->ping(); $ping->resolvedIp; // Your IP address (prefers forwarded IP) $ping->forwardedIp; // Forwarded IP (from X-Forwarded-For header) $ping->yourIp; // Raw IP from API response
Domains
// List all domains (iterates all pages automatically) foreach ($client->domains()->all() as $domain) { echo "{$domain->domain} expires {$domain->expireDate?->format('Y-m-d')}\n"; } // Single page with pagination metadata $page = $client->domains()->list(); $page->domains(); // DomainCollection (also available via iteration/count/json on $page itself) $page->hasMore; // bool — true if more pages exist $page->nextStart; // ?int — pass to list() for the next page $page->start; // int — current offset // PaginatedResult is iterable, countable, and JSON-serializable: count($page); // number of domains on this page json_encode($page); // serializes with pagination metadata foreach ($page as $domain) { /* ... */ } // Paginate manually $page = $client->domains()->list(start: 0, includeLabels: true); while ($page->hasMore) { $page = $client->domains()->list(start: $page->nextStart); } // Find a specific domain $domain = $client->domains()->find('example.com'); // Domain DTO or null // Bulk auto-renewal management $client->domains()->enableAutoRenew('example.com', 'other.com'); $client->domains()->disableAutoRenew('example.com');
Domain Details
$domain = $client->domain('example.com'); $info = $domain->details(); // Domain DTO (from your account) $info->domain; // 'example.com' $info->status; // 'ACTIVE' $info->expireDate; // ?DateTimeImmutable $info->autoRenew; // ?bool $info->tld; // 'com'
Domain Availability
$result = $client->domain('example.com')->check(); $result->isAvailable; // bool $result->price; // ?float (registration price) $result->type; // string — 'standard', 'premium', etc. $result->priceInCents; // ?int (e.g., 999 for $9.99) $result->effectivePrice; // ?float (promo price if available, else regular)
Domain Registration
$result = $client->domain('newdomain.com')->register(868); $result->domain; // 'newdomain.com' $result->orderId; // int $result->costInCents; // int $result->costInDollars; // float (computed) $result->balanceInCents; // int $result->balanceInDollars; // float (computed)
DNS Records
Tip
Use the builder for validated record creation, or direct methods when you need to bypass client-side validation.
$dns = $client->domain('example.com')->dns(); // Retrieve $dns->all(); // DnsRecordCollection $dns->find($recordId); // DnsRecord or null $dns->findByType('A'); // DnsRecordCollection $dns->findByType('A', 'www'); // By type and subdomain // Create (direct) $result = $dns->create('A', 'www', '192.0.2.1', ttl: 3600); echo "Created record: {$result->id}"; // Create (builder — recommended) $result = $dns->createFromBuilder( $dns->record() ->a('192.0.2.2') ->name('api') ->ttl(3600) ->notes('API server') ); // Builder convenience methods $dns->record()->mx('mail.provider.com', priority: 10)->name('mail'); $dns->record()->txt('v=DMARC1; p=reject')->name('_dmarc'); $dns->record()->cname('blog.provider.com')->name('blog'); $dns->record()->aaaa('2001:db8::1')->name('app'); // Enum types are also accepted use Porkbun\Enum\DnsRecordType; $dns->findByType(DnsRecordType::A); $dns->create(DnsRecordType::A, 'www', '192.0.2.1'); // Update (direct or builder) $dns->update($recordId, 'A', 'www', '192.0.2.3'); $dns->updateFromBuilder($recordId, $dns->record()->a('192.0.2.3')->name('www')); $dns->updateByType('A', 'www', '192.0.2.3'); // Delete $dns->delete($recordId); $dns->deleteByType('A', 'old-subdomain'); // Collection helpers (all collections support first(), last(), count()) $records = $dns->all(); $records->byType('MX'); $records->byName('www'); $records->rootRecords; $records->byType('A')->first();
DNSSEC Records
$dnssec = $client->domain('example.com')->dnssec(); $dnssec->all(); // DnssecRecordCollection $result = $dnssec->create(keyTag: 12345, algorithm: 13, digestType: 2, digest: 'abc123...'); $result->message; // ?string $dnssec->delete($keyTag);
Batch DNS Operations
$dns = $client->domain('example.com')->dns(); // Pre-wired batch builder — no need to pass $dns to execute() $results = $dns->batch() ->addRecord('A', 'www', '192.0.2.1') ->addRecord('A', 'api', '192.0.2.2') ->add($dns->record()->mx('mail.example.com', priority: 10)) // builder-based add ->updateRecord($existingId, 'A', 'www', '192.0.2.3', ttl: 3600) ->deleteRecord($oldRecordId) ->deleteByType('TXT', 'old-subdomain') ->execute(); if ($results->hasFailures()) { echo "Some operations failed!\n"; } foreach ($results as $result) { if ($result->success) { echo "OK: {$result->operation->value}\n"; } else { echo "Failed: {$result->error}\n"; } }
SSL Certificates
$cert = $client->domain('example.com')->ssl(); $cert->certificateChain; $cert->privateKey; $cert->publicKey; $cert->fullChain; // Chain + intermediate $cert->hasPrivateKey; // bool $cert->hasCertificate; // bool $cert->hasIntermediateCertificate; // bool
Nameservers
$ns = $client->domain('example.com')->nameservers(); $ns->all(); // NameserverCollection: ['ns1.porkbun.com', 'ns2.porkbun.com'] $ns->update('ns1.custom.com', 'ns2.custom.com');
URL Forwarding
$forwards = $client->domain('example.com')->urlForwarding(); $forwards->all(); // UrlForwardCollection $result = $forwards->create('https://destination.example.com', 'temporary', subdomain: 'go'); $result->message; // ?string $forwards->delete($recordId);
Glue Records
$glue = $client->domain('example.com')->glueRecords(); $glue->all(); // GlueRecordCollection $result = $glue->create('ns1', '192.0.2.1', '192.0.2.2'); $result->message; // ?string $glue->update('ns1', '192.0.2.10'); $glue->delete('ns1'); // OperationResult
Auto-Renewal
$autoRenew = $client->domain('example.com')->autoRenew(); $result = $autoRenew->enable(); // AutoRenewResult $result->success; // bool $result->message; // ?string $autoRenew->disable();
Error Handling
All exceptions implement Porkbun\Exception\ExceptionInterface for unified catching:
use Porkbun\Exception\ApiException; use Porkbun\Exception\AuthenticationException; use Porkbun\Exception\InvalidArgumentException; use Porkbun\Exception\NetworkException; use Porkbun\Exception\ExceptionInterface; try { $client->domains()->list(); } catch (AuthenticationException $e) { // Invalid or missing API credentials (403) } catch (ApiException $e) { // API returned an error (4xx/5xx) $e->getStatusCode(); $e->getRequest(); $e->getResponse(); } catch (NetworkException $e) { // HTTP/connection failure $e->getRequest(); } catch (InvalidArgumentException $e) { // Invalid parameters (bad DNS type, empty domain list, etc.) } catch (ExceptionInterface $e) { // Catch-all for any library exception }
Tip
If the default endpoint is unreachable, fall back to $client->useIpv4Endpoint(). See 08-error-handling.php for the full pattern.
Laravel Integration
The package auto-registers via Laravel's package discovery. The service provider is deferred — the client is only instantiated when you use it.
Add credentials to .env:
PORKBUN_API_KEY=pk1_your_key PORKBUN_SECRET_KEY=sk1_your_secret PORKBUN_ENDPOINT=default # or 'ipv4' for IPv4-only
Optionally publish the config:
php artisan vendor:publish --tag=porkbun-config
Facade
use Porkbun\Laravel\Facades\Porkbun; $domains = Porkbun::domains()->list(); $records = Porkbun::domain('example.com')->dns()->all();
Dependency Injection
use Porkbun\Client; class DnsController { public function index(Client $client) { return $client->domain('example.com')->dns()->all(); } }
Examples
See the examples/ directory for runnable scripts:
01-ping.php- Auth test and IPv4 endpoint switching02-pricing.php- Public pricing API, cheapest TLDs, iteration03-domains.php- List domains, pagination, expiring soon, availability check04-dns.php- DNS CRUD with direct methods, collection helpers05-dns-builder.php- Fluent builder, convenience methods, immutable templates06-dns-batch.php- Batch operations, mixed create/edit/delete07-domain-services.php- Nameservers, URL forwarding, glue records, SSL, auto-renew08-error-handling.php- Exception hierarchy, endpoint fallback pattern09-dynamic-dns.php- Real-world dynamic DNS updater recipe10-multi-account.php- Account switching, public/auth/clearAuth flow11-laravel.php- Facade usage, dependency injection, Artisan commands
Development
composer install composer run check # code style + static analysis + tests composer run fix # auto-fix style issues composer run test # run test suite
License
MIT License. See LICENSE for details.
porkbun-php/client 适用场景与选型建议
porkbun-php/client 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 11 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 03 月 14 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「api」 「dns」 「domain」 「ssl」 「API-Client」 「porkbun」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 porkbun-php/client 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 porkbun-php/client 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 porkbun-php/client 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Build a domain-oriented application on Laravel Framework
A PSR-7 compatible library for making CRUD API endpoints
Command bus implementation: Commands and domain events
A module manager for Zend Framework which can be used to create configs per domain.
An advanced PHP library for email validation with DNS checks and typo suggestions.
DDD auth basic class
统计信息
- 总下载量: 11
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 39
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-03-14
