Skip to content

Instantly share code, notes, and snippets.

@daemondevin
Created March 9, 2026 02:22
Show Gist options
  • Select an option

  • Save daemondevin/95acf2ed771a0a3f596110afdcaa71de to your computer and use it in GitHub Desktop.

Select an option

Save daemondevin/95acf2ed771a0a3f596110afdcaa71de to your computer and use it in GitHub Desktop.
Gravatar API Client—A clean, zero-dependency PHP class for working with the Gravatar API.

Gravatar PHP

A clean, zero-dependency PHP class for working with the Gravatar API. Supports avatar image URLs, public profile data, QR codes, and the authenticated Gravatar API v3 — all through a fluent, chainable interface.

Requirements

  • PHP 8.1 or higher
  • allow_url_fopen enabled (for profile fetching and avatar existence checks)

Installation

Copy Gravatar.php into your project and include it:

require_once 'Gravatar.php';

Quick Start

// Simple avatar URL
$gravatar = new Gravatar('user@example.com');
echo $gravatar->url();
// https://secure.gravatar.com/avatar/b58996c504c5638798eb6b511e6f49af?s=80&d=mp&r=g

// Fluent static factory
echo Gravatar::for('user@example.com')->size(200)->url();

// Drop an avatar directly into a template
echo Gravatar::for('user@example.com')
    ->size(120)
    ->rating(Gravatar::RATING_G)
    ->defaultImage(Gravatar::DEFAULT_IDENTICON)
    ->imageTag('Jane Smith', ['class' => 'avatar rounded']);

Avatar Images

url(array $overrides = []): string

Returns the full avatar image URL. Accepts optional per-call overrides so you can reuse one configured instance across multiple contexts.

$g = new Gravatar('user@example.com');
$g->size(80)->rating(Gravatar::RATING_G)->defaultImage(Gravatar::DEFAULT_MP);

echo $g->url();
// Override size for a single call without changing the instance
echo $g->url(['size' => 200]);

imageTag(string $alt = '', array $attrs = []): string

Returns a complete, escaped <img> tag. The src, width, and height attributes are set automatically; pass $attrs to merge in anything else.

echo Gravatar::for('user@example.com')
    ->size(64)
    ->imageTag('Profile photo', [
        'class'   => 'avatar rounded-circle',
        'loading' => 'lazy',
    ]);
// <img src="https://secure.gravatar.com/avatar/..." alt="Profile photo" width="64" height="64" class="avatar rounded-circle" loading="lazy">

exists(): bool

Makes a HEAD request using the 404 default. Returns true only if Gravatar has a real avatar on file for the email.

if (Gravatar::for('user@example.com')->exists()) {
    echo 'Custom avatar found.';
} else {
    echo 'No Gravatar registered.';
}

Configuration Options

All setters return $this for chaining.

size(int $size): static

Avatar dimensions in pixels. Gravatar returns square images. Valid range: 1–2048. Default: 80.

$g->size(256);

defaultImage(string $default): static

What to show when no Gravatar exists for the email. Pass one of the built-in constants or a fully-qualified URL to your own fallback image.

$g->defaultImage(Gravatar::DEFAULT_RETRO);
$g->defaultImage('https://example.com/fallback-avatar.png');
Constant Description
DEFAULT_404 Return an HTTP 404 — useful for detecting missing avatars
DEFAULT_MP Mystery person silhouette (default)
DEFAULT_IDENTICON Geometric pattern unique to the email hash
DEFAULT_MONSTERID Randomly generated monster illustration
DEFAULT_WAVATAR Randomly generated cartoon face
DEFAULT_RETRO 8-bit pixel art
DEFAULT_ROBOHASH Randomly generated robot
DEFAULT_BLANK Transparent 1×1 PNG

rating(string $rating): static

Maximum content rating to display. Avatars rated above this threshold fall back to the default image. Default: g.

$g->rating(Gravatar::RATING_PG);
Constant Meaning
RATING_G Suitable for all audiences (default)
RATING_PG May contain mildly offensive content
RATING_R May contain harsh content
RATING_X May contain explicit content

forceDefault(bool $force = true): static

Always show the default image, even when a real Gravatar exists. Useful for testing fallback layouts.

$g->forceDefault();

secure(bool $secure = true): static

Use the HTTPS endpoint (secure.gravatar.com). Enabled by default; set to false to use www.gravatar.com over HTTP.

$g->secure(false);

timeout(int $seconds): static

HTTP request timeout for profile fetches and existence checks. Default: 10.

$g->timeout(5);

QR Codes

Gravatar generates a QR code linking to a user's profile page.

qrCodeUrl(int $size = 80): string

echo Gravatar::for('user@example.com')->qrCodeUrl(200);
// https://secure.gravatar.com/avatar/b58996c...?s=200

qrCodeTag(int $size = 80, array $attrs = []): string

echo Gravatar::for('user@example.com')->qrCodeTag(150, ['class' => 'qr-code']);

Public Profile Data

Gravatar profiles are publicly accessible without an API key. Profile data is fetched once and cached on the instance for subsequent calls.

fetchProfile(bool $useCache = true): ?array

Returns the raw profile array, or null if no public profile exists or the request fails. Pass false to bypass the in-memory cache and re-fetch.

$profile = Gravatar::for('user@example.com')->fetchProfile();

if ($profile !== null) {
    print_r($profile);
}

profileField(string $field, mixed $default = null): mixed

Fetch any single top-level field from the profile by name.

$g = new Gravatar('user@example.com');

echo $g->profileField('displayName');
echo $g->profileField('currentLocation', 'Unknown');

Convenience Accessors

$g = new Gravatar('user@example.com');

echo $g->displayName();    // "Jane Smith"
echo $g->aboutMe();        // Bio / description text
echo $g->profilePageUrl(); // "https://gravatar.com/janesmith"

// Linked URLs added to the profile
foreach ($g->profileUrls() as $link) {
    echo $link['title'] . ': ' . $link['value'] . PHP_EOL;
}

// Verified social accounts
foreach ($g->accounts() as $account) {
    echo $account['shortname'] . ': ' . $account['url'] . PHP_EOL;
}

profileUrl(string $format = 'json'): string

Returns the URL for a profile in the requested format without fetching it. Useful for constructing links or feeding to your own HTTP client.

echo $g->profileUrl(Gravatar::FORMAT_JSON);
echo $g->profileUrl(Gravatar::FORMAT_VCF);  // vCard download URL
Constant Format
FORMAT_JSON JSON (default)
FORMAT_XML XML
FORMAT_PHP PHP serialized
FORMAT_VCF vCard

Authenticated API (v3)

The Gravatar API v3 exposes additional profile fields — interests, payment info, verified accounts, and more — that are not available publicly. An API key is required. Get yours at gravatar.com/developers.

Pass the key as the second constructor argument:

$g = new Gravatar('user@example.com', 'your-api-key-here');

fetchAuthenticatedProfile(): ?array

Fetches the full v3 profile as an array. Throws \RuntimeException if no API key is set.

$profile = $g->fetchAuthenticatedProfile();

fetchInterests(): ?array

Returns the interests/hobbies array from the authenticated profile.

$interests = $g->fetchInterests();
foreach ($interests ?? [] as $interest) {
    echo $interest['name'] . PHP_EOL;
}

fetchPayments(): ?array

Returns payment and cryptocurrency wallet information.

$payments = $g->fetchPayments();

Hashing

Gravatar identifies users by a hash of their email address. The class uses SHA-256 (current standard). An MD5 helper is included for compatibility with older systems.

$g = new Gravatar('user@example.com');

echo $g->getHash();                          // SHA-256 (used internally)
echo $g->computeHash('other@example.com');   // SHA-256 of any email
echo $g->computeMd5Hash('old@example.com');  // MD5 — legacy only

Email addresses are normalised (trimmed, lowercased) before hashing, matching Gravatar's own behaviour.


Utilities

setEmail(string $email): static

Change the email on an existing instance. The hash and profile cache are updated automatically.

$g = new Gravatar('first@example.com');
$g->setEmail('second@example.com');

getEmail(): string / getHash(): string

echo $g->getEmail(); // "user@example.com"
echo $g->getHash();  // "b58996c504c5638798eb6b511e6f49af..."

toArray(): array

Returns all current configuration and the computed URL as an associative array.

print_r(Gravatar::for('user@example.com')->size(100)->toArray());
// [
//   'email'        => 'user@example.com',
//   'hash'         => 'b58996c504...',
//   'size'         => 100,
//   'default'      => 'mp',
//   'rating'       => 'g',
//   'forceDefault' => false,
//   'secure'       => true,
//   'url'          => 'https://secure.gravatar.com/avatar/...',
// ]

__toString(): string

Casting the object to a string returns the avatar URL directly.

$g = new Gravatar('user@example.com');
echo "Avatar: $g";
// Avatar: https://secure.gravatar.com/avatar/b58996c...?s=80&d=mp&r=g

Error Handling

Situation Exception
Invalid email address passed to constructor or setEmail() \InvalidArgumentException
size() called with a value outside 1–2048 \InvalidArgumentException
defaultImage() called with an unrecognised value \InvalidArgumentException
rating() called with an unrecognised value \InvalidArgumentException
profileUrl() called with an invalid format \InvalidArgumentException
Any authenticated API method called without an API key \RuntimeException

Network failures (connection timeout, DNS errors, non-2xx responses) return null from fetch methods rather than throwing, so you can handle them with a simple null check.

$profile = $g->fetchProfile();

if ($profile === null) {
    // No profile, private profile, or network error
}

Examples

User profile card

$g = new Gravatar('user@example.com');

echo '<div class="profile-card">';
echo $g->size(96)->imageTag($g->displayName() ?? 'User', ['class' => 'avatar']);
echo '<h2>' . htmlspecialchars($g->displayName() ?? 'Unknown') . '</h2>';
echo '<p>' . htmlspecialchars($g->aboutMe() ?? '') . '</p>';
echo '</div>';

Checking before displaying

$g = (new Gravatar('user@example.com'))->size(64);

$avatarUrl = $g->exists()
    ? $g->url()
    : '/img/default-avatar.png';

echo '<img src="' . $avatarUrl . '" alt="Avatar">';

Reusing one instance for multiple sizes

$g = new Gravatar('user@example.com');

$thumbnail = $g->url(['size' => 32]);
$profile   = $g->url(['size' => 128]);
$hero      = $g->url(['size' => 512]);

Rendering all linked social accounts

$g = new Gravatar('user@example.com');

foreach ($g->accounts() as $account) {
    printf(
        '<a href="%s">%s</a>' . PHP_EOL,
        htmlspecialchars($account['url']),
        htmlspecialchars($account['display'])
    );
}

API Reference Summary

Method Returns Description
__construct(email, apiKey?) Create instance; validates email
for(email, apiKey?) static Static factory for fluent use
setEmail(email) static Change email, invalidates cache
getEmail() string Normalised email address
getHash() string SHA-256 hash of the email
computeHash(email) string SHA-256 hash of any email
computeMd5Hash(email) string MD5 hash (legacy)
size(int) static Set image size (1–2048px)
defaultImage(string) static Set fallback image
rating(string) static Set max content rating
forceDefault(bool) static Always show fallback
secure(bool) static Use HTTPS endpoint
timeout(int) static Set HTTP timeout in seconds
url(overrides?) string Build avatar URL
imageTag(alt?, attrs?) string Build <img> HTML tag
exists() bool Check if real avatar exists
qrCodeUrl(size?) string QR code image URL
qrCodeTag(size?, attrs?) string QR code <img> tag
profileUrl(format?) string Public profile data URL
fetchProfile(cache?) array|null Fetch public profile
profileField(field, default?) mixed Get one profile field
displayName() string|null Display name from profile
aboutMe() string|null Bio from profile
profilePageUrl() string|null Gravatar profile page URL
profileUrls() array Linked URLs from profile
accounts() array Verified social accounts
fetchAuthenticatedProfile() array|null Full v3 profile (API key required)
fetchInterests() array|null Interests from v3 profile
fetchPayments() array|null Payment info from v3 profile
toArray() array All config + URL as array
__toString() string Avatar URL on string cast

License

MIT

<?php
declare(strict_types=1);
/**
* Gravatar API Client
*
* Handles avatar image URLs, profile data fetching, and QR code URLs
* for Gravatar (gravatar.com) using both the public image API
* and the authenticated REST API (Gravatar API v3).
*
* @see https://docs.gravatar.com/
* @see https://docs.gravatar.com/api/avatars/
* @see https://docs.gravatar.com/api/profiles/
*/
class Gravatar {
public const BASE_URL = 'https://www.gravatar.com';
public const API_BASE_URL = 'https://api.gravatar.com/v3';
public const SECURE_BASE_URL = 'https://secure.gravatar.com';
public const CDN_BASE_URL = 'https://0.gravatar.com';
/** Default image fallback options */
public const DEFAULT_404 = '404'; // Return HTTP 404 if no avatar
public const DEFAULT_MP = 'mp'; // Mystery person silhouette
public const DEFAULT_IDENTICON = 'identicon'; // Geometric pattern
public const DEFAULT_MONSTERID = 'monsterid'; // Generated monster
public const DEFAULT_WAVATAR = 'wavatar'; // Generated face
public const DEFAULT_RETRO = 'retro'; // 8-bit retro pixel art
public const DEFAULT_ROBOHASH = 'robohash'; // Generated robot
public const DEFAULT_BLANK = 'blank'; // Transparent PNG
/** Rating levels (content suitability) */
public const RATING_G = 'g'; // Suitable for all audiences
public const RATING_PG = 'pg'; // May contain mildly offensive content
public const RATING_R = 'r'; // May contain harsh content
public const RATING_X = 'x'; // May contain explicit content
/** Supported profile data formats */
public const FORMAT_JSON = 'json';
public const FORMAT_XML = 'xml';
public const FORMAT_PHP = 'php';
public const FORMAT_VCF = 'vcf';
public const FORMAT_QR = 'qr';
private const VALID_RATINGS = [self::RATING_G, self::RATING_PG, self::RATING_R, self::RATING_X];
private const VALID_FORMATS = [self::FORMAT_JSON, self::FORMAT_XML, self::FORMAT_PHP, self::FORMAT_VCF];
private const VALID_DEFAULTS = [
self::DEFAULT_404, self::DEFAULT_MP, self::DEFAULT_IDENTICON,
self::DEFAULT_MONSTERID, self::DEFAULT_WAVATAR, self::DEFAULT_RETRO,
self::DEFAULT_ROBOHASH, self::DEFAULT_BLANK,
];
private string $email;
private string $hash;
private int $size = 80;
private string $default = self::DEFAULT_MP;
private string $rating = self::RATING_G;
private bool $forceDefault = false;
private bool $secure = true;
private ?string $apiKey = null;
private int $timeout = 10;
private ?array $profileCache = null;
/**
* @param string $email Email address to look up
* @param string|null $apiKey Gravatar API key (required for profile API v3)
*
* @throws \InvalidArgumentException If the email address is invalid
*/
public function __construct(string $email, ?string $apiKey = null) {
$this->setEmail($email);
$this->apiKey = $apiKey;
}
/**
* Static factory for a fluent interface without assignment.
*
* @example Gravatar::for('user@example.com')->size(200)->url()
*/
public static function for(string $email, ?string $apiKey = null): static {
return new static($email, $apiKey);
}
/**
* Set or change the email address and recompute the hash.
*
* @throws \InvalidArgumentException
*/
public function setEmail(string $email): static {
$email = trim(strtolower($email));
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new \InvalidArgumentException(
sprintf('"%s" is not a valid email address.', $email)
);
}
$this->email = $email;
$this->hash = $this->computeHash($email);
$this->profileCache = null; // Invalidate cache on email change
return $this;
}
/**
* Compute the SHA-256 hash of a normalised email address.
* Gravatar switched from MD5 to SHA-256 in their newer API.
*/
public function computeHash(string $email): string {
return hash('sha256', trim(strtolower($email)));
}
/**
* Compute an MD5 hash (legacy — kept for older integrations).
*/
public function computeMd5Hash(string $email): string {
return md5(trim(strtolower($email)));
}
/** Return the current SHA-256 hash. */
public function getHash(): string {
return $this->hash;
}
/** Return the normalised email address. */
public function getEmail(): string {
return $this->email;
}
/**
* Set the avatar image size in pixels (1–2048).
*
* @throws \InvalidArgumentException
*/
public function size(int $size): static {
if ($size < 1 || $size > 2048) {
throw new \InvalidArgumentException('Size must be between 1 and 2048 pixels.');
}
$this->size = $size;
return $this;
}
/**
* Set the default image fallback.
*
* Pass one of the DEFAULT_* constants or a fully-qualified URL
* to a custom fallback image.
*
* @throws \InvalidArgumentException
*/
public function defaultImage(string $default): static {
if (!in_array($default, self::VALID_DEFAULTS, true) && !filter_var($default, FILTER_VALIDATE_URL)) {
throw new \InvalidArgumentException(
sprintf('"%s" is not a valid default image. Use a DEFAULT_* constant or a valid URL.', $default)
);
}
$this->default = $default;
return $this;
}
/**
* Set the maximum content rating to display.
*
* @throws \InvalidArgumentException
*/
public function rating(string $rating): static {
if (!in_array($rating, self::VALID_RATINGS, true)) {
throw new \InvalidArgumentException(
sprintf('"%s" is not a valid rating. Use g, pg, r, or x.', $rating)
);
}
$this->rating = $rating;
return $this;
}
/**
* Force the default image to always display, even if a Gravatar exists.
*/
public function forceDefault(bool $force = true): static {
$this->forceDefault = $force;
return $this;
}
/**
* Use the secure (HTTPS) endpoint — enabled by default.
*/
public function secure(bool $secure = true): static {
$this->secure = $secure;
return $this;
}
/**
* Set HTTP request timeout in seconds.
*/
public function timeout(int $seconds): static {
$this->timeout = max(1, $seconds);
return $this;
}
/**
* Build and return the avatar image URL.
*
* @param array $overrides Optional per-call overrides: size, default, rating, forceDefault
* @return string
*/
public function url(array $overrides = []): string {
$size = $overrides['size'] ?? $this->size;
$default = $overrides['default'] ?? $this->default;
$rating = $overrides['rating'] ?? $this->rating;
$forceDefault = $overrides['forceDefault'] ?? $this->forceDefault;
$base = $this->secure ? self::SECURE_BASE_URL : self::BASE_URL;
$params = http_build_query(array_filter([
's' => $size,
'd' => $default,
'r' => $rating,
'f' => $forceDefault ? 'y' : null,
], static fn($v) => $v !== null));
return sprintf('%s/avatar/%s?%s', $base, $this->hash, $params);
}
/**
* Return a ready-to-use <img> HTML tag for the avatar.
*
* @param string $alt Alt text for the image
* @param array $attrs Additional HTML attributes (e.g. ['class' => 'avatar', 'loading' => 'lazy'])
*/
public function imageTag(string $alt = '', array $attrs = []): string {
$attrs = array_merge([
'src' => $this->url(),
'alt' => htmlspecialchars($alt, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'),
'width' => $this->size,
'height' => $this->size,
], $attrs);
$attrString = implode(' ', array_map(
static fn($k, $v) => sprintf('%s="%s"', $k, htmlspecialchars((string) $v, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8')),
array_keys($attrs),
$attrs
));
return "<img {$attrString}>";
}
/**
* Check whether a real Gravatar exists for this email address.
* Uses the 404 default — if the response is 404, no avatar exists.
*/
public function exists(): bool {
$url = $this->url(['default' => self::DEFAULT_404]);
$code = $this->getHttpStatusCode($url);
return $code === 200;
}
/**
* Return the URL of the Gravatar QR code image.
*
* @param int $size QR code size in pixels (default: 80)
*/
public function qrCodeUrl(int $size = 80): string {
return sprintf('%s/%s.qr?s=%d', self::SECURE_BASE_URL, $this->hash, $size);
}
/**
* Return an <img> tag for the QR code.
*/
public function qrCodeTag(int $size = 80, array $attrs = []): string {
$attrs = array_merge([
'src' => $this->qrCodeUrl($size),
'alt' => 'Gravatar QR Code',
'width' => $size,
'height' => $size,
], $attrs);
$attrString = implode(' ', array_map(
static fn($k, $v) => sprintf('%s="%s"', $k, htmlspecialchars((string) $v, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8')),
array_keys($attrs),
$attrs
));
return "<img {$attrString}>";
}
/**
* Return the profile data URL for a given format.
*
* @param string $format One of the FORMAT_* constants
* @throws \InvalidArgumentException
*/
public function profileUrl(string $format = self::FORMAT_JSON): string {
if (!in_array($format, self::VALID_FORMATS, true)) {
throw new \InvalidArgumentException(
sprintf('"%s" is not a valid profile format.', $format)
);
}
return sprintf('%s/%s.%s', self::SECURE_BASE_URL, $this->hash, $format);
}
/**
* Fetch the public profile data as an array (parsed from JSON).
*
* @param bool $useCache Return cached result if already fetched
* @return array|null Null on failure or missing profile
*/
public function fetchProfile(bool $useCache = true): ?array {
if ($useCache && $this->profileCache !== null) {
return $this->profileCache;
}
$url = $this->profileUrl(self::FORMAT_JSON);
$json = $this->httpGet($url);
if ($json === null) {
return null;
}
$data = json_decode($json, true);
if (json_last_error() !== JSON_ERROR_NONE || !isset($data['entry'][0])) {
return null;
}
$this->profileCache = $data['entry'][0];
return $this->profileCache;
}
/**
* Get a single field from the public profile.
*
* @param string $field Top-level profile field name (e.g. 'displayName', 'profileUrl')
* @param mixed $default Value to return if the field is missing
*/
public function profileField(string $field, mixed $default = null): mixed {
$profile = $this->fetchProfile();
return $profile[$field] ?? $default;
}
/**
* Return the display name from the public profile.
*/
public function displayName(): ?string {
return $this->profileField('displayName');
}
/**
* Return the profile URL (gravatar.com/username).
*/
public function profilePageUrl(): ?string {
return $this->profileField('profileUrl');
}
/**
* Return the "about me" / bio text from the public profile.
*/
public function aboutMe(): ?string {
return $this->profileField('aboutMe');
}
/**
* Return the array of URLs listed on the public profile.
*
* @return array<int, array{value: string, title: string}>
*/
public function profileUrls(): array {
return $this->profileField('urls', []);
}
/**
* Return the array of accounts/social links on the public profile.
*/
public function accounts(): array {
return $this->profileField('accounts', []);
}
/**
* Fetch the authenticated profile from Gravatar API v3.
* Requires an API key set in the constructor.
*
* @return array|null
* @throws \RuntimeException If no API key has been set
*/
public function fetchAuthenticatedProfile(): ?array {
$this->requireApiKey();
$url = sprintf('%s/profiles/%s', self::API_BASE_URL, $this->hash);
$json = $this->httpGet($url, ['Authorization: Bearer ' . $this->apiKey]);
if ($json === null) {
return null;
}
$data = json_decode($json, true);
return json_last_error() === JSON_ERROR_NONE ? $data : null;
}
/**
* Fetch interests/hobbies from the authenticated profile.
*
* @throws \RuntimeException
*/
public function fetchInterests(): ?array {
$profile = $this->fetchAuthenticatedProfile();
return $profile['interests'] ?? null;
}
/**
* Fetch payments/crypto info from the authenticated profile.
*
* @throws \RuntimeException
*/
public function fetchPayments(): ?array {
$profile = $this->fetchAuthenticatedProfile();
return $profile['payments'] ?? null;
}
/**
* Return all configurable options as an associative array.
*/
public function toArray(): array {
return [
'email' => $this->email,
'hash' => $this->hash,
'size' => $this->size,
'default' => $this->default,
'rating' => $this->rating,
'forceDefault' => $this->forceDefault,
'secure' => $this->secure,
'url' => $this->url(),
];
}
/**
* Return the avatar URL when the object is cast to string.
*/
public function __toString(): string {
return $this->url();
}
/**
* Perform a GET request and return the response body, or null on failure.
*
* @param string $url
* @param string[] $headers
*/
private function httpGet(string $url, array $headers = []): ?string {
$context = stream_context_create([
'http' => [
'method' => 'GET',
'header' => implode("\r\n", $headers),
'timeout' => $this->timeout,
'ignore_errors' => true,
'follow_location' => 1,
],
'ssl' => [
'verify_peer' => true,
'verify_peer_name' => true,
],
]);
$body = @file_get_contents($url, false, $context);
if ($body === false) {
return null;
}
// Check HTTP status from $http_response_header (populated by file_get_contents)
$status = $this->parseStatusCode($http_response_header ?? []);
if ($status < 200 || $status >= 300) {
return null;
}
return $body;
}
/**
* Retrieve only the HTTP status code for a URL (HEAD request).
*/
private function getHttpStatusCode(string $url): int {
$context = stream_context_create([
'http' => [
'method' => 'HEAD',
'timeout' => $this->timeout,
'ignore_errors' => true,
],
]);
@file_get_contents($url, false, $context);
return $this->parseStatusCode($http_response_header ?? []);
}
/**
* Parse the HTTP status code from the response headers array.
*/
private function parseStatusCode(array $headers): int {
foreach ($headers as $header) {
if (preg_match('/^HTTP\/[\d.]+ (\d{3})/', $header, $matches)) {
return (int) $matches[1];
}
}
return 0;
}
/**
* Throw if no API key has been configured.
*
* @throws \RuntimeException
*/
private function requireApiKey(): void {
if ($this->apiKey === null || $this->apiKey === '') {
throw new \RuntimeException(
'An API key is required for the Gravatar API v3. ' .
'Pass it as the second argument to the constructor.'
);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment