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

Currencies Laravel Package

mibo/currencies

A Laravel/PHP package for working with currencies, offering helpers to define, format, convert, and validate currency codes and amounts in your applications.

View on GitHub
Deep Wiki
Context7

Getting Started

mibo/currencies is a plain PHP library — not a Laravel package. There is no service provider, no config file to publish, and no facade. That means installation is a one-liner and the entire integration cost sits in how you wrap it.

composer require mibo/currencies

Where to look first: open src/ before writing any code. This library is a static data set with a thin accessor layer, so the whole API surface is one or two classes. Confirm three things before you commit to it:

  1. Return type — does it hand back arrays of scalars or a Currency value object? This determines whether you can type-hint it or need a DTO of your own.
  2. Lookup keys — is lookup by ISO code only, or does it also expose symbol/name lookups (which are not unique)?
  3. Minor unit / exponent — does each entry carry the decimal exponent (2 for USD, 0 for JPY, 3 for KWD)? If not, you cannot safely store money with it.

A first use case that pays for itself immediately: replacing a hardcoded <select> of currencies in a registration or checkout form, plus the matching Rule::in() validation.

// tinker
$all = \Mibo\Currencies\Currencies::all();      // verify exact class/method in src/
// Inspect the shape of a single record before you build anything on top of it.

Sanity-check the output for USD, JPY, and KWD — those three expose exponent bugs immediately.

Implementation Patterns

Wrap it. Do not call it from controllers. With zero stars and zero dependents there is no community vetting, so treat it as a vendor detail behind a small service you own:

namespace App\Support;

use Mibo\Currencies\Currencies; // adjust to the real entry point

class CurrencyRepository
{
    public function all(): array
    {
        return cache()->rememberForever('currencies.all', fn () => Currencies::all());
    }

    public function codes(): array
    {
        return array_column($this->all(), 'code');
    }

    public function find(string $code): ?array
    {
        return collect($this->all())->firstWhere('code', strtoupper($code));
    }

    public function exponent(string $code): int
    {
        return $this->find($code)['exponent'] ?? 2;
    }
}

Bind it in a service provider ($this->app->singleton(CurrencyRepository::class)) so tests can swap it and so a future migration to moneyphp/money or symfony/intl is a one-file change.

Validation. Pair the repository with a rule rather than duplicating a code list:

$request->validate([
    'currency' => ['required', 'string', Rule::in(app(CurrencyRepository::class)->codes())],
]);

Blade select. One component, reused everywhere, sorted by name with the code as the value — never the symbol:

@foreach (app(CurrencyRepository::class)->all() as $currency)
    <option value="{{ $currency['code'] }}">{{ $currency['code'] }} — {{ $currency['name'] }}</option>
@endforeach

Storage and casting. Store the ISO code as a char(3) column and store amounts as integer minor units, deriving the multiplier from the exponent. This is the single most valuable thing the library gives you; skip it and you will ship rounding bugs.

$exponent = $repo->exponent($order->currency); // 2
$minor    = (int) round($order->total * (10 ** $exponent));

Seeding a reference table. If you need currencies joinable in SQL (reporting, filters), seed them once and keep the repository as the source of truth:

foreach (app(CurrencyRepository::class)->all() as $currency) {
    DB::table('currencies')->updateOrInsert(
        ['code' => $currency['code']],
        ['name' => $currency['name'], 'exponent' => $currency['exponent'] ?? 2]
    );
}

API resources. Expose code, name, and symbol — but make code the canonical identifier clients persist. Cache the full list at the HTTP layer too; it never changes at runtime.

Gotchas and Tips

  • Maintenance risk is the headline. Zero stars, zero dependents, a single maintainer. Pin the exact version in composer.lock, keep the wrapper thin, and assume you may vendor-fork the data file if the package goes stale. The abstraction above is your insurance policy.
  • ISO-4217 data ages. Currencies are added and withdrawn (HRK → EUR, SLL → SLE). Check the commit date of the data file against the current ISO list before trusting it for anything financial. This is the top reason to prefer symfony/intl or moneyphp/money if you can absorb the weight.
  • Symbol collisions. $ maps to a dozen currencies, ¥ to both JPY and CNY. Never resolve a currency from a symbol — it is a display-only field. Key everything by the uppercase alpha-3 code.
  • Normalize input. Users type usd, Usd, and USD. Uppercase at the boundary, then look up. If the library's lookup is case-sensitive you will get silent nulls.
  • Exponents are not uniform. JPY/KRW are 0; KWD/BHD/JOD are 3. Hardcoding * 100 anywhere is a defect. Also guard against the library omitting the field entirely — default to 2 only as a last resort, not as a silent habit.
  • Caching and Octane. cache()->rememberForever() on static data is correct, but add a php artisan cache:clear note to your deploy docs, and remember that a long-lived Octane worker holds container singletons across requests — make the repository stateless.
  • Testing. Mock your CurrencyRepository, never the vendor class. In feature tests, assert against real codes (assertSee('USD')) rather than asserting the library's internal array shape, which you do not control.
  • Extension points are thin. If the entry class is final or fully static, you cannot subclass it. Your extension point is composition, not inheritance — build your own facade and leave the vendor class untouched.
  • Check composer.json constraints against your PHP version before installing — small libraries often lag on newer PHP minor versions, and a ^8.1 cap will block a 8.3 project if the maintainer hasn't bumped it.
  • It is not a rates provider. No conversion, no FX. If a stakeholder asks for "currency support" and means rates, this package answers a different question — pair it with an actual rates API.
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.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle