本文目录导读:

我来帮您分析PHP项目中处理数字挪威克朗(NOK)与电子克朗(eNOK)的相关实现。
货币基础配置
<?php
// 货币配置类
class CurrencyConfig {
// 货币代码
const NOK = 'NOK'; // 挪威克朗
const ENOK = 'eNOK'; // 电子克朗
// 货币精度(小数位数)
const PRECISION_NOK = 2; // 挪威克朗2位小数
const PRECISION_ENOK = 2; // 电子克朗2位小数
// 货币符号
const SYMBOL_NOK = 'kr';
const SYMBOL_ENOK = 'e-kr';
// 汇率配置(示例)
const RATIO_NOK_TO_ENOK = 1; // 1:1 兑换(实际中可能有差异)
}
货币值对象
<?php
// 不可变的货币值对象
class Money {
private float $amount;
private string $currency;
public function __construct(float $amount, string $currency) {
if (!in_array($currency, [CurrencyConfig::NOK, CurrencyConfig::ENOK])) {
throw new InvalidArgumentException("不支持的货币类型");
}
$this->amount = $this->round($amount, $this->getPrecision($currency));
$this->currency = $currency;
}
public function getAmount(): float {
return $this->amount;
}
public function getCurrency(): string {
return $this->currency;
}
// 货币加减运算
public function add(Money $other): Money {
$this->assertSameCurrency($other);
return new Money(
$this->amount + $other->amount,
$this->currency
);
}
public function subtract(Money $other): Money {
$this->assertSameCurrency($other);
return new Money(
$this->amount - $other->amount,
$this->currency
);
}
// 乘法(用于计算税费等)
public function multiply(float $multiplier): Money {
return new Money(
$this->amount * $multiplier,
$this->currency
);
}
// 格式化显示
public function format(): string {
$formatted = number_format(
$this->amount,
$this->getPrecision($this->currency),
',',
' '
);
if ($this->currency === CurrencyConfig::NOK) {
return $formatted . ' ' . CurrencyConfig::SYMBOL_NOK;
}
return $formatted . ' ' . CurrencyConfig::SYMBOL_ENOK;
}
private function getPrecision(string $currency): int {
return $currency === CurrencyConfig::NOK
? CurrencyConfig::PRECISION_NOK
: CurrencyConfig::PRECISION_ENOK;
}
private function round(float $amount, int $precision): float {
return round($amount, $precision);
}
private function assertSameCurrency(Money $other): void {
if ($this->currency !== $other->currency) {
throw new InvalidArgumentException("货币类型不匹配");
}
}
}
货币转换服务
<?php
// 货币转换服务
class CurrencyConversionService {
private array $exchangeRates;
public function __construct(array $exchangeRates = []) {
// 默认汇率配置
$this->exchangeRates = $exchangeRates ?: [
CurrencyConfig::NOK => [
CurrencyConfig::ENOK => 1.0, // 1 NOK = 1 eNOK
],
CurrencyConfig::ENOK => [
CurrencyConfig::NOK => 1.0, // 1 eNOK = 1 NOK
]
];
}
// 货币转换
public function convert(Money $money, string $targetCurrency): Money {
if ($money->getCurrency() === $targetCurrency) {
return $money;
}
$rate = $this->getExchangeRate($money->getCurrency(), $targetCurrency);
$convertedAmount = $money->getAmount() * $rate;
return new Money($convertedAmount, $targetCurrency);
}
// 批量转换
public function convertAll(array $moneyList, string $targetCurrency): array {
return array_map(
fn(Money $money) => $this->convert($money, $targetCurrency),
$moneyList
);
}
private function getExchangeRate(string $from, string $to): float {
if (!isset($this->exchangeRates[$from][$to])) {
throw new RuntimeException("汇率未配置: $from -> $to");
}
return $this->exchangeRates[$from][$to];
}
}
账户与交易模型
<?php
// 账户模型
class Account {
private string $accountId;
private string $userId;
private Money $balance;
private string $accountType; // 'nok' 或 'enok'
public function __construct(string $userId, string $currency) {
$this->accountId = uniqid('acc_', true);
$this->userId = $userId;
$this->balance = new Money(0, $currency);
$this->accountType = $currency;
}
// 存款
public function deposit(Money $amount): Transaction {
if ($amount->getCurrency() !== $this->balance->getCurrency()) {
throw new InvalidArgumentException("货币类型不匹配");
}
$this->balance = $this->balance->add($amount);
return new Transaction(
$this->accountId,
$amount,
Transaction::TYPE_DEPOSIT
);
}
// 取款
public function withdraw(Money $amount): Transaction {
if ($amount->getCurrency() !== $this->balance->getCurrency()) {
throw new InvalidArgumentException("货币类型不匹配");
}
if ($amount->getAmount() > $this->balance->getAmount()) {
throw new InsufficientFundsException("余额不足");
}
$this->balance = $this->balance->subtract($amount);
return new Transaction(
$this->accountId,
$amount,
Transaction::TYPE_WITHDRAWAL
);
}
// 获取余额
public function getBalance(): Money {
return $this->balance;
}
}
// 交易记录
class Transaction {
const TYPE_DEPOSIT = 'deposit';
const TYPE_WITHDRAWAL = 'withdrawal';
const TYPE_TRANSFER = 'transfer';
const TYPE_EXCHANGE = 'exchange';
private string $transactionId;
private string $accountId;
private Money $amount;
private string $type;
private DateTime $createdAt;
public function __construct(string $accountId, Money $amount, string $type) {
$this->transactionId = uniqid('txn_', true);
$this->accountId = $accountId;
$this->amount = $amount;
$this->type = $type;
$this->createdAt = new DateTime();
}
}
货币兑换功能
<?php
// 货币兑换服务
class CurrencyExchangeService {
private CurrencyConversionService $conversionService;
public function __construct(CurrencyConversionService $conversionService) {
$this->conversionService = $conversionService;
}
// 账户间兑换
public function exchange(
Account $fromAccount,
Account $toAccount,
Money $amount
): array {
if ($fromAccount->getBalance()->getCurrency() ===
$toAccount->getBalance()->getCurrency()) {
throw new InvalidArgumentException("不能兑换相同货币");
}
// 从源账户取款
$withdrawalTransaction = $fromAccount->withdraw($amount);
// 转换货币
$targetCurrency = $toAccount->getBalance()->getCurrency();
$convertedAmount = $this->conversionService->convert(
$amount,
$targetCurrency
);
// 存入目标账户
$depositTransaction = $toAccount->deposit($convertedAmount);
return [$withdrawalTransaction, $depositTransaction];
}
}
使用示例
<?php
// 使用示例
try {
// 创建账户
$nokAccount = new Account('user1', CurrencyConfig::NOK);
$enokAccount = new Account('user1', CurrencyConfig::ENOK);
// 存入NOK
$depositAmount = new Money(1000.50, CurrencyConfig::NOK);
$nokAccount->deposit($depositAmount);
echo "NOK余额: " . $nokAccount->getBalance()->format() . "\n";
// 输出: 1 000,50 kr
// 存入eNOK
$enokDeposit = new Money(500.00, CurrencyConfig::ENOK);
$enokAccount->deposit($enokDeposit);
echo "eNOK余额: " . $enokAccount->getBalance()->format() . "\n";
// 输出: 500,00 e-kr
// 货币兑换
$exchangeService = new CurrencyExchangeService(
new CurrencyConversionService()
);
$exchangeAmount = new Money(200.00, CurrencyConfig::NOK);
$transactions = $exchangeService->exchange(
$nokAccount,
$enokAccount,
$exchangeAmount
);
echo "兑换后NOK余额: " . $nokAccount->getBalance()->format() . "\n";
echo "兑换后eNOK余额: " . $enokAccount->getBalance()->format() . "\n";
} catch (Exception $e) {
echo "错误: " . $e->getMessage() . "\n";
}
注意事项
- 精度处理: 使用
round()函数确保货币精度 - 不可变对象:
Money类设计为不可变,确保数据安全 - 类型安全: 严格检查货币类型,防止错误操作
- 汇率更新: 实际应用中汇率需要定期更新
- 数据库存储: 建议使用 DECIMAL 类型存储金额
- 审计日志: 所有货币操作应记录详细日志
这个实现提供了完整的挪威克朗与电子克朗处理功能,包括创建、转换、交易等核心操作。