ویژگی تصویر

تابع money_format() در PHP

  /  PHP   /  تابع money_format() در PHP
بنر تبلیغاتی الف
آموزش PHP

تابع money_format() در PHP برای قالب‌دهی اعداد به شکل رشته‌های پولی (currency) طراحی شده بود. این تابع بر پایهٔ توابع C (strfmon) و تنظیمات محلی (locale) کار می‌کرد و خروجی‌ای با نماد واحد پولی، جداکننده گروهی (thousands separator) و تعداد ارقام اعشار مطابق locale تولید می‌کرد.

نحو کلی

نحو کلی تابع:

string money_format(string $format, float $number)

پارامتر $format شامل یک یا چند قالب مشابه strftime/strfmon است؛ معمولاً از تبدیل‌کننده‌های %n (قالب ملی) یا %i (قالب بین‌المللی) استفاده می‌شود.

مثال ساده

setlocale(LC_MONETARY, 'en_US.UTF-8');
echo money_format('%.2n', 1234.56); // خروجی: $1,234.56

در این مثال ابتدا locale را روی en_US تنظیم کرده‌ایم و سپس با الگوی ‘%.2n’ مقدار 1234.56 را به صورت پولی با دو رقم اعشار چاپ کرده‌ایم.

نکات مهم و محدودیت‌ها

  • عدم پشتیبانی در ویندوز: money_format() بر پایه strfmon است و در سیستم‌هایی که آن را ندارند (مثلاً بسیاری از پیاده‌سازی‌های ویندوز) قابل استفاده نیست.
  • وابستگی به locale جهانی: setlocale حالت سراسری (global) را تغییر می‌دهد؛ در برنامه‌هایی با چند رشتهٔ اجرایی یا سرویس‌های هم‌زمان می‌تواند مشکل‌ساز باشد.
  • حذف و منسوخ شدن: این تابع از PHP 7.4 به بعد منسوخ اعلام شد و در PHP 8.0 حذف گردید. بنابراین در کدهای جدید نباید از آن استفاده شود.
  • قابلیت‌های قالب‌دهی: الگوها می‌توانند پیشوند/پسوند، پر کردن با کاراکتر دلخواه، سرجمع/منفی با پرانتز و امثال آن را کنترل کنند؛ اما استفاده دقیق از فلگ‌ها نیاز به مطالعهٔ مستندات C دارد.

جایگزین‌های پیشنهادی

برای پروژه‌های مدرن بهتر است از یکی از دو جایگزین زیر استفاده کنید:

1) number_format — راه‌حل ساده

echo number_format(1234.56, 2, '.', ','); // خروجی: 1,234.56

توضیح: number_format عدد را با جداسازی هزارگان و تعیین کاراکتر اعشار قالب‌بندی می‌کند اما نماد واحد پول (مثل $ یا تومان) را اضافه نمی‌کند و مستقل از locale است. برای افزودن نماد می‌توانید آن را دستی کنار رشته قرار دهید.

2) Intl::NumberFormatter — بهترین جایگزین برای زبان‌ها و localeهای مختلف

$fmt = new NumberFormatter('en_US', NumberFormatter::CURRENCY);
echo $fmt->formatCurrency(1234.56, 'USD'); // خروجی: $1,234.56

$fmt = new NumberFormatter('fa_IR', NumberFormatter::CURRENCY);
echo $fmt->formatCurrency(1234.56, 'IRR'); // خروجی وابسته به پیاده‌سازی و locale

توضیح: کلاس NumberFormatter از افزونهٔ intl استفاده می‌کند، thread-safe است، وابستگی به تغییر locale سراسری ندارد و قابلیت‌های پیشرفتهٔ محلی‌سازی (مانند نماد ارز، سمت نمایش نماد، قواعد گروه‌بندی و ارقام یونیکد) را فراهم می‌آورد. برای پشتیبانی کامل باید افزونه intl نصب و فعال باشد.

نمونهٔ تبدیل سریع از money_format به NumberFormatter

function money_format_compat($format, $number, $locale = 'en_US') {
    // ساده‌سازی: اگر %n یا %i وجود دارد، از NumberFormatter استفاده می‌کنیم
    $useCurrency = preg_match('/%[ni]/', $format);
    $precision = 2;
    if (preg_match('/.([0-9]+)/', $format, $m)) {
        $precision = (int)$m[1];
    }
    if ($useCurrency && class_exists('NumberFormatter')) {
        $fmt = new NumberFormatter($locale, NumberFormatter::CURRENCY);
        $fmt->setAttribute(NumberFormatter::FRACTION_DIGITS, $precision);
        // پیش‌فرض USD؛ در حالت واقعی باید کد ارز را از locale یا ورودی دریافت کنید
        return $fmt->formatCurrency($number, 'USD');
    }
    return number_format($number, $precision, '.', ',');
}

توضیح: این تابع سازگارسازی ساده‌ای ارائه می‌دهد؛ فرمت‌های پیچیدهٔ money_format (فلگ‌ها، کاراکترهای پرکننده و غیره) را پشتیبانی کامل نمی‌کند اما برای تبدیل سریع اکثر موارد کاربردی مناسب است. در عمل بهتر است کد ارز را صریحاً دریافت کنید و locale مناسب را تعیین نمایید.

مقایسهٔ اجمالی

ویژگیmoney_format()NumberFormatter (intl)number_format()
وابسته به localeبلهبله (بدون تغییر locale سراسری)خیر
پشتیبانی نماد ارزبلهبله (قابل تنظیم با کد ارز)خیر
قابل استفاده در ویندوزمعمولاً خیربله (در صورت نصب intl)بله
موجود در PHP 8+خیر (حذف شده)بلهبله

پیشنهادات عملی و نکات پایانی

  • اگر برنامه شما روی PHP 7.4 یا بالاتر اجرا می‌شود یا قرار است قابل حمل باشد، از money_format استفاده نکنید.
  • برای بهترین نتیجه و تطبیق‌پذیری از NumberFormatter::formatCurrency استفاده کنید؛ این روش thread-safe است و پشتیبانی قوی از locale و ارزها دارد.
  • برای خروجی‌های ساده و مستقل از locale، number_format کافی و سبک است؛ نماد ارز را دستی اضافه کنید.
  • همیشه مطمئن شوید افزونهٔ intl روی سرور نصب است و localeهای مورد نیاز در سیستم فراهم‌اند.

در نهایت، money_format تاریخچهٔ مفید در پروژه‌های قدیمی دارد اما برای کدنویسی مدرن و قابل نگهداری باید به جای آن از ابزارهای استانداردتر مثل intl استفاده کنید.

آیا این مطلب برای شما مفید بود ؟

خیر
بله
موضوعات شما در انجمن: