All notable changes to ipwhois/ipwhois-php will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
-
Removed two
curl_close()calls from the internal request handler. The function has been a no-op since PHP 8.0 (curl_init()returns aCurlHandleobject that is automatically freed when it goes out of scope) and was deprecated in PHP 8.5, which made the library emit:Deprecated: Function curl_close() is deprecated since 8.5, as it has no effect since PHP 8.0 in …/src/IPWhois.phpThe handle is now released by PHP's garbage collector at the end of
request(). No behavioural change — public API, return shapes, and error handling are identical to 1.2.0.
- Every error response now carries an
error_typefield, including errors returned by the API. The new value'api'joins the existing'network','environment', and'invalid_argument'codes, so callers can branch on the category of any failure with a single$info['error_type']check — no need to combinesuccesswithhttp_statusto distinguish API vs. non-API errors. Applies to HTTP 4xx / 5xx responses, malformed JSON bodies, and HTTP 2xx responses where the API itself setssuccess: false(e.g. "Invalid IP address", "Reserved range").
retry_afteris now only attached to HTTP 429 responses on the free plan (ipwho.is). The paid endpoint (ipwhois.pro) does not send aRetry-Afterheader, so reading it on paid plans is now skipped and the field will not appear there. Behaviour on the free plan is unchanged.- README "Setting defaults once" section now shows the Free and Paid plans as two separate code blocks, matching the layout used in "Quick start" and "HTTPS Encryption". The setters work identically on both plans, so the lookup-override snippet is shared underneath.
- README "Error response fields" table now lists
messageexplicitly (it has always been present on every error response) and theerror_typerow covers the new'api'value as well.
- The
outputoption has been removed. The library only ever processed JSON responses meaningfully, sooutput=xmlandoutput=csvwere a thin pass-through that returned the raw payload as a string. The option has been dropped fromlookup(),bulkLookup(), and the constructor's$optionsarray; theIPWhois::SUPPORTED_OUTPUTSconstant is gone. Passing'output' => …will silently no-op. - The 2xx + non-JSON success-with-
rawfallback in the response handler (which only existed to support the removedoutputparameter) is gone. The API always returns JSON, so any non-JSON 2xx body is now treated as a transport error and returned as asuccess => falsearray.
setFields()PHPDoc now mentions thatsuccessshould be included in the field whitelist if you rely on$info['success']for error checking — whenfieldsis set, the API only returns the fields you list.- README "Setting defaults once" section rewritten for clarity: the two
ways of passing options (per call vs. as defaults), the available
setters, and the
success-in-fieldsgotcha are now spelled out explicitly. The free/paid example pair was collapsed into a single example, since the setters work identically on both plans. - All examples that filter fields (
README.md,examples/basic.php,examples/defaults.php) now include'success'in the field list.
If your code passes 'output' => 'json' you can simply remove it — the
library always returns the decoded JSON anyway. If you were relying on
'output' => 'xml' or 'output' => 'csv' to get the raw payload, that
use case is no longer supported; call the API directly with cURL for
those formats.
// Before (1.1.3):
$info = $ipwhois->lookup('8.8.8.8', ['output' => 'json', 'fields' => ['country', 'city']]);
// After (1.1.4):
$info = $ipwhois->lookup('8.8.8.8', ['fields' => ['success', 'country', 'city']]);- Bumped
IPWhois::VERSIONconstant to1.1.3(in 1.1.2 it was still set to1.1.2, this release just keeps the constant in sync with the actual released tag). No functional changes since 1.1.2.
- Renamed the main class
ClienttoIPWhoisfor consistency with the package and brand. The fully-qualified name is now\Ipwhois\IPWhois. The source file moved fromsrc/Client.phptosrc/IPWhois.php, and the test class fromtests/ClientTest.phptotests/IPWhoisTest.php. Public behaviour, method signatures, constructor arguments, and return shapes are all unchanged.
// Before (1.1.1):
use Ipwhois\Client;
$client = new Client('YOUR_API_KEY');
$info = $client->lookup('8.8.8.8');
// After (1.1.2+):
use Ipwhois\IPWhois;
$ipwhois = new IPWhois('YOUR_API_KEY');
$info = $ipwhois->lookup('8.8.8.8');The variable name ($client, $ipwhois, anything else) is up to you; only
the class identifier changed.
- Non-JSON responses (when
output=xmloroutput=csvis requested) now includesuccess => truealongside therawpayload, so the universalif (!$info['success'])check documented in README works for these responses too. Previously they only contained therawkey, which made a!$info['success']check evaluate totruefor a successful response. - Updated the
examples/defaults.phpexample to actually follow the success-check contract documented in README.
- Behaviour change: the library never throws. All errors — API errors,
network failures, missing extension, bad input options — are returned in
the response array with
success => falseand amessage. An outage of the ipwhois.io API or of your server's DNS / connection will never surface as a fatal error in your application. - HTTP error responses are additionally enriched with
http_status, and HTTP 429 responses withretry_after(when the API sent aRetry-Afterheader). - Non-API errors carry an
error_typefield ('network','environment', or'invalid_argument') so you can branch on the cause if needed.
// Before (1.0.x):
try {
$info = $ipwhois->lookup('bad.ip');
} catch (\Ipwhois\Exception\ApiException $e) {
error_log($e->getMessage());
} catch (\Ipwhois\Exception\NetworkException $e) {
error_log($e->getMessage());
}
// After (1.1.0+):
$info = $ipwhois->lookup('bad.ip');
if (!$info['success']) {
error_log($info['message']);
}- All exception classes (
IpwhoisException,ApiException,AuthenticationException,RateLimitException,NetworkException) have been removed. The library never throws, so they had no purpose. Code that imported them from 1.0.x will need to drop thoseusestatements; code that only calledlookup()/bulkLookup()and read the result is unaffected.
- The library now actually runs on PHP 8.0, matching the version constraint
declared in
composer.json. Previous releases usedreadonlyproperties, which require PHP 8.1+. Replaced them with classicalprivateproperties with constructor assignment — public API and exception behaviour are unchanged.
- Initial release.
IPWhois::lookup()— single IP lookup (IPv4 / IPv6, or current IP).IPWhois::bulkLookup()— up to 100 IPs in a single GET request (paid plan).- Localisation, field filtering, threat detection (
security), rate info. - Optional
'ssl' => falseflag to fall back to HTTP. - Typed exceptions:
IpwhoisException,ApiException,AuthenticationException,RateLimitException,NetworkException. - Fluent setters for client-wide defaults.
- PHPUnit test suite covering URL construction and input validation.