ویژگی تصویر

تابع preg_replace_callback() در PHP

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

تابع preg_replace_callback() یکی از ابزارهای قدرتمند برای جایگزینی متن با استفاده از عبارت‌های منظم (PCRE) و یک تابع callback در PHP است. این تابع زمانی مفید است که نیاز به پردازش پیچیده یا محاسباتی برای مقدار جایگزین دارید؛ مثلاً تبدیل قالب‌های سفارشی، محاسبه مقادیر پویا یا فرمت‌دهی بر اساس محتوا.

فرم کلی تابع

$result = preg_replace_callback(string $pattern, callable $callback, string $subject, int $limit = -1, int &$count = null)

پارامترها:

  • $pattern: الگوی PCRE (می‌تواند آرایه باشد).
  • $callback: تابعی که برای هر تطبیق فراخوانی می‌شود و باید رشته جایگزین را بازگرداند.
  • $subject: رشته (یا آرایه‌ای از رشته‌ها) که در آن جستجو انجام می‌شود.
  • $limit: حداکثر تعداد جایگزینی‌ها (پیش‌فرض -1 = بی‌نهایت).
  • $count: در صورت نیاز تعداد جایگزینی‌های انجام‌شده را برمی‌گرداند.

چرا از preg_replace_callback استفاده کنیم؟

  • اجتناب از modifier قدیمی /e که خطرناک و منسوخ شده است.
  • امکان اجرای منطق پیشرفته برای هر تطبیق (مثلاً تبدیل تاریخ‌ها، محاسبه، یا فراخوانی توابع دیگر).
  • استفاده از closures و use برای انتقال متغیرهای خارجی به callback.

مثال پایه: تبدیل اعداد به متن‌شده (افزایش هر عدد)

$text = "Item1 costs 20, Item2 costs 35.";
$result = preg_replace_callback('/d+/', function($matches) {
    return (int)$matches[0] + 1;
}, $text);
echo $result; // Item1 costs 21, Item2 costs 36.

در این مثال، الگوی /d+/ تمام اعداد را می‌گیرد. تابع ناشناس (closure) هر عدد را به مقدار عددی تبدیل کرده و یک واحد اضافه می‌کند. مقدار بازگشتی به‌عنوان جایگزین در متن قرار می‌گیرد.

مثال: استفاده از گروه‌های نام‌گذاری‌شده برای قالب‌بندی تاریخ

$date = "2025-11-07";
$formatted = preg_replace_callback('/(?Pd{4})-(?Pd{2})-(?Pd{2})/', function($m) {
    return sprintf('%s/%s/%s', $m['d'], $m['m'], $m['y']);
}, $date);
echo $formatted; // 07/11/2025

اینجا از گروه‌های نام‌گذاری‌شده (?P<name>) استفاده شده تا در callback با کلیدهای خوانا به مقادیر دسترسی داشته باشیم. مزیت این شیوه خوانایی و کاهش خطای اندیس‌گذاری است.

مثال پیشرفته: امن‌سازی و تبدیل لینک‌ها

$text = 'Visit http://example.com or https://site.org/page?x=1.';
$result = preg_replace_callback('#bhttps?://[^s<]+#i', function($m) {
    $url = htmlspecialchars($m[0], ENT_QUOTES, 'UTF-8');
    return sprintf('%s', $url, $url);
}, $text);
echo $result;

در این کد، URLها شناسایی می‌شوند و در callback ابتدا با htmlspecialchars امن‌سازی می‌شوند سپس داخل تگ <a> قرار می‌گیرند تا از حملات XSS جلوگیری شود.

preg_replace_callback_array — چند الگو با callbackهای مختلف

$subject = "foo 123 bar 456";
$result = preg_replace_callback_array([
    '/d+/' => function($m) { return '['.$m[0].']'; },
    '/foo|bar/' => function($m) { return strtoupper($m[0]); }
], $subject);
echo $result; // FOO [123] BAR [456]

این تابع (موجود از PHP 7) به شما اجازه می‌دهد چندین الگو را همراه با callback متناظرشان به‌طور هم‌زمان تعریف کنید. مناسب زمانی است که می‌خواهید انواع مختلفی از جایگزینی‌ها را در یک فراخوانی انجام دهید.

نکات عملکردی و بهترین شیوه‌ها

  • هرچند callback قدرت زیادی دارد، اما فراخوانی پی‌درپی تابع گران‌تر از جایگزینی ساده است؛ برای داده‌های بسیار بزرگ، تست عملکرد انجام دهید.
  • از پرهیز الگوهای پر بازگشتی (backtracking) و الگوهای ناکارا جلوگیری کنید؛ از آکولادهای محدودکننده و ^$ استفاده کنید تا محدوده جستجو کمتر شود.
  • برای متن‌های یونیکد حتماً از فلگ u استفاده کنید (مثل /.../u) و برای پردازش رشته‌های چندبایتی از توابع mb_* داخل callback بهره ببرید.
  • در صورتی که اطلاعات خارجی لازم است، با use در closure آن‌ها را وارد کنید تا خوانایی و ایمنی بهبود یابد.

جلوگیری از اشکال رایج

  • عدم استفاده از modifier /e و انتقال منطق به callback.
  • بررسی ورودی‌ها برای امنیت—در callback هر دادهٔ ورودی که به HTML یا SQL می‌رود باید ضدعفونی شود.
  • اگر callback بسیار سنگین است، سعی کنید از کش (memoization) برای نتایج تکراری استفاده کنید.

مثال بهینه‌سازی: Memoization در callback

$cache = [];
$text = "apple apple banana apple";
$result = preg_replace_callback('/bw+b/', function($m) use (&$cache) {
    $word = $m[0];
    if (isset($cache[$word])) {
        return $cache[$word];
    }
    // فرضاً محاسبهٔ سنگینی شبیه به فراخوانی وب‌سرویس
    $replacement = strtoupper($word);
    $cache[$word] = $replacement;
    return $replacement;
}, $text);
echo $result; // APPLE APPLE BANANA APPLE

با نگه‌داشتن نتایج در آرایه کش، از محاسبهٔ دوباره برای واژه‌های تکراری جلوگیری می‌کنیم که می‌تواند در موارد واقعی (مثلاً فراخوانی API یا پردازش پیچیده) بسیار مفید باشد.

مقایسه سریع

تابعکاربردمزیت
preg_replaceجایگزینی ساده با الگوسریع و مستقیم
preg_replace_callbackجایگزینی با منطق دینامیکانعطاف و امنیت بیشتر
preg_replace_callback_arrayچند الگو با callbackهای مجزاسازماندهی بهتر

جمع‌بندی و نکات نهایی

تابع preg_replace_callback() ابزاری بسیار انعطاف‌پذیر برای انجام جایگزینی‌های پیچیده و امن در PHP است. با استفاده از closures، گروه‌های نام‌گذاری‌شده، و تکنیک‌های بهینه‌سازی مثل کش، می‌توانید پردازش متن قوی و قابل‌نگهداری بسازید. همیشه به امنیت (مثل ضدعفونی خروجی) و عملکرد توجه کنید و از /e پرهیز نمایید.

در صورت نیاز می‌توان مثال‌های بیشتری شامل کار با آرایه‌های موضوع، کنترل limit و بررسی تعداد جایگزینی‌ها با پارامتر &$count ارائه داد.

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

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