ویژگی تصویر

تابع is_resource() در PHP

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

تابع is_resource() یکی از توابع پایهٔ PHP است که مشخص می‌کند یک متغیر از نوع resource هست یا خیر. منابع (resources) در PHP نشان‌دهندهٔ اشاره‌گرها یا هندل‌هایی به موجودیت‌های خارج از مدیریت حافظهٔ PHP مثل فایل، اتصال شبکه، تصویر GD یا اتصال دیتابیس هستند. در این مقاله به صورت دقیق عملکرد، مثال‌ها، نکات سازگاری با نسخه‌های جدید PHP (از جمله PHP 8) و بهترین شیوه‌ها را بررسی می‌کنیم.

تعریف و سینتکس

سینتکس ساده است:

bool is_resource ( mixed $var )

اگر $var یک resource باشد مقدار true و در غیر این صورت false برمی‌گرداند.

منابع (Resources) چیستند؟

منابع متغیرهایی هستند که به داده‌ها یا سرویس‌های خارجی اشاره می‌کنند؛ برای مثال:

  • دسکریپتور فایل: نتیجهٔ fopen()
  • هندل شبکه یا socket
  • منابع کتابخانه‌های C مثل GD (در نسخه‌های قدیمی‌تر)
  • برخی هندل‌های موقت برای streamها، XMLReader و غیره

مثال پایه

<?php
$fp = fopen('example.txt', 'w');
if (is_resource($fp)) {
    fwrite($fp, "Hellon");
    fclose($fp);
} else {
    echo "Not a resourcen";
}
?>

در این مثال ابتدا یک فایل باز می‌کنیم و سپس با is_resource بررسی می‌کنیم که هندل فایل معتبر است. اگر مثبت بود، مقداری می‌نویسیم و در پایان fclose() را صدا می‌زنیم.

نکات ایمنی: قبل از get_resource_type حتما چک کنید

تابع get_resource_type() فقط روی منابع معتبر کار می‌کند و اگر آرگومانش resource نباشد ممکن است اخطار تولید کند. بهتر است همیشه با is_resource() چک کنید:

<?php
if (is_resource($res)) {
    echo get_resource_type($res);
} else {
    echo "Not a resource or already closedn";
}
?>

این روش از بروز هشدارها جلوگیری می‌کند و امن‌تر است.

تغییرات در PHP 8 و اهمیت سازگاری

در نسخه‌های جدید PHP (از جمله PHP 8) برخی از منابع سنتی به اشیاء (objects) تبدیل شدند. برای مثال:

  • هندل‌های cURL در PHP 8 به کلاس داخلی CurlHandle تبدیل شده‌اند.
  • GD به جای بازگرداندن resource از نوع gd از شیء GdImage استفاده می‌کند.

در نتیجه کدهایی که صرفاً روی is_resource() تکیه می‌کردند ممکن است در PHP 8 درست کار نکنند. بهترین راه حل، نوشتن چک‌های سازگار با نسخه‌های مختلف است.

نمونهٔ کد سازگاری برای cURL

<?php
function is_curl_handle($ch) {
    // اگر resource باشد (نسخه‌های قدیمی)
    if (is_resource($ch)) {
        return true;
    }
    // اگر کلاس CurlHandle تعریف شده و شیء از آن نوع باشد (PHP 8+)
    if (class_exists('CurlHandle') && $ch instanceof CurlHandle) {
        return true;
    }
    return false;
}

// استفاده
$ch = curl_init('https://example.com');
if (is_curl_handle($ch)) {
    // ایمن برای ادامه کار با cURL
    curl_close($ch);
}
?>

در این کد ابتدا با is_resource بررسی می‌کنیم تا برای نسخه‌های قدیمی سازگار باشد. سپس با class_exists از وجود کلاس CurlHandle در زمان اجرا مطمئن می‌شویم و تنها در صورت وجود آن از instanceof استفاده می‌کنیم تا در محیط‌هایی که این کلاس تعریف نشده خطا رخ ندهد.

مثال سازگاری با GD

<?php
function is_gd_image($img) {
    if (is_resource($img) && get_resource_type($img) === 'gd') return true;
    // در PHP 8 به بعد، شیء GdImage وجود دارد
    if (class_exists('GdImage') && $img instanceof GdImage) return true;
    return false;
}
?>

این تابع می‌تواند تشخیص دهد که آیا ورودی یک تصویر GD است چه در نسخه‌های قدیمی که از resource استفاده می‌شد و چه در نسخه‌های جدید که از GdImage استفاده می‌شود.

رفتار پس از بستن resource

بعد از فراخوانی توابعی مانند fclose() یا curl_close()، resource معمولاً منقضی می‌شود. در برخی موارد متغیر هنوز مقداری دارد اما با is_resource() دیگر معتبر شناخته نمی‌شود. بنابراین همیشه قبل از کار با یک resource چک کنید که هنوز معتبر است.

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

  • همیشه پیش از فراخوانی توابعی مثل fwrite() یا fread() از is_resource استفاده کنید.
  • برای سازگاری با PHP 8 از چک‌های ترکیبی (is_resource و instanceof یا class_exists) استفاده کنید.
  • از بستن منابع (fclose، curl_close و …) پس از اتمام کار غافل نشوید تا حافظه و دیسک آزاد شود.
  • در پروژه‌های بزرگ ترجیح دهید هندل‌ها را داخل کلاس‌هایی بسته‌بندی کنید و از نوع‌دهی (type-hinting) و interfaceها برای مدیریت بهینه استفاده نمایید.
  • از نگهداری طولانی‌مدت منابع در حافظه جلوگیری کنید تا از نشت منابع (resource leak) پرهیز شود.

جدول: برخی resourceهای رایج و وضعیت در PHP 8+

منبع/هندلنسخه‌های قدیمی (PHP < 8)نسخه‌های جدید (PHP 8+)
فایل (fopen)resource (stream)معمولاً resource (stream) — همچنان resource
cURLresourceشیء (CurlHandle)
GDresource (gd)شیء (GdImage)
موتورهای قدیمی MySQLresource (mysql link)اکثر extensionهای قدیمی حذف یا تغییر یافته‌اند

جمع‌بندی

تابع is_resource() ابزار ساده و مفیدی برای تشخیص منابع در PHP است، اما با تغییرات معماری در نسخه‌های جدید مثل PHP 8 لازم است که در کدهای خود به سازگاری با اشیاء نیز توجه کنیم. ترکیب is_resource با بررسی وجود کلاس‌ها و instanceof راهکار مناسبی برای نوشتن کدی پایدار در برابر تغییرات نسخهٔ PHP است.

در صورت نیاز می‌توانید نمونه‌های واقعی پروژه‌تان را بیاورید تا راهنمایی سازگاری و اصلاح کد مخصوص همان مورد را نیز ارائه دهم.

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

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