Installation:
composer require cknow/laravel-money
Run php artisan vendor:publish --provider="Cknow\Money\MoneyServiceProvider" to publish the default config.
First Use Case: Convert raw amounts to formatted currency strings:
use Cknow\Money\Money;
// Basic usage
echo Money::USD(500); // Outputs "$5.00"
// Force decimals (e.g., for accounting)
echo Money::USD(500, true); // Outputs "$500.00"
Key Classes:
Money: Facade for currency operations.Money\Money: Core class for creating and manipulating money objects.Money\Currency: Handles currency-specific logic.Money facade in Cknow\Money\Money for quick operations.config/money.php for currency settings (e.g., default locale, precision).tests/ directory for usage examples and edge cases.Creating Money Objects:
// Static creation
$amount = Money::USD(1000); // Creates a Money object for $10.00
// Dynamic creation
$money = new \Cknow\Money\Money(1000, 'USD');
Currency Conversion:
$eur = Money::EUR(1000); // €10.00
$usd = $eur->convert('USD'); // Converts to $11.00 (approx)
Arithmetic Operations:
$total = Money::USD(500)->add(Money::USD(300)); // $8.00
$discount = Money::USD(1000)->subtract(Money::USD(200)); // $8.00
Formatting:
// Default formatting
echo Money::USD(1234.56)->format(); // "$1,234.56"
// Custom formatting (via config)
echo Money::USD(1234.56)->format('en_US', '€#,##0.00'); // "€1,234.56"
Database Storage:
Use the Money type in Eloquent models:
use Cknow\Money\Money;
class Order extends Model {
protected $casts = [
'amount' => Money::class,
];
}
money rule in Laravel’s validator:
$request->validate([
'price' => 'required|money:USD',
]);
return response()->json(['total' => Money::USD(1000)->format()]);
public function handle($request, Closure $next) {
if ($request->user()->isAdmin()) {
$request->merge(['currency' => 'USD']);
}
return $next($request);
}
Precision Handling:
500 = $5.00). Avoid floating-point arithmetic.Money::USD(500)->divide(2) instead of Money::USD(500) / 2.Currency Conversion Rates:
config/money.php:
'rates' => [
'USD' => ['EUR' => 0.85, 'GBP' => 0.75],
],
Locale Conflicts:
Intl extension. If format() fails, ensure:
en_US).Intl is installed (pecl install intl).format('en_US', 'custom_pattern') to bypass locale issues.Database Migrations:
amount_in_cents). Example migration:
$table->unsignedBigInteger('amount')->comment('Amount in cents');
Time Zones and Rates:
Money class or use a service layer.dd(Money::USD(1000)->getAmount(), Money::USD(1000)->getCurrency());
php artisan config:clear
Then verify config/money.php settings.Custom Formatters:
Override the format() method in a service class:
class CustomMoneyFormatter {
public function format(Money $money, string $locale = null, string $pattern = null) {
// Custom logic (e.g., add tax symbols)
return $money->format($locale, $pattern) . ' (incl. tax)';
}
}
Add New Currencies:
Extend the Currency class or use MoneyPHP’s Currency directly:
$customCurrency = new \Money\Currency('XBT'); // Bitcoin
$amount = new \Money\Money(1000, $customCurrency);
Event Listeners:
Trigger events for money operations (e.g., money.converted):
// In EventServiceProvider
protected $listen = [
'money.converted' => [YourListener::class],
];
Testing:
Mock the Money facade in tests:
Money::shouldReceive('USD')->andReturn(Money::new(1000, 'USD'));
trait HandlesMoney {
public function getFormattedPrice() {
return Money::USD($this->price_in_cents)->format();
}
}
$totals = $orders->map->amount->sum(); // Sums all Money objects
$rate = Cache::remember("currency_rate_{$from}_{$to}", now()->addHours(1), function() use ($from, $to) {
return Money::getRate($from, $to);
});
How can I help you explore Laravel packages today?