ImagePlaceholder
in package
Detects MyAnimeList placeholder images.
MyAnimeList serves a set of generic, non-artwork images for entities that
have no picture of their own (characters without art, voice actors, people,
companies, users with the default avatar, and anime/manga whose cover was
never uploaded or was removed). These placeholders carry no information, so
parsers must not surface them: the correct value is null, meaning "this
entity has no image".
The fragments below were measured against live cdn.myanimelist.net pages and the jikan recording fixtures (jikan-me/jikan#488):
/images/questionmark_23.gif characters & voice actors / people /images/questionmark_50.gif user search, friend lists /images/kaomoji_mal_white.png user search default avatar (no custom picture) /images/qm_50.gif anime search results (missing art) /images/company/placeholder.png company / producer search /images/na.gif club search /images/na_series_*.png|json anime / manga missing art /img/sp/icon/apple-touch-icon-256.png anime / manga detail pages with no cover: og:image falls back to the MAL site icon (measured 2026-10-12 on anime/43535, manga/90440)
Matching is done against URL fragments on purpose: MyAnimeList rewrites
these assets with a /r/WxH/ size prefix and a ?s= cache-busting query
(e.g. https://cdn.myanimelist.net/r/42x62/images/questionmark_23.gif?s=…),
and can host them on either cdn.myanimelist.net or akamai-origin
.myanimelist.net. A path-based substring match therefore stays
false-positive-free while covering every host/query variant.
Table of Contents
Constants
- PLACEHOLDER_FRAGMENTS : mixed = ['/images/questionmark_23.gif', '/images/questi...
Methods
- isPlaceholder() : bool
- Whether the given URL is a MyAnimeList "no image" placeholder.
- normalize() : string|null
- Returns null when the URL is a placeholder, the URL unchanged otherwise.
Constants
PLACEHOLDER_FRAGMENTS
private
mixed
PLACEHOLDER_FRAGMENTS
= ['/images/questionmark_23.gif', '/images/questionmark_50.gif', '/images/kaomoji_mal_white.png', '/images/qm_50.gif', '/images/company/placeholder.png', '/images/na.gif', '/images/na_series_', '/img/sp/icon/apple-touch-icon-256.png']
Methods
isPlaceholder()
Whether the given URL is a MyAnimeList "no image" placeholder.
public
static isPlaceholder(string|null $url) : bool
Parameters
- $url : string|null
Return values
boolnormalize()
Returns null when the URL is a placeholder, the URL unchanged otherwise.
public
static normalize(string|null $url) : string|null
Central helper for every spot that turns an image URL into an entity's image value: image resource factories, raw-string parser getters and the raw-string model properties all funnel through here so the placeholder set lives in exactly one place.
Parameters
- $url : string|null