ویژگی تصویر

تابع preg_replace_callback_array() در PHP

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

تابع preg_replace_callback_array() در PHP ابزاری برای جایگزینی متن با استفاده از الگوهای منظم و توابع callback است. این تابع از یک آرایه که کلیدهای آن الگوهای (pattern) منظم و مقادیر آن‌ها کال‌بک‌ها (callable) هستند استفاده می‌کند تا به هر الگو یک تابع پردازش اختصاص دهد. این روش خواناتر و سازمان‌یافته‌تر از فراخوانی‌های متوالی preg_replace_callback() است.

امضای تابع

این تابع به شکل زیر فراخوانی می‌شود:

mixed preg_replace_callback_array (
    array $pattern_callback_pairs ,
    string|array $subject ,
    int $limit = -1 ,
    int &$count = null
)

پارامترها:

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

نمونه ساده و توضیح

$patterns = [
    '/d+/' => function($matches) {
        return '[' . $matches[0] . ']';
    },
    '/foo/i' => function($matches) {
        return strtoupper($matches[0]);
    }
];

$subject = "foo has 123 apples and Foo has 45.";
$result = preg_replace_callback_array($patterns, $subject, -1, $count);
echo $result; // => "FOO has [123] apples and FOO has [45]."

در این مثال دو الگو تعریف شده‌اند: یکی برای اعداد و دیگری برای رشتهٔ “foo” با نادیده‌گرفتن بزرگی/کوچکی حروف. هر بار که الگو منطبق می‌شود، کال‌بک مربوطه فراخوانی شده و مقدار بازگشتی جایگزین متنِ پیدا شده می‌شود. مقدار $count، تعداد کل جایگزینی‌ها را بازمی‌گرداند.

موارد کاربرد و مزایا

  • مدیریت همزمان چند الگو و کال‌بک مرتبط با آن‌ها در یک ساختار مرتب.
  • کاهش کدهای تکراری نسبت به فراخوانی‌های جداگانهٔ preg_replace_callback.
  • خواناتر بودن نگهداری و افزودن الگوهای جدید (سازمان‌دهی بهتر).

مثال واقعی: تبدیل نشانه‌گذاری ساده به HTML

$patterns = [
    '/**(.*?)**/s' => function($m) { // bold
        return '' . htmlspecialchars($m[1]) . '';
    },
    '/[(.*?)]((.*?))/s' => function($m) { // link
        $text = htmlspecialchars($m[1]);
        $url = htmlspecialchars($m[2]);
        return '' . $text . '';
    }
];

$markdown = "This is **bold** and a [link](http://example.com).";
echo preg_replace_callback_array($patterns, $markdown);

در این سناریو، متن ساده‌ای که از علامت‌گذاری شبیه Markdown استفاده کرده را به HTML تبدیل می‌کنیم. توجه کنید که از htmlspecialchars برای جلوگیری از XSS استفاده شده — همیشه خروجی‌هایی که از متن کاربران به HTML تبدیل می‌شوند را ایمن کنید.

نکات فنی و ریسک‌ها

  • ترتیب الگوها اهمیت دارد: وقتی الگوها هم‌پوشانی داشته باشند، ترتیب آیتم‌ها در آرایه تعیین‌کنندهٔ این است که کدام الگو ابتدا پردازش شود.
  • هر کال‌بک باید رشته بازگرداند؛ بازگرداندن مقدار غیررشته یا null ممکن است به خروجی ناخواسته منجر شود.
  • برای رشته‌های UTF-8 از سوئیچ u در الگوها استفاده کنید تا رفتار صحیح برای یونیکد داشته باشید.
  • تابع /e (modifier قدیمی) حذف شده — از کال‌بک‌ها استفاده کنید و از eval یا اجرای کد داینامیک پرهیز کنید.

استفاده از آرایه به عنوان موضوع

$subjects = [
    "first: 10 apples",
    "second: 20 oranges"
];

$patterns = [
    '/d+/' => function($m) { return (int)$m[0] * 2; }
];

print_r(preg_replace_callback_array($patterns, $subjects));

اگر $subject آرایه باشد، تابع روی هر عنصر از آرایه اعمال شده و آرایهٔ نتیجه بازگردانده می‌شود. این می‌تواند برای پردازش مجموعهٔ داده‌ها مفید باشد.

بهینه‌سازی و روش‌های پیشرفته

اگر شمار زیادی الگو دارید و نگرانی عملکرد دارید، دو رویکرد ممکن است مفید باشد:

  • ادغام الگوها به یک الگوی ترکیبی (با نام‌گذاری گروه‌ها) و استفاده از یک کال‌بک واحد که بر اساس گروهِ یافته شده تصمیم می‌گیرد. این روش یک پاس برای همهٔ الگوها ایجاد می‌کند و می‌تواند از تکرار عبور متن جلوگیری کند.
  • اجتناب از کارهای سنگین داخل کال‌بک برای هر تطابق؛ به جای پردازش سنگین داخل کال‌بک، داده‌ها را جمع‌آوری کنید و پس‌پردازش دسته‌ای انجام دهید.

مثال: ادغام الگوها و کال‌بک واحد

$combined = '/(?P**(.*?)**)|(?P[(.*?)]((.*?)))/s';
$result = preg_replace_callback($combined, function($m) {
    if (!empty($m['bold'])) {
        return '' . htmlspecialchars($m[2]) . '';
    }
    if (!empty($m['link'])) {
        return '' . htmlspecialchars($m[4]) . '';
    }
    return '';
}, $text);

اینجا با یک الگوی ترکیبی و یک callback واحد کار را انجام دادیم. اگرچه کدنویسی کمی پیچیده‌تر می‌شود، اما در مواردی که تعداد الگوها زیاد است و عملکرد اهمیت دارد، مفید است.

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

  • همیشه خروجی کال‌بک‌ها را در برابر XSS و محتوای مخرب ایمن کنید (مثلاً با htmlspecialchars).
  • الگوها را با دقت بنویسید: استفاده از علامت‌های شیوه‌مند مثل u برای یونیکد و s برای مطابقت چندخطی وقتی لازم است.
  • به ترتیب الگوها دقت کنید و در صورت نیاز از الگوهای ترکیبی برای بهینه‌سازی استفاده کنید.
  • برای خطاها و اشکال‌زدایی، از لاگ یا شمارش جایگزینی‌ها ($count) کمک بگیرید.

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

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

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