本文目录导读:

我来帮你分析PHP项目中处理摩洛哥迪拉姆(MAD)与电子迪拉姆(eMAD)的常见方案。
货币处理核心代码
货币格式化类
<?php
class MoroccanCurrencyFormatter {
/**
* 格式化金额为MAD显示格式
*/
public static function formatMAD($amount, $decimals = 2) {
return number_format($amount, $decimals, ',', ' ') . ' MAD';
}
/**
* 格式化金额为eMAD显示格式
*/
public static function formatEMAD($amount, $decimals = 2) {
return number_format($amount, $decimals, ',', ' ') . ' eMAD';
}
/**
* MAD转换为eMAD (1 MAD = 1 eMAD,数值相同但用途不同)
*/
public static function madToEmad($amount) {
return (float) $amount;
}
/**
* eMAD转换为MAD
*/
public static function emadToMad($amount) {
return (float) $amount;
}
/**
* 金额验证
*/
public static function validateAmount($amount) {
if (!is_numeric($amount) || $amount < 0) {
throw new InvalidArgumentException('Invalid amount value');
}
if ($amount > 999999999.99) {
throw new OverflowException('Amount exceeds maximum limit');
}
return true;
}
/**
* 阿拉伯语金额显示
*/
public static function formatArabic($amount) {
$arabicDigits = ['٠', '١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩'];
$formatted = number_format($amount, 2, '.', ',');
$result = '';
foreach (str_split($formatted) as $char) {
if (is_numeric($char)) {
$result .= $arabicDigits[(int)$char];
} else {
$result .= $char;
}
}
return $result . ' درهم';
}
}
?>
数据库货币字段设计
-- MySQL示例
CREATE TABLE transactions (
id INT PRIMARY KEY AUTO_INCREMENT,
amount_mad DECIMAL(15,2) NOT NULL COMMENT '摩洛哥迪拉姆金额',
amount_emad DECIMAL(15,2) DEFAULT NULL COMMENT '电子迪拉姆金额',
currency_type ENUM('MAD', 'eMAD') NOT NULL DEFAULT 'MAD',
exchange_rate DECIMAL(10,6) DEFAULT 1.000000 COMMENT '汇率',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_currency (currency_type)
);
税款计算示例
<?php
class TaxCalculator {
// VAT税率 (20%标准税率)
const VAT_RATE = 0.20;
/**
* 计算含税金额
*
* @param float $exclTax 不含税金额
* @param string $currency 'MAD' 或 'eMAD'
* @return array
*/
public static function calculateWithTax($exclTax, $currency = 'MAD') {
$vatAmount = $exclTax * self::VAT_RATE;
$inclTax = $exclTax + $vatAmount;
return [
'excl_tax' => $exclTax,
'vat_rate' => self::VAT_RATE * 100,
'vat_amount' => $vatAmount,
'incl_tax' => $inclTax,
'currency' => $currency,
'formatted_excl' => MoroccanCurrencyFormatter::formatMAD($exclTax),
'formatted_incl' => MoroccanCurrencyFormatter::formatMAD($inclTax)
];
}
/**
* 支付方式处理
*/
public static function processPayment($amount, $paymentMethod) {
switch ($paymentMethod) {
case 'cash':
return MoroccanCurrencyFormatter::formatMAD($amount);
case 'electronic':
return MoroccanCurrencyFormatter::formatEMAD($amount);
case 'mixed':
$cashAmount = $amount * 0.5;
$emadAmount = $amount * 0.5;
return [
'cash' => MoroccanCurrencyFormatter::formatMAD($cashAmount),
'electronic' => MoroccanCurrencyFormatter::formatEMAD($emadAmount),
'total' => $amount
];
default:
throw new InvalidArgumentException('Unsupported payment method');
}
}
}
?>
货币转换中间件示例 (Laravel)
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class CurrencyMiddleware
{
/**
* 处理货币转换请求
*/
public function handle(Request $request, Closure $next)
{
// 检测请求中的货币类型
$currencyType = $request->header('X-Currency-Type', 'MAD');
// 存储到请求属性
$request->attributes->set('currency_type', $currencyType);
// 自动转换金额参数
if ($request->has('amount')) {
$amount = $request->input('amount');
if ($currencyType === 'eMAD') {
// eMAD转换为MAD内部处理
$madAmount = MoroccanCurrencyFormatter::emadToMad($amount);
$request->merge(['amount_mad' => $madAmount]);
} else {
$request->merge(['amount_mad' => $amount]);
}
}
$response = $next($request);
// 响应中转换货币格式
if ($response->getStatusCode() === 200 && $response->original) {
$data = $response->getData(true);
if (isset($data['amount'])) {
if ($currencyType === 'eMAD') {
$data['formatted_amount'] = MoroccanCurrencyFormatter::formatEMAD($data['amount']);
} else {
$data['formatted_amount'] = MoroccanCurrencyFormatter::formatMAD($data['amount']);
}
$response->setData($data);
}
}
return $response;
}
}
?>
支付网关集成示例
<?php
class CMI_PaymentGateway {
private $merchantId;
private $secretKey;
public function __construct($merchantId, $secretKey) {
$this->merchantId = $merchantId;
$this->secretKey = $secretKey;
}
/**
* 创建支付请求
*/
public function createPayment($amount, $orderId, $currency = 'MAD') {
$paymentData = [
'merchantId' => $this->merchantId,
'orderId' => $orderId,
'amount' => $amount * 100, // 转换为分
'currency' => $currency,
'paymentType' => ($currency === 'eMAD') ? 'ELECTRONIC' : 'CASH',
'successUrl' => url('/payment/success'),
'failUrl' => url('/payment/fail'),
'timestamp' => time()
];
// 生成签名
$paymentData['signature'] = $this->generateSignature($paymentData);
return $paymentData;
}
/**
* 生成支付签名
*/
private function generateSignature($data) {
ksort($data);
$signatureString = implode('|', $data);
return hash_hmac('sha256', $signatureString, $this->secretKey);
}
}
?>
使用示例
<?php
// 使用示例
try {
// 格式化金额
echo MoroccanCurrencyFormatter::formatMAD(1500.50); // "1 500,50 MAD"
echo MoroccanCurrencyFormatter::formatEMAD(2000.00); // "2 000,00 eMAD"
// 阿拉伯语显示
echo MoroccanCurrencyFormatter::formatArabic(1234.56); // "١٢٣٤,٥٦ درهم"
// 计算税款
$taxResult = TaxCalculator::calculateWithTax(1000, 'MAD');
print_r($taxResult);
// 混合支付
$mixedPayment = TaxCalculator::processPayment(500, 'mixed');
} catch (Exception $e) {
echo 'Error: ' . $e->getMessage();
}
?>
注意事项
- 汇率处理: MAD和eMAD名义上1:1,但实际使用场景不同
- 精度控制: 财务计算建议使用
DECIMAL或BCMath函数 - 国际化: 考虑多语言显示(阿拉伯语、法语等)
- 合规性: 遵循摩洛哥央行(BAM)的相关规定
需要了解更具体的业务场景或功能实现吗?