calliostro/lastfm-client
Lightweight Last.fm API client for PHP 8.1+ with clean, modern methods for artists, albums, tracks, search, and charts. Uses Guzzle and supports API-key access for all calls plus session authentication for write actions like scrobbling and loving tracks.
composer require calliostro/lastfm-client
use Calliostro\LastFm\LastFmClientFactory;
$lastfm = LastFmClientFactory::createWithApiKey('your-api-key', 'your-secret');
$artist = $lastfm->getArtistInfo('Billie Eilish');
dd($artist); // Returns structured artist data
$tracks = $lastfm->searchTracks(track: 'Anti-Hero', artist: 'Taylor Swift', limit: 5);
dd($tracks);
$lastfm = LastFmClientFactory::createWithApiKey('key', 'secret');
$artist = $lastfm->getArtistInfo('Artist Name');
$tracks = $lastfm->getArtistTopTracks('Artist Name', limit: 10);
if (isset($artist['artist'])) {
echo $artist['artist']['name'];
}
$lastfm = LastFmClientFactory::createWithSession('key', 'secret', 'session-key');
$lastfm = LastFmClientFactory::createWithMobileAuth('key', 'secret', 'username', 'password');
$lastfm->scrobbleTrack(
artist: 'Artist',
track: 'Track',
timestamp: time()
);
// app/Providers/AppServiceProvider.php
public function register()
{
$this->app->singleton(LastFmClient::class, function ($app) {
return LastFmClientFactory::createWithApiKey(
config('services.lastfm.key'),
config('services.lastfm.secret')
);
});
}
config/services.php):
'lastfm' => [
'key' => env('LASTFM_API_KEY'),
'secret' => env('LASTFM_API_SECRET'),
],
public function __construct(private LastFmClient $lastfm) {}
// Fetch top artists for multiple countries
$countries = ['US', 'UK', 'DE'];
$charts = collect($countries)->map(fn($country) =>
$lastfm->getTopArtistsByCountry($country)
);
try {
$artist = $lastfm->getArtistInfo('Nonexistent Artist');
} catch (LastFmException $e) {
if ($e->getCode() === 1) { // Invalid artist
// Handle gracefully
}
}
Missing Authentication:
Error Code 6 → Missing required parametercreateWithSession() for user-specific operations.try-catch with LastFmException for clear error messages.Rate Limiting:
$handler = HandlerStack::create();
$handler->push(Middleware::retry(
fn ($retries) => $retries < 3,
fn ($retries) => 1000 * 2 ** $retries
));
$lastfm = LastFmClientFactory::createWithApiKey('key', 'secret', ['handler' => $handler]);
Parameter Validation:
null for optional parameters:
$lastfm->searchTracks(track: 'Track', artist: null); // Forces artist to be omitted
$lastfm = LastFmClientFactory::createWithApiKey('key', 'secret', [
'debug' => fopen('php://output', 'w'),
]);
X-Lastfm-Error for API errors.$response = $lastfm->getClient()->send(new Request('GET', '...'));
if ($response->hasHeader('X-Lastfm-Error')) {
$errorCode = $response->getHeader('X-Lastfm-Error')[0];
}
use Illuminate\Support\Facades\Cache;
$artist = Cache::remember("lastfm_artist_{$artistName}", now()->addHours(1), function() use ($lastfm, $artistName) {
return $lastfm->getArtistInfo($artistName);
});
getTopArtistsChart() with period=7day).Custom Middleware:
$stack = HandlerStack::create();
$stack->push(Middleware::tap(function ($request) {
// Modify request (e.g., add headers)
$request = $request->withHeader('X-Custom-Header', 'value');
return $request;
}));
$lastfm = LastFmClientFactory::createWithApiKey('key', 'secret', ['handler' => $stack]);
Override API Endpoint:
$lastfm = LastFmClientFactory::createWithApiKey('key', 'secret', [
'base_uri' => 'https://custom-api.lastfm.com',
]);
Mocking for Tests:
$mockHandler = HandlerStack::create();
$mockHandler->push(Middleware::mock(function ($request) {
return new Response(200, [], json_encode(['artist' => ['name' => 'Mock Artist']]));
}));
$lastfm = LastFmClientFactory::createWithApiKey('key', 'secret', ['handler' => $mockHandler]);
User-Agent Override:
LastFmClient/2.0.0 +https://github.com/calliostro/lastfm-client$lastfm = LastFmClientFactory::createWithApiKey('key', 'secret', [
'headers' => ['User-Agent' => 'MyApp/1.0 (+https://myapp.com)'],
]);
Timeout Handling:
5.0 seconds.$lastfm = LastFmClientFactory::createWithApiKey('key', 'secret', ['timeout' => 10.0]);
Session Expiry:
$sessionKey = session('lastfm_session_key');
if (!$sessionKey) {
// Redirect to auth flow
}
Mobile Auth Edge Cases:
Store Credentials Securely:
// .env
LASTFM_API_KEY=your_key
LASTFM_API_SECRET=your_secret
// config/services.php
'lastfm' => [
'key' => env('LASTFM_API_KEY'),
'secret' => env('LASTFM_API_SECRET'),
],
Queue Scrobbling:
// app/Jobs/ScrobbleTrack.php
public function handle()
{
$lastfm = app(LastFmClient::class);
$lastfm->scrobbleTrack($this->trackData);
}
Middleware for Auth:
// app/Http/Middleware/EnsureLastFmSession.php
public function handle($request, Closure $next)
{
if
How can I help you explore Laravel packages today?