Download the PHP package alwayscurious/laravel-vin without Composer

On this page you can find all versions of the php package alwayscurious/laravel-vin. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package laravel-vin

Laravel VIN

Latest Version on Packagist Tests

Decode a US vehicle VIN into year, make, model, series, trim, body class and more via the NHTSA vPIC API. Decodes are cached (a VIN's decode is immutable), with a version knob to invalidate every cached decode at once and a master switch to disable live lookups entirely.

NHTSA is the default provider, but the decoder is a driver — register your own with Vin::extend() and select it with VIN_DRIVER, exactly like Laravel's cache, mail and filesystem drivers.

Requirements

Installation

The service provider is auto-discovered — no manual registration needed.

Publishing the config file is optional; the package ships with sane defaults and reads everything from environment variables:

Configuration

Every setting is driven by an environment variable, so you rarely need to touch the published config file:

Env var Config key Default Purpose
VIN_DRIVER vin.driver nhtsa Which decoder driver lookups use.
VIN_BASE_URL vin.decoders.nhtsa.base_url https://vpic.nhtsa.dot.gov/api NHTSA vPIC API base URL.
VIN_TIMEOUT vin.decoders.nhtsa.timeout 10 HTTP timeout (seconds) per decode request.
VIN_ATTRIBUTES vin.decoders.nhtsa.attributes identity How much to hydrate: identity, typed, or full (see below).
VIN_RETRY_TIMES vin.decoders.nhtsa.retry.times 2 Max NHTSA request attempts (1 disables retrying).
VIN_RETRY_SLEEP vin.decoders.nhtsa.retry.sleep 200 Milliseconds between NHTSA retry attempts.
VIN_CACHE_STORE vin.cache.store (app default) Cache store for decodes (blank = the app's default store).
VIN_CACHE_TTL vin.cache.ttl 86400 How long (seconds) a decoded VIN stays cached.
VIN_CACHE_VERSION vin.cache.version 1 Bump to invalidate every cached decode at once.
VIN_ENABLED vin.enabled true Master switch for live decoding.

Usage

Use the Vin facade (auto-registered — no alias config needed):

Prefer dependency injection? Type-hint or resolve VinLookupService — it is the default driver's lookup service and exposes the same lookup() / tryLookup() / isValid() methods:

tryLookup()

Returns null instead of throwing on any failure:

isValid()

Structurally validate a VIN (17 characters, excluding I, O and Q) without hitting the network:

Validating form input — the Vin rule and check digit

Validate a VIN field with the Rules\Vin rule object. By default it checks structure only (the same as isValid()); call withCheckDigit() to also verify the ISO 3779 9th-position check digit and catch a transposed/mistyped VIN before spending a decode call:

isValid() stays structural-only on purpose — some real, decodable VINs don't honor the check digit. When you want the stricter gate without the network, use Vin::hasValidCheckDigit('…').

inspect() — validate with useful feedback

When a bare true/false isn't enough — you want to tell the user why their VIN was rejected — Vin::inspect() runs every offline check and returns a VinValidation reporting the overall verdict, the structural and check-digit dimensions separately, and a typed reason per failure. No network call:

$result->valid is the strong (structure + check digit) verdict; $result->structurallyValid mirrors the lenient isValid() the decode path uses. toArray() / JSON-encoding gives a flat, API-friendly shape (vin, valid, structurally_valid, check_digit_valid, errors).

lookupMany() — decode a batch in one request

Importing a fleet? lookupMany() decodes many VINs in a single provider round-trip (NHTSA's DecodeVinValuesBatch), reusing the per-VIN cache and only decoding the misses. It returns VehicleData keyed by normalized VIN, in input order:

The enabled gate and caching apply to the whole batch; a structurally invalid VIN throws before any request (pre-filter with isValid() if your input may be dirty). A custom driver that doesn't implement batching still works — lookupMany() transparently falls back to looping lookup().

Knowing why a lookup failed

VinLookupException carries a typed ->reason (VinFailureReason), so a single catch can render the right message instead of pairing isValid() with tryLookup():

Decode events

The package dispatches Events\VinDecoded on every successful lookup (with a fromCache flag) and Events\VinDecodeFailed on every failure (with the VinFailureReason and the exception) — the latter fires even when tryLookup() swallows the error. Wire them to your own telemetry:

The VehicleData value object

lookup() / tryLookup() return an immutable VehicleData. By default (VIN_ATTRIBUTES=identity) it carries the clean core set that covers ~80% of use cases:

Want engine/safety/body/plant specs, series, or the raw NHTSA fields too? Raise the level with VIN_ATTRIBUTES (see Trim the response) — everything below this line needs typed or full.

decodedSuccessfully() is stricter than isFullyIdentified(): NHTSA can return a full year/make/model while still flagging a non-blocking warning (e.g. a model year mismatch), in which case isFullyIdentified() is true but decodedSuccessfully() is false.

Filling a model — only() / toColumns()

To persist a decode, project the identity fields into a Model::fill()-ready array. only() keeps the property names; toColumns() re-keys them onto your column names:

Both throw on an unknown field (so a typo surfaces), and both project only the flat identity fields — your app keeps ownership of which columns win when merging into an existing row.

Extended attributes — engine, safety, body, plant

DecodeVinValues returns far more than identity. Beyond the fields above, four typed, always-present groups carry the commonly-used specs. Each field is null when NHTSA has no value for it — a missing numeric field (doors, horsepower, …) is null, never 0:

Each group is itself Arrayable + JsonSerializable. toArray() / json_encode() on the VehicleData nest them under engine, safety, body and plant.

Raw attribute passthrough

For anything NHTSA returns that the typed groups don't surface (e.g. DestinationMarket, NCSABodyType, Note), the complete non-empty response row is kept verbatim, keyed by the original NHTSA field name:

Raw values are strings exactly as NHTSA sent them (trimmed); use the typed groups above when you want real int / float types. The raw bag is not embedded in toArray() / json_encode() — it's reachable only via ->attributes and attribute(), so your serialized payloads stay curated and stable.

Only need year/make/model? Trim the response

The default is deliberately lean. Building the typed groups — and especially keeping the full raw passthrough — costs a little CPU per decode and, more importantly, makes each cached row larger. Step up with VIN_ATTRIBUTES (vin.decoders.nhtsa.attributes) only when you need more:

VIN_ATTRIBUTES Core identity series Typed groups Raw attributes Use when…
identity (default) ✓ You read year/make/model/trim/body class/vehicle type/manufacturer. Smallest cache, least work.
typed ✓ ✓ ✓ You also want series and engine/safety/body/plant typed, but never the long tail.
full ✓ ✓ ✓ ✓ You want everything, including fields not lifted into a typed group.

Core identity = year, make, model, trim, body class, vehicle type, manufacturer (plus VIN and decode status, which are always present). At any level the groups are still present (never null) — lighter levels just leave their fields null and keep ->attributes empty, so $vehicle->engine->horsepower is always safe to read.

Because the level changes what's stored, bump VIN_CACHE_VERSION when you change it so already cached VINs are re-decoded at the new level (see below).

Invalidating cached decodes

A VIN's decode never changes, so results are cached for VIN_CACHE_TTL seconds. If NHTSA corrects its data — or you change what the package stores — bump VIN_CACHE_VERSION. The version is part of the cache key, so every previously cached decode is bypassed at once without flushing your whole cache store.

Disabling live decoding

Set VIN_ENABLED=false to turn off all network calls. lookup() then throws a VinLookupException and tryLookup() returns null — neither hits the API.

Using a different VIN provider

NHTSA is just the default driver. The package uses Laravel's Manager driver system, so you register your own provider and select it by name — the same ergonomics as Cache::extend() / Mail::extend().

A driver is any class implementing Contracts\VinDecoder. It only performs the lookup and maps the response; the VIN it receives is already normalized (uppercased, trimmed) and structurally validated, and validation, the enabled gate and caching are applied around it by the package — so a driver never reimplements them.

Register it as a named driver in a service provider's register() (or boot()). The closure receives the container, so you can pull in config or other services:

Then make it the default for the whole app:

…or use it for a single call while NHTSA stays the default:

Because the package wraps every driver, your provider automatically inherits structural validation, the VIN_ENABLED master switch, and caching. Cache entries are namespaced per driver, so two providers never serve each other's cached decode. Prefer to decode from a fixed dataset, a queue, or an in-memory table? Same seam — your decode() doesn't have to make an HTTP call at all.

Driver config is captured when the driver is first resolved. If you change a driver's own settings (e.g. vin.decoders.*) at runtime, call Vin::forgetDrivers() to rebuild. The enabled gate and cache version are re-read on every lookup, so those take effect immediately.

Testing

Vin::fake() — the easy way

Swap the decoder for a fake so your tests never touch the network or the NHTSA wire format. Map a VIN to a VehicleData (build one with VehicleData::fake()); unmapped VINs return a generated fake. The fake still runs the real validation, enabled gate and caching, and records lookups for assertion:

Map a VIN to a Throwable to exercise a failure path (Vin::fake(['…' => VinLookupException::requestFailed('…', 503)])).

Faking the HTTP layer directly

Prefer to assert on the wire? The package uses Laravel's HTTP client, so you can fake NHTSA instead:

Run the package's own suite with:

Versioning

This package follows Semantic Versioning. As of 1.0.0 the public API — the Vin facade, the Contracts\VinDecoder driver seam, VehicleData, VinLookupException, and the vin.* config keys / env vars — is stable and covered by SemVer. See the CHANGELOG for what each release adds.

License

The MIT License (MIT). See LICENSE.


All versions of laravel-vin with dependencies

PHP Build Version
Package Version
Requires php Version ^8.3
illuminate/cache Version ^11.0|^12.0|^13.0
illuminate/contracts Version ^11.0|^12.0|^13.0
illuminate/http Version ^11.0|^12.0|^13.0
illuminate/support Version ^11.0|^12.0|^13.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package alwayscurious/laravel-vin contains the following files

Loading the files please wait ...