devhammed/laravel-brick-money 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

devhammed/laravel-brick-money

Composer 安装命令:

composer require devhammed/laravel-brick-money

包简介

Laravel Brick Money Integration

README 文档

README

Latest Version on Packagist GitHub Tests Action Status Total Downloads Laravel Compatibility

Table of Contents

Introduction

This package provides the Laravel integration of Brick/Money.

Installation

Install via Composer:

composer require devhammed/laravel-brick-money

Configuration

Publish the configuration file if you need to customize defaults:

php artisan vendor:publish --tag="brick-money-config"

You can view the contents of the default configuration in config/brick-money.php

Usage

use Devhammed\LaravelBrickMoney\Money;
use Devhammed\LaravelBrickMoney\Currency;

echo Money::of(100); // '$100.00'

echo Money::of(100, Currency::of('EUR')); // '€100,00'

echo Money::of(100, 'USD'); // '$100.00'

echo Money::ofMinor(100); // '$1.00'

echo Money::ofMinor(100, 'EUR'); // '€1,00'

Available Methods

The package has tried to wrap as many brick/money package methods as possible but if you encounter a method that we haven't wrapped yet, you can get the underlying instance by calling ->getMoney() on Money or ->getCurrency() on Currency and call it directly:

use Devhammed\LaravelBrickMoney\Money;
use Devhammed\LaravelBrickMoney\Currency;

// Creation
$usd = Currency::of('USD');
$eur = Currency::of('EUR');
$total = Money::of(1000, $usd);
$tax = Money::of(100, $usd);

// Money static methods
Money::of(100, $usd); // Get the Money instance of a numeric amount and currency.
Money::ofMinor(100, $usd); // Get the Money instance of a numeric amount in minor units and currency.
Money::ofMoney(\Brick\Money\Money::of(100, 'USD')); // Get the Money instance of a Brick\Money\Money instance.
Money::zero($usd); // Get the Money instance of zero amount and currency.
Money::min(Money::of(100, $usd), Money::of(200, $usd)); // Get the minimum of two or more Money instances.
Money::max(Money::of(100, $usd), Money::of(200, $usd)); // Get the maximum of two or more Money instances.
Money::total(Money::of(100, $usd), Money::of(200, $usd)); // Get the total of two or more Money instances.
Money::avg(Money::of(100, $usd), Money::of(200, $usd)); // Get the average of two or more Money instances.
Money::locale('en_US'); // Get or set the default locale for formatting.
Money::jsonSerializeMinorUnits(true); // Get or set whether to return minor units in JSON serialization.
Money::jsonSerializer(fn(Money $money) => [
    'amount' => (string) (Money::jsonSerializeMinorUnits() ?
    $money->getMinorAmount() : $money->getAmount(),
    'currency' => (string) $money->getCurrency(),
 ); // Get or set the JSON serializer for Money instances.

// Money instance methods
$total->getCurrency(); // Devhammed\LaravelBrickMoney\Currency{}
$total->getMoney(); // Brick\Money\Money{}
$total->getContext(); // Brick\Money\Context\DefaultContext{}
$total->getAmount(); // Brick\Math\BigDecimal{}
$total->getMinorAmount(); // Brick\Math\BigDecimal{}
$total->getUnscaledAmount(); // Brick\Math\BigInteger{}
$total->getSign(); // 1
$total->isZero(); // false
$total->isNegative(); // false
$total->isNegativeOrZero(); // false
$total->isPositive(); // true
$total->isPositiveOrZero(); // true
$total->compareTo($tax); // 1
$total->isEqualTo($tax); // false
$total->isLessThan($tax); // false
$total->isLessThanOrEqualTo($tax); // false
$total->isGreaterThan($tax); // true
$total->isGreaterThanOrEqualTo($tax); // true
$total->plus($tax); // $1,100
$total->minus($tax); // $900
$total->multipliedBy(2); // $2,000
$total->dividedBy(2); // $500
$total->allocate(1, 2, 3);
$total->split(2); // [$500, $500]
$total->splitWithRemainder(3); // [$33.33, $33.33, $33.33, $0.01]
$total->abs(); // $1,000
$total->convertedTo($eur, 0.91); // $910
$total->convertedTo('NGN', 1457); // N1,457,000
$total->negated(); // -$1,000
$total->format(); // "$1,000"

# Currency static methods
Currency::of('USD'); // Get the Currency instance of a currency code.
Currency::of(\Brick\Money\Currency::of('USD')); // Get the Currency instance of a Brick\Money\Currency instance.
Currency::ofCountry('NG'); // Get the Currency instance for a country code.
Currency::currencies(); // Get an array of all configured currencies.
Currency::jsonSerializer(fn(Currency $currency) => [
    'name' => $currency->getName(),
    'code' => $currency->getCode(),
]); // Get or set the JSON serializer for Currency instances.

# Currency instance methods
$usd->getCode(); // "USD"
$usd->getName(); // "US Dollar"
$usd->getNumericCode(); // 840
$usd->getSymbol(); // $
$usd->isSymbolFirst(); // true
$usd->isSymbolSpaced(); // false
$usd->getDecimalPlaces(); // 2
$usd->getDecimalSeparator(); // "."
$usd->getThousandPlaces(); // 3
$usd->getThousandSeparator(); // ","
$usd->getCurrency(); // Brick\Money\Currency{}
$usd->is($eur); // false

Eloquent

This package provides Model casts to help with money and currency storage in the database.

There are currently two supported storage cast types, and each of them support either storing in a single JSON column or separate amount and currency columns:

AsIntegerMoney (Recommended)

This stores the amount in the currency's minor unit.

Example Model:

use Devhammed\LaravelBrickMoney\Money;
use Devhammed\LaravelBrickMoney\Casts\AsIntegerMoney;

/**
 * @property Money $amount
 * @property string $currency
 * @property Money $tax
 */
class Transaction extends Model
{
    protected function casts(): array
    {
        return [
            'amount' => AsIntegerMoney::of('currency'),
            'tax' => AsIntegerMoney::class,
        ];
    }
}

Example Migration:

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;

Schema::create('transactions', function (Blueprint $table) {
    $table->id();

    $table->bigInteger('amount');   // e.g., 1000 = $10.00,
    $table->string('currency');  // currency code e.g. USD
    $table->json('tax'); // {"amount": "2345", "currency": "TRX"}

    $table->timestamps();
});

Some cryptocurrencies, particularly those with very high precision (e.g., ETH uses 18 decimal places) will exceed the limit of ->bigInteger() so it is recommended to use ->string() in this case when you are using the separate columns mode.

AsDecimalMoney

This stores the amount in the currency's major unit.

Example Model:

use Devhammed\LaravelBrickMoney\Money;
use Devhammed\LaravelBrickMoney\Casts\AsDecimalMoney;

/**
 * @property Money $amount
 * @property string $currency
 * @property Money $tax
 */
class Transaction extends Model
{
    protected function casts(): array
    {
        return [
            'amount' => AsDecimalMoney::of('currency'),
            'tax' => AsDecimalMoney::class,
        ];
    }
}

Example Migration:

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;

Schema::create('transactions', function (Blueprint $table) {
    $table->id();

    $table->decimal('amount', 36, 18);  // e.g., 10.00 = $10.00,
    $table->string('currency');  // currency code e.g. USD
    $table->json('tax'); // {"amount": "23.45", "currency": "TRX"}

    $table->timestamps();
});

The reason for using DECIMAL(36, 18) in the separate column example is to accommodate cryptocurrencies with very high precision like ETH that uses 18 decimal places, you can reduce or increase the scale and precision to match your project requirements.

AsCurrency

This is useful for casting currency columns to Currency.

Example Model:

use Devhammed\LaravelBrickMoney\Currency;
use Devhammed\LaravelBrickMoney\Casts\AsCurrency;

/**
 * @property Currency $currency
 */
class Transaction extends Model
{
    protected function casts(): array
    {
        return [
            'currency' => AsCurrency::class,
        ];
    }
}

Example Migration:

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;

Schema::create('transactions', function (Blueprint $table) {
    $table->id();
    $table->string('currency');  // currency code e.g. USD
    $table->timestamps();
});

This can also be used in conjunction with the currency column of the amount casts explained above.

HTTP

This package provides request macros and validation rules to work with money/currency in HTTP Requests.

Request Macros

request()->currency('currency'); // Devhammed\LaravelBrickMoney\Currency{}

request()->money('price'); // Devhammed\LaravelBrickMoney\Money{}

request()->money('price', currency: 'EUR', minor: true); // Devhammed\LaravelBrickMoney\Money{}

Validation Rules

namespace App\Http\Requests;

use Devhammed\LaravelBrickMoney\Rules\MoneyRule;
use Devhammed\LaravelBrickMoney\Rules\CurrencyRule;
use Illuminate\Foundation\Http\FormRequest;

class CreateProductRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'price' => [
                'required',
                new MoneyRule(
                    min: 0,
                    max: 1000,
                ),
            ],
            'currency' => [
                'required',
                new CurrencyRule(),
            ],
        ];
    }
}

JSON Serialization

This package provides JSON serialization for both Money and Currency objects but you can customize according to your project requirements.

Money

Default:

{
    "amount": "1.00",
    "currency": {
        "name": "US Dollar",
        "code": "USD",
        "numeric_code": 840,
        "symbol": "$",
        "symbol_first": true,
        "symbol_spaced": false,
        "decimal_places": 2,
        "decimal_separator": ".",
        "thousand_places": 3,
        "thousand_separator": ","
    }
}

The amount field respects the JSON serialization unit of the Money object (which defaults to brick-money.minor configuration). If set to true, the amount is returned in minor units (e.g., cents for USD). Otherwise, it is returned in major units (e.g., dollars for USD):

use Devhammed\LaravelBrickMoney\Money;

Money::jsonSerializeMinorUnits(true); // or `false` to return major units.

You can also customize the whole JSON serialization process by providing a custom serializer:

use Devhammed\LaravelBrickMoney\Money;

Money::jsonSerializer(fn(Money $money) => [
    'amount' => (string) (Money::jsonSerializeMinorUnits() ? $money->getMinorAmount() : $money->getAmount()),
    'currency' => (string) $money->getCurrency(),
]);

Which will return something like this:

{
    "amount": "1.00",
    "currency": "USD"
}
Currency

Default:

{
    "name": "US Dollar",
    "code": "USD",
    "numeric_code": 840,
    "symbol": "$",
    "symbol_first": true,
    "symbol_spaced": false,
    "decimal_places": 2,
    "decimal_separator": ".",
    "thousand_places": 3,
    "thousand_separator": ","
}

Customize:

use Devhammed\LaravelBrickMoney\Currency;

Currency::jsonSerializer(fn(Currency $currency) => [
    'name' => $currency->getName(),
    'code' => $currency->getCode(),
]);

Helpers

money(100) // $100.00

money(100, minor: true) // $1.00

money(100, 'EUR') // €100,00

currency('USD') // USD

Views

This package provides helpers to work with money and currency in Blade templates.

Components

<x-money amount="100"/> <!-- $100.00 -->

<x-money amount="100" currency="USD"/> <!-- $100.00 -->

<x-money amount="100" currency="USD" minor/> <!-- $1.00 -->

<x-currency currency="USD"/> <!-- USD -->

Directives

@money(100) // $100.00

@money(100, minor: true) // $1.00

@money(100, 'EUR') // €100,00

@currency('USD') // USD

Extensions

The Money and Currency classes implements the Laravel Macroable trait, allowing you to add custom functionalities through macros and mixins.

Macros

use Devhammed\LaravelBrickMoney\Money;
use Devhammed\LaravelBrickMoney\Currency;

Money::macro('zero', fn(Currency|string $currency) => Money::of(0, $currency));

Money::macro('withPercentage', function (float $percentage): Money {
    return $this->multipliedBy(1 + ($percentage / 100));
});

Money::zero('USD')->plus(100)->withPercentage(10); // $110

Mixins

And with mixins, you can achieve the same thing using a dedicated class:

use Devhammed\LaravelBrickMoney\Money;
use Devhammed\LaravelBrickMoney\Currency;

class MoneyExtensions
{
    public static function zero(Currency|string $currency): Money
    {
        return Money::of(0, $currency);
    }
    
    public function withPercentage(float $percentage): Money
    {
        return $this->multipliedBy(1 + ($percentage / 100));
    }
}

Money::mixin(new MoneyExtensions());

Money::zero('USD')->plus(100)->withPercentage(10); // $110

Livewire

This package provides automatic support for Livewire by registering property synthesizers for Money and Currency objects.

This allows you to use Money and Currency objects directly as Livewire properties:

use Devhammed\LaravelBrickMoney\Money;
use Livewire\Component;

class Wallet extends Component
{
    public Money $balance;

    public function mount()
    {
        $this->balance = Money::of(100, 'USD');
    }

    public function addTenDollars()
    {
        $this->balance = $this->balance->plus(10);
    }

    public function render()
    {
        return view('livewire.wallet');
    }
}

Filament

This package also provides a Filament plugin and components to work with money and currency.

Forms

The MoneyInput component allows you to manage money fields in your Filament forms. It provides a fused group of an amount input and a currency selector.

use Devhammed\LaravelBrickMoney\Filament\Forms\Components\MoneyInput;

MoneyInput::for('price')

It will automatically use the configured currencies and default currency to populate the currency selector.

You must not use the make() method on the MoneyInput class directly, as we extended the FusedGroup component to provide this functionality and PHP does not support overriding methods with different signatures.

You can also specify a custom list of currencies and a default currency:

use Devhammed\LaravelBrickMoney\Filament\Forms\Components\MoneyInput;

MoneyInput::for('price')
    ->defaultCurrency('USD')
    ->currencies(['USD' => 'US Dollar', 'EUR' => 'Euro'])

You can also fix the currency so only the amount is editable:

MoneyInput::for('price')
    ->fixedCurrency()

And you can customize the underlying input and select components:

MoneyInput::for('price')
    ->currencySelect(fn ($select) => $select->columnSpan(['xl' => 3]))
    ->amountInput(fn ($input) => $input->columnSpan(['xl' => 9]))

Tables

The MoneyColumn allows you to display money values in your Filament tables.

use Devhammed\LaravelBrickMoney\Filament\Tables\Columns\MoneyColumn;

MoneyColumn::make('price')

It will automatically format the Money object using its format() method, and it extended the TextColumn component so you can use any of its methods to further customize the column.

Testing

Run the test suite:

composer test

Changelog

See the CHANGELOG for a full history of updates.

Security

If you discover a security vulnerability, please refer to the security policy.

Credits

License

This package is open-source software released under the MIT License.

See LICENSE.md for details.

devhammed/laravel-brick-money 适用场景与选型建议

devhammed/laravel-brick-money 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 478 次下载、GitHub Stars 达 25, 最近一次更新时间为 2025 年 12 月 02 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「money」 「laravel」 「brick」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 devhammed/laravel-brick-money 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 devhammed/laravel-brick-money 我们能提供哪些服务?
定制开发 / 二次开发

基于 devhammed/laravel-brick-money 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 478
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 25
  • 点击次数: 6
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 25
  • Watchers: 0
  • Forks: 1
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-12-02