Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Steamid Laravel Package

xpaw/steamid

Lightweight PHP library for converting Steam IDs between SteamID64, SteamID32, and legacy SteamID formats, with support for individual, group, and lobby accounts. Simple, dependency-free API for parsing and formatting Steam identifiers in Laravel or any PHP project.

View on GitHub
Deep Wiki
Context7

Getting Started

Install with Composer — the package is xpaw/steamid (the repo filename is SteamID.php, but the class lives in xPaw\SteamID):

composer require xpaw/steamid

There is no service provider, config file, or facade. This is a framework-agnostic, dependency-free value object. Composer autoloading is all the wiring you get — you call new SteamID(...) directly, or wrap it yourself.

Confirm it works in Tinker:

use xPaw\SteamID;

$id = new SteamID('76561197960287930');
$id->RenderSteam64();  // "76561197960287930"
$id->RenderSteam2();   // "STEAM_0:0:22202"
$id->RenderSteam3();   // "[U:1:44404]"
$id->RenderLink();     // "https://steamcommunity.com/profiles/76561197960287930"
$id->IsValid();        // true

Where to look first: the README shows the accepted input formats (SteamID64, STEAM_X:Y:Z, [U:1:Z]). Then skim the class for the account-type/universe/instance constants and the IsValid* / Get* methods — those are what you'll branch on.

First use case: you accept a Steam ID from a user in some form (a profile URL, a legacy STEAM_0, or a 64-bit number), normalize it once at the boundary, and store the canonical SteamID64 string in your database. Every other format is a rendering concern.

Implementation Patterns

1. Normalize on input, store SteamID64. Use a FormRequest rule so controllers never see malformed IDs:

namespace App\Rules;

use Closure;
use Illuminate\Contracts\Validation\ValidationRule;
use xPaw\SteamID;

class SteamIdRule implements ValidationRule
{
    public function __construct(private bool $requireIndividual = true) {}

    public function validate(string $attribute, mixed $value, Closure $fail): void
    {
        $id = new SteamID(is_string($value) ? trim($value) : '');

        if (!$id->IsValid()) {
            $fail("The {$attribute} field is not a valid Steam ID.");
            return;
        }

        if ($this->requireIndividual && !$id->IsValidIndividual()) {
            $fail("The {$attribute} must belong to an individual Steam account.");
        }
    }
}

2. Eloquent cast returning the object. Keeps the model pleasant to work with and guarantees anything written back is a valid SteamID64 string:

namespace App\Casts;

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use Illuminate\Database\Eloquent\Model;
use xPaw\SteamID;

class SteamIdCast implements CastsAttributes
{
    public function get(Model $model, string $key, mixed $value, array $attributes): ?SteamID
    {
        return $value === null ? null : new SteamID((string) $value);
    }

    public function set(Model $model, string $key, mixed $value, array $attributes): ?string
    {
        if ($value === null) {
            return null;
        }

        $id = $value instanceof SteamID ? $value : new SteamID(trim((string) $value));

        if (!$id->IsValid()) {
            throw new \InvalidArgumentException("Invalid Steam ID for [{$key}].");
        }

        return $id->RenderSteam64();
    }
}
// app/Models/User.php
protected function casts(): array
{
    return [
        'steam_id' => \App\Casts\SteamIdCast::class,
    ];
}

3. Wrap “resolution” (vanity URLs, full profile URLs) in one service. This is where Steam Web API rate limits and URL parsing belong:

namespace App\Support;

use xPaw\SteamID;

class SteamIdResolver
{
    public function parse(string $input): ?SteamID
    {
        $input = trim($input);

        if (preg_match('~steamcommunity\.com/profiles/(\d+)~i', $input, $m)) {
            $input = $m[1];
        }

        $id = new SteamID($input);

        return $id->IsValid() ? $id : null;
    }

    public function fromVanity(string $vanity): ?SteamID
    {
        $vanity = strtolower(trim($vanity, "/ \t\n\r\0\x0B"));

        $steam64 = cache()->remember(
            "steam:vanity:{$vanity}",
            now()->addDay(),
            fn () => SteamID::ResolveVanityURL($vanity, config('services.steam.key'))
        );

        if (!$steam64) {
            return null;
        }

        $id = new SteamID($steam64);

        return $id->IsValid() ? $id : null;
    }
}

Bind it as a singleton if you want app(SteamIdResolver::class) access, but the class itself is stateless.

4. Serialization belongs in API Resources, and must emit strings. Never rely on the model's raw attribute:

public function toArray($request): array
{
    return [
        'steam_id'    => $this->steam_id?->RenderSteam64(),  // string
        'steam_id_2'  => $this->steam_id?->RenderSteam2(),
        'steam_id_3'  => $this->steam_id?->RenderSteam3(),
        'profile_url' => $this->steam_id?->RenderLink(),
    ];
}

5. Migration shape. SteamID64 fits in UNSIGNED BIGINT, but char(17) is usually safer to reason about (no numeric casts anywhere, no 32-bit surprises, straightforward unique index):

$table->char('steam_id', 17)->nullable()->unique();

6. Queue jobs and DTOs. Pass the SteamID64 string across job boundaries and rehydrate:

SyncSteamProfile::dispatch($user->steam_id->RenderSteam64());

// inside the job
$id = new SteamID($this->steamId64);

7. Steam login handoff. If you use Socialite with a Steam/OpenID driver, the callback gives you a SteamID64. Push it through SteamIdResolver::parse() before persisting so STEAM_0/[U:1:] variants can't sneak into the column.

8. Display helpers on the model. Add accessors for the legacy formats once, so Blade doesn't call the class inline:

protected function steam2(): Attribute
{
    return Attribute::get(fn () => $this->steam_id?->RenderSteam2());
}

Gotchas and Tips

  • SteamID64 is not a JS-safe number. It exceeds Number.MAX_SAFE_INTEGER. Always serialize as a string; never let Eloquent return it as an integer in JSON.
  • new SteamID($anything) does not throw on garbage. Invalid input produces an invalid object, so always check IsValid() before trusting it. Wrap parsing in your own method that returns null or throws a domain exception.
  • IsValid() ≠ “is a user.” A clan ID or game-server ID is structurally valid. Use IsValidIndividual() whenever you expect a human account, especially for auth and profile linking.
  • Vanity URLs need the Steam Web API key and are rate-limited. The ResolveVanityURL helper (present in recent versions — verify against your installed tag) hits the network. Cache results; a day is reasonable. Handle null/failure without breaking the request.
  • Full profile URLs aren't guaranteed to parse. The library handles the ID formats, not arbitrary URLs. Trim whitespace, extract the numeric path from /profiles/…, and route /id/… through vanity resolution yourself.
  • RenderSteam2() is lossy by design. It encodes universe/instance, and for non-individual accounts (clans, game servers, anonymous servers) the legacy form is not meaningful. SteamID64 is your canonical identifier; everything else is display.
  • Account ID is 32-bit but incomplete. GetAccountID() is great for compact storage/comparisons, but it drops universe and instance. Don't make it your primary key unless you deliberately only ever store public individual accounts.
  • 32-bit PHP. On 32-bit builds, integer-casting SteamID64 overflows. Keep it as a string end-to-end (char(17) column, (string) casts, string in queues).
  • No facade, no provider, no config. Package discovery registers nothing. If you want Steam::parse(...), write the facade/wrapper yourself — don't expect one.
  • Testing. Use a real, known SteamID64 in tests (e.g. 76561197960287930) and assert every rendered format. Add a test for '', 'not-an-id', a clan ID, and a numeric-string ID to catch the “valid but wrong type” case.
  • RenderSteam64() returns a string in current versions — lean on that and skip (string) noise in your API layer, but don't assume GetAccountID() is also a string.
  • Steam Web API credentials. Put the key in config/services.php under steam.key, sourced from .env; the library will happily use null and fail silently-ish if you forget.
  • Composer name ≠ repo name. composer require xpaw/steamid (lowercase), while the GitHub repo and class file are SteamID.php. Autoloading resolves it to xPaw\SteamID, so keep that use statement exact.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings