KnpLabs php-github-api: an object oriented GitHub client for PHP
A simple PHP GitHub API client, Object Oriented, tested and documented.
At a glance
- What is it?
- A Composer package that wraps the GitHub API in PHP classes, decoupled from any HTTP client through HTTPlug, and used by Laravel applications that need more than hand rolled requests.
- Who is it for?
- php-github-api is the kind of library that has quietly outlived several changes to the platform underneath it. It stays inside PHP, it accepts any PSR-18 client, and it hands you typed results from an API that GitHub keeps versioned.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 55 days ago.
- What is it written in?
- Mainly PHP, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 11, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Installing the Composer package with Guzzle
The quick install pulls three packages at once: the library itself, an HTTP client, and a PSR-17 factory implementation. That combination is not decoration. php-github-api declares no dependency on any particular HTTP client, so something has to supply both the transport and the message factory before the client can build a request.
composer require knplabs/github-api:^3.0 guzzlehttp/guzzle:^7.0.1 http-interop/http-factory-guzzle:^1.0The stated requirements are PHP 7.2 or newer plus a PSR-17 factory and a PSR-18 client. Requiring an interface rather than an implementation is what lets the same code run against Guzzle, Symfony's HTTP client, or anything else that satisfies those two contracts.
The first call is three lines. The `api` method takes the API family as its argument and returns an object with the endpoints under it:
<?php
// This file is generated by Composer
require_once __DIR__ . '/vendor/autoload.php';
$client = new \Github\Client();
$repositories = $client->api('user')->repositories('ornicar');The version constraint to notice is `^3.0`. The repository tree contains both `UPGRADE-3.0.md` and `UPGRADE-4.0.md`, so a major upgrade path exists and is documented even though only the 3.x line is on Packagist in that command.
Swapping the HTTP client without touching call sites
The decoupling is real rather than theoretical. The advanced install swaps Guzzle for Symfony's HTTP client and Nyholm's PSR-7 implementation, then hands the result to a factory:
composer require knplabs/github-api:^3.0 symfony/http-client nyholm/psr7The README notes that this works through HTTPlug, and points at `doc/customize.md` for the wider set of options. Symfony's `HttplugClient` adapter is what bridges their client to the PSR-18 interface the library expects, so the object you pass in is a wrapper, not the client itself.
That design has a cost worth naming. Because the library only knows about PSR-18 and PSR-17, anything you want from your HTTP client's own feature set, such as middleware, retries, or a mocking layer, has to be expressed through those interfaces or live outside the library. The README does not enumerate what is lost. It also does not say how authentication is configured in this example, because `new \Github\Client()` with no arguments performs unauthenticated requests, which GitHub rate limits far more aggressively than authenticated ones.
Caching responses to stay under the rate limit
The caching section is the most practically useful part of the README, because it explains what the library does about GitHub's `X-Rate-Limit` header rather than leaving it to you. Any PSR-6 pool will do; the example uses the Redis adapter.
<?php
// This file is generated by Composer
require_once __DIR__ . '/vendor/autoload.php';
use Cache\Adapter\Redis\RedisCachePool;
$client = new \Redis();
$client->connect('127.0.0.1', 6379);
// Create a PSR6 cache pool
$pool = new RedisCachePool($client);
$client = new \Github\Client();
$client->addCache($pool);
// Do some request
// Stop using cache
$client->removeCache();The README's claim is that with a cache attached the client returns stored responses when the resource has not changed, without consuming a request against GitHub's rate limit. Two details are worth flagging. First, the example reuses the variable name `$client` for both the Redis connection and the GitHub client, which works but reads as a copy paste artifact. Second, `removeCache()` exists as a separate call, which implies the pool stays attached for the lifetime of the object rather than being scoped to a single request. Whether the cache honours conditional requests or stores responses unconditionally is something the README leaves to `doc/`.
For an application that polls on a schedule, this is the difference between working and getting throttled.
What the feature list claims, and what the release notes show
The README's feature list has two bullets: lazy loading of API classes, and being extensively tested and documented. Both are checkable. Lazy loading is the reason the package feels light despite covering a large API surface, since an endpoint class is only built when you ask for it. The testing claim is backed by a `test/` directory, a `phpunit.xml.dist`, a `phpstan.neon.dist`, a StyleCI badge, and a GitHub Actions workflow for CI.
The release notes are more informative than the feature list. The most recent tag, v3.16.1 on 2026-08-18, is a single fix: handling 422 responses where the `errors` field arrives as a string rather than the expected structure. That is a small patch, but it tells you something real about how the library models errors, and it is exactly the kind of breakage that hits when GitHub adjusts one endpoint's validation payload.
The two tags before it are worth contrasting. v3.16.0 from 2024-11-07 added endpoints for re-requesting a check run and for listing pull requests associated with a commit. v3.15.0 from 2024-09-23 is the more substantial one, adding organization role endpoints and Copilot usage endpoints, fixing a type error in `ResultPager::fetch`, and changing implicit nullable types to silence PHP 8.4 warnings. That last item is the pattern to watch: the library is tracking PHP's forward deprecation warnings as the language tightens.
There is a gap between v3.15.0 in September 2024 and v3.16.0 in November 2024, and then roughly twenty months to v3.16.1. The repository is not archived and the last push matches the v3.16.1 date, so this is a maintained project on a quiet cadence rather than an abandoned one.
Version coverage, license, and the framework story
The README's opening line says the library uses GitHub API v3 and supports v4, and explains that the object API in v3 resembles the REST API. That distinction matters more than it first appears. v3 is organized around HTTP verbs and paths, which is why a PHP client can mirror it with one class per resource and a method per endpoint. GraphQL, which is what API v4 is, has a single endpoint and a query document instead, so supporting it means the object model has to work differently. The contributor list credits Miguel Piedrafita specifically for the v4 and Apps API work, which suggests that part of the surface has had less continuous attention than the v3 object API.
The license is MIT, stated in the README and matching the `LICENSE` file in the tree. That is about as permissive as a dependency gets, which is part of why a package with 2,200 stars and 586 forks is easy to adopt commercially. Open issues sit at 52, which is modest for a project this size.
For Laravel there is a supported path rather than a DIY one. The README points at GrahamCampbell's Laravel-GitHub package, which wraps this library with service provider registration and configuration. Maintenance is named rather than implied: the README lists @acrobat and @Nyholm as maintainers, credits Thibault Duplessis for the original version, and asks that you read the project's FOSS maintenance announcement before opening anything. That is a small signal, and a useful one, that response expectations are set somewhere other than the issue tracker.
Editorial conclusion
php-github-api is the kind of library that has quietly outlived several changes to the platform underneath it. It stays inside PHP, it accepts any PSR-18 client, and it hands you typed results from an API that GitHub keeps versioned. What the README will not tell you is which endpoints are covered today or how the client behaves when GitHub changes a response shape, and both of those live in the doc directory rather than on this page. For a Laravel team, the practical first step is GrahamCampbell's Laravel-GitHub wrapper rather than this package directly, since it handles the container binding and authentication for you. For anything else, install the Composer line, add a cache pool if you are polling on a schedule, and read doc/customize.md before assuming the client is swappable without cost.
Frequently asked questions
Is the GitHub API free?
That is a question about GitHub's own policy rather than about this library, and the library does not set or change it. What php-github-api does is give you one place to attach a PSR-6 cache so repeated reads of unchanged resources can be served without spending a request against the limit. Authentication configuration is left to the client you construct.
Which HTTP client does php-github-api need?
Any PSR-18 client plus a PSR-17 factory implementation. The quick install pairs Guzzle 7 with the Guzzle factory from http-interop, and the advanced section shows Symfony's HTTP client wrapped in HttplugClient with Nyholm's PSR-7 objects. The library declares both interfaces as requirements rather than depending on a specific package.
Does php-github-api support GitHub API v4?
The README states that it uses GitHub API v3 and supports v4. The object API follows the RESTful shape of v3 closely, which is why one class per resource works. The contributor list credits a specific person for the v4 and Apps API contributions, so treat v3 coverage as the more exercised surface.
How do I reduce rate limiting when polling GitHub from PHP?
Attach a PSR-6 cache pool with the client's addCache method, then remove it when you no longer want cached behaviour. The README states that with a cache the client returns stored responses for resources that have not changed, without reaching GitHub's X-Rate-Limit. The example uses the Redis adapter, and any PSR-6 implementation works in its place.
Which Laravel package should I use for GitHub access?
For Laravel specifically, the README points at GrahamCampbell's Laravel-GitHub, which wraps this library and handles integration for the framework. That avoids wiring the client and its PSR dependencies into a service provider yourself. Outside Laravel, install knplabs/github-api directly and follow doc/customize.md for client selection.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/knplabs-php-github-api)