تابع stream_filter_remove() در PHP
تابع stream_filter_remove() در PHP برای حذف یک فیلتر (filter) که پیشتر به یک جریان (stream) یا bucket متصل شده، استفاده میشود. این تابع زمانی کاربردی است که بخواهید پردازش اضافهای که توسط فیلتر انجام میشود را متوقف کرده و دوباره جریان را بدون آن فیلتر ادامه دهید.
امکانات و کاربردهای معمول
- حذف فیلترهای تبدیلی مانند تبدیل کاراکترها (convert.*)، فشردهسازی (zlib.*) یا فیلترهای رشتهای (string.*).
- خاموش کردن موقت لاگینگ یا رمزنگاری که بهصورت داینامیک به یک stream اضافه شدهاند.
- پاکسازی ذخیره منابع — هرچند بسته شدن جریان بهطور خودکار فیلترها را آزاد میکند.
- در سناریوهای پردازش دادهای که فیلترها باید شرطی اعمال یا برداشته شوند.
امضای تابع و پارامترها
| تابع | شرح |
|---|---|
| bool stream_filter_remove(resource $filter) | حذف فیلتر مشخصشده. پارامتر $filter باید همان resource بازگشتی از stream_filter_append یا stream_filter_prepend باشد. |
تابع مقدار true در صورت موفقیت و false در صورت شکست بازمیگرداند.
چگونه کار میکند؟ — مثالی ساده
$fp = fopen('php://temp', 'r+');
stream_filter_append($fp, 'string.toupper', STREAM_FILTER_WRITE);
fwrite($fp, "hellon");
rewind($fp);
echo stream_get_contents($fp); // HELLO
// حالا فرض کنیم میخواهیم فیلتر را حذف کنیم:
$filters = stream_get_filters(); // فقط برای مشاهده نام فیلترها (لیست کلی)
$filterResource = stream_filter_append($fp, 'string.toupper', STREAM_FILTER_WRITE);
// حذف فیلتر با resource بازگشتی
stream_filter_remove($filterResource);
fwrite($fp, "worldn");
rewind($fp);
echo stream_get_contents($fp);توضیح: در این مثال ابتدا فیلتر string.toupper اضافه شده و ورودی به حروف بزرگ تبدیل میشود. برای حذف فیلتر باید resource برگشتی از stream_filter_append را نگهدارید و سپس آن را به stream_filter_remove بدهید. توجه داشته باشید که اگر چند بار فیلتر مشابه اضافه کنید، هر فراخوانی stream_filter_append یک resource مجزا ایجاد میکند و باید همان resource را حذف کنید تا آن فیلتر برداشته شود.
نکته مهم: حذف بر اساس resource، نه بر اساس نام
شاید وسوسه شوید فیلتر را بر اساس نام آن حذف کنید؛ اما این امکان وجود ندارد. stream_filter_remove تنها یک resource را میپذیرد که هنگام افزودن فیلتر برگشت داده شده است. بنابراین اگر قصد دارید بعداً فیلتر را حذف کنید، resource را ذخیره کنید.
مثال پیشرفته: ثبت و حذف یک php_user_filter سفارشی
class MyFilter extends php_user_filter {
public function filter($in, $out, &$consumed, $closing) {
while ($bucket = stream_bucket_make_writeable($in)) {
$bucket->data = str_replace('foo', 'bar', $bucket->data);
$consumed += $bucket->datalen;
stream_bucket_append($out, $bucket);
}
return PSFS_PASS_ON;
}
}
stream_filter_register('myreplace', 'MyFilter');
$fp = fopen('php://temp', 'r+');
$fr = stream_filter_append($fp, 'myreplace', STREAM_FILTER_READ);
fwrite($fp, "foo baz foon");
rewind($fp);
echo stream_get_contents($fp); // bar baz bar
// حذف فیلتر سفارشی
stream_filter_remove($fr);توضیح: در این مثال یک فیلتر سفارشی با نام myreplace تعریف و ثبت شده است که هر بار کلمه ‘foo’ را به ‘bar’ تبدیل میکند. پس از افزودن فیلتر و خواندن دادهها میتوانیم همان resource (در متغیر $fr) را به stream_filter_remove بدهیم تا فیلتر حذف شود. اگر کلاس فیلتر متد onClose داشته باشد، هنگام حذف فیلتر فراخوانی میشود.
نکات و بهترین شیوهها (Expert Tips)
- همیشه resource برگشتی از stream_filter_append یا stream_filter_prepend را ذخیره کنید تا امکان حذف دقیق وجود داشته باشد.
- اگر چند فیلتر روی یک stream دارید و میخواهید ترتیب را کنترل کنید، از stream_filter_prepend برای قرار دادن فیلتر در ابتدای زنجیره استفاده کنید. حذف تنها فیلتر مشخصشده را برمیدارد و ترتیب باقیمانده را تغییر نمیدهد.
- بستن (fclose) یک stream تمام فیلترهای مربوطه را آزاد میکند؛ در نتیجه نیاز به حذف دستی همیشه ضروری نیست، اما حذف دستی در زمان کارِ جاری میتواند کارایی را بهبود دهد (مثلاً برای جلوگیری از انجام پردازشهای غیرضروری).
- برای اشکالزدایی میتوانید از stream_get_filters() برای دیدن نام فیلترهای موجودِ قابل ثبت استفاده کنید، اما توجه کنید که این لیست نامهای قابل ثبت است نه منابع فیلترِ الحاقشده به یک stream خاص.
- حذف فیلتر ممکن است در برخی موارد با خطا مواجه شود اگر resource معتبر نباشد یا قبلاً حذف/آزاد شده باشد. همیشه مقدار بازگشتی را بررسی کنید.
مشکلات رایج و راهحلها
- عدم حذف فیلتر: اغلب به دلیل از دست دادن resource است. همیشه resource را در متغیری که در دستیابی بعدی قابل دسترسی باشد ذخیره کنید.
- انتظار حذف بر اساس نام: همانطور که گفته شد، باید resource داشته باشید. اگر فقط نام را دارید، هیچ تابع استانداردی برای حذف همه فیلترهای با آن نام وجود ندارد و باید خودتان مکانیزم پیگیری resource را پیادهسازی کنید.
- حذف بعد از fclose: اگر stream بسته شده باشد، حذف فیلتر ممکن است بیمعنی باشد زیرا منابع از قبل آزاد شدهاند.
جمعبندی
تابع stream_filter_remove() یک ابزار ساده اما قدرتمند برای مدیریت چرخه حیات فیلترها در اکوسیستم Stream های PHP است. با ذخیرهسازی resource بازگشتی هنگام افزودن فیلتر، میتوانید کنترل دقیقی روی اعمال یا حذف پردازشهای مرتبط با جریان داشته باشید. این تابع مخصوصاً در سیستمهایی که فیلترها بهصورت داینامیک بر اساس شرایط اجرا اضافه و حذف میشوند بسیار مفید است.
اگر نیاز به نمونههای بیشتر یا بررسی سناریوی خاصی دارید (مثلاً ترکیب فیلترهای فشردهسازی و رمزنگاری یا تعامل با stream context ها)، میتوان نمونههای دقیقتری ارائه کرد.
آیا این مطلب برای شما مفید بود ؟



