chronoarc/comicvine
Composer 安装命令:
composer require chronoarc/comicvine
包简介
A PHP wrapper for the Comicvine API
关键字:
README 文档
README
A lightweight, slightly opinionated PHP SDK for the ComicVine API, built on top of Saloon v4. Every documented ComicVine endpoint is covered, with typed DTOs for every response.
📦 Installation
composer require chronoarc/comicvine
Requires PHP 8.2+. Grab an API key at comicvine.gamespot.com/api.
🚀 Quick start
use Chronoarc\Comicvine\Comicvine; $comicvine = new Comicvine('your-api-key'); // Fetch a single resource — /issue/4000-6 $issue = $comicvine->issues()->get(6)->dto(); echo $issue->name; // "The Lost Race" echo $issue->volume->name; // "Chamber of Chills Magazine" echo $issue->image->originalUrl; // List resources — /volumes $volumes = $comicvine->volumes()->all(limit: 50)->dto(); echo $volumes->numberOfTotalResults; foreach ($volumes->results as $volume) { echo $volume->name; } // Search everything — /search $results = $comicvine->search()->query('Batman', resources: ['character'])->dto();
Every resource method returns a Saloon Response; you choose how to consume it:
$response = $comicvine->characters()->get(1699); $response->dto(); // typed DTO (Character) $response->json(); // raw decoded payload $response->status(); // HTTP status code
🗂 Resources
Every ComicVine resource is exposed through a method on the Comicvine connector:
| Connector method | Endpoints | DTOs |
|---|---|---|
$comicvine->characters() |
/characters, /character |
Character, CharactersList |
$comicvine->chats() |
/chats, /chat |
Chat, ChatsList |
$comicvine->concepts() |
/concepts, /concept |
Concept, ConceptsList |
$comicvine->episodes() |
/episodes, /episode |
Episode, EpisodesList |
$comicvine->issues() |
/issues, /issue |
Issue, IssuesList |
$comicvine->locations() |
/locations, /location |
Location, LocationsList |
$comicvine->movies() |
/movies, /movie |
Movie, MoviesList |
$comicvine->objects() |
/objects, /object |
ComicObject, ObjectsList |
$comicvine->origins() |
/origins, /origin |
Origin, OriginsList |
$comicvine->people() |
/people, /person |
Person, PeopleList |
$comicvine->powers() |
/powers, /power |
Power, PowersList |
$comicvine->promos() |
/promos, /promo |
Promo, PromosList |
$comicvine->publishers() |
/publishers, /publisher |
Publisher, PublishersList |
$comicvine->search() |
/search |
SearchResults |
$comicvine->series() |
/series_list, /series |
Series, SeriesList |
$comicvine->storyArcs() |
/story_arcs, /story_arc |
StoryArc, StoryArcsList |
$comicvine->teams() |
/teams, /team |
Team, TeamsList |
$comicvine->videoCategories() |
/video_categories, /video_category |
VideoCategory, VideoCategoriesList |
$comicvine->videos() |
/videos, /video |
Video, VideosList |
$comicvine->videoTypes() |
/video_types, /video_type |
VideoType, VideoTypesList |
$comicvine->volumes() |
/volumes, /volume |
Volume, VolumesList |
$comicvine->meta() |
/types |
Type, TypesList |
All list endpoints share the same signature:
$comicvine->issues()->all( limit: 100, // page size, API max is 100 offset: 200, // zero-based offset for pagination fieldList: ['id', 'name', 'volume'], // trim the response to specific fields sort: 'cover_date:desc', // field:asc or field:desc filter: ['volume' => 1487], // field => value pairs );
All detail endpoints share the same signature:
$comicvine->characters()->get(1699, fieldList: ['id', 'name', 'publisher']);
Pagination
List DTOs extend PaginatedList and expose the full envelope:
$page = $comicvine->issues()->all(limit: 100)->dto(); $page->numberOfTotalResults; // e.g. 1024872 $page->numberOfPageResults; // e.g. 100 $page->limit; // 100 $page->offset; // 0 $page->hasMorePages(); // true $next = $comicvine->issues()->all(limit: 100, offset: $page->offset + $page->limit)->dto();
Search
/search paginates with a 1-based page parameter and caps limit at 10.
Results are mixed-type: each item is hydrated into the DTO matching its
resource_type (unknown types are kept as raw arrays):
use Chronoarc\Comicvine\Dto\Character\Character; $results = $comicvine->search()->query('Batman', resources: ['character', 'volume'], page: 1)->dto(); foreach ($results->results as $result) { if ($result instanceof Character) { echo $result->realName; // "Bruce Wayne" } }
🧬 DTOs
- Every DTO is
readonlyand hydrated via::fromArray(); you never parse JSON yourself. - Fields the API omits — association fields on list responses, or anything excluded via
field_list— arenull, never missing.nullmeans "not fetched", an empty array means "fetched, and empty". - Cross-resource pointers are
Referenceobjects (id,name,apiDetailUrl,siteDetailUrl). Specialised references add context:IssueReference(issueNumber),EpisodeReference(episodeNumber),PersonCredit(role),CountedReference(count, used by volume credits). imagefields hydrate intoImagewith all size renditions (iconUrl…originalUrl).- Gender is the
Chronoarc\Comicvine\Enum\Genderenum (Other/Male/Female). - Quirks are normalised: the story arc
count_of_isssue_appearancestypo (sic, ComicVine's spelling) maps tocountOfIssueAppearances, and a person'sdeathobject is flattened to a date string.
⚠️ Error handling
The connector uses Saloon's AlwaysThrowOnErrors, so any non-2xx response throws a Saloon request exception:
use Saloon\Exceptions\Request\RequestException; try { $comicvine->issues()->get(999999999)->dto(); } catch (RequestException $e) { $e->getResponse()->status(); }
ComicVine rate-limits API keys to 200 requests per resource per hour. Be a good citizen: request only the fields
you need via fieldList, and cache responses where you can.
🧩 Extending
The SDK is deliberately thin so you can reach into any layer:
- Custom requests — extend
Chronoarc\Comicvine\Requests\ListRequestorDetailRequestand send them with$comicvine->send(new MyRequest()). - Saloon features — the connector is a regular Saloon connector: middleware, retries, caching plugins and mock clients all work as documented at docs.saloon.dev.
- Raw responses — skip DTOs entirely with
->json()when you need something the DTOs don't model.
🧪 Testing
composer test
Tests use Saloon's MockClient with recorded fixtures — no live API calls, no API key needed.
The test suite also demonstrates how to mock the SDK in your own app:
use Chronoarc\Comicvine\Requests\GetIssueRequest; use Saloon\Http\Faking\MockClient; use Saloon\Http\Faking\MockResponse; $mockClient = new MockClient([ GetIssueRequest::class => MockResponse::fixture('valid_single_issue'), ]); $comicvine = new Comicvine('fake-key'); $comicvine->withMockClient($mockClient);
🤝 Contributions Welcome
Your feedback and contributions are highly appreciated! Whether it's submitting an issue, suggesting improvements, or adding new features, every bit helps make this SDK better for everyone.
Feel free to fork the repository, make pull requests, or just share ideas! Let's make this SDK awesome together.
统计信息
- 总下载量: 11
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 1
- 点击次数: 3
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2024-11-15