ویژگی تصویر

تابع is_callable() در PHP

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

تابع is_callable() یکی از ابزارهای مفید در PHP برای تشخیص اینکه یک مقدار قابل فراخوانی (callable) هست یا خیر می‌باشد. در این مقاله به صورت جامع تفاوت‌ها، سناریوها، نکات فنی و مثال‌های عملی را بررسی می‌کنیم تا کاربرد صحیح و ایمن این تابع را در پروژه‌های PHP یاد بگیرید.

تعریف ساده و کاربرد اصلی

is_callable(mixed $var, bool $syntax_only = false, string &$callable_name = null): bool

این تابع بررسی می‌کند که آیا مقدار ورودی می‌تواند به‌عنوان تابع/متد/کلوزر فراخوانی شود یا خیر. خروجی بولی است و در صورت استفاده از پارامتر سوم، نام نهایی که PHP برای فراخوانی انتخاب می‌کند در آن بازگردانده می‌شود.

انواع مقدارهایی که is_callable پشتیبانی می‌کند

  • رشته‌ها: نام توابع مانند “strlen” یا “MyNamespace\func”
  • آرایه‌ها: [‘ClassName’, ‘method’] یا [$object, ‘method’]
  • کلوزرها (Closure) و توابع ناشناس
  • آبجکت‌های قابل‌فراخوانی (کلاس‌هایی که متد __invoke تعریف کرده‌اند)
  • رشته‌های با فرمت ‘Class::method’ برای متدهای استاتیک

مثال‌های پایه


// مثال 1: تابع استاندارد
var_dump(is_callable('strlen')); // true

// مثال 2: کلوزر
$fn = function($x){ return $x * 2; };
var_dump(is_callable($fn)); // true

// مثال 3: آرایه با شیء و متد
class A { public function foo(){} }
$a = new A();
var_dump(is_callable([$a, 'foo'])); // true

در این مثال‌ها نشان داده شد که توابع سطحی، کلوزرها و متدهای عمومی برای آبجکت‌ها به‌عنوان callable شناسایی می‌شوند.

تفاوت is_callable با function_exists و method_exists

تابعچه چیزی را بررسی می‌کندتفاوت مهم
is_callableقابلیت فراخوانی (شامل وجود و دسترسی)بررسی دسترسی و سازگاری فراخوانی؛ مناسب قبل از call_user_func
function_existsوجود تابع رشته‌ایتنها بررسی وجود، نه دسترسی یا سازگاری با context
method_existsوجود متد در کلاس/شیءوجود را بررسی می‌کند اما دسترسی (private/protected) را لحاظ نمی‌کند

دیدگاه دسترسی (visibility) و پارامتر syntax_only

is_callable هم وجود را بررسی می‌کند و هم دسترسی (visibility) را نسبت به کانتکست فعلی. اگر متد private/protected باشد و از کانتکست بیرون فراخوانی کنید، is_callable نتیجه false می‌دهد.


class B {
    private function secret(){}
}

$b = new B();
var_dump(method_exists($b, 'secret'));   // true
var_dump(is_callable([$b, 'secret']));  // false (از بیرون قابل فراخوانی نیست)

اگر بخواهید فقط سینتکس را بررسی کنید (بدون توجه به دسترسی و حتی بدون تلاش برای لود کلاس)، می‌توانید پارامتر دوم را true بگذارید:


var_dump(is_callable('B::secret', true)); // ممکن است true باشد (Syntax-only)

در حالت syntax_only، تابع تنها فرمت/قالب را بررسی می‌کند و نه قابلیت فراخوانی واقعی در کانتکست فعلی.

آیا is_callable باعث اتولود می‌شود؟

بله؛ هنگامی که شما عباراتی مانند [‘SomeClass’, ‘method’] یا ‘SomeClass::method’ را بررسی می‌کنید، PHP ممکن است برای بررسی وجود کلاس یا متد، autoload را فعال کند. بنابراین is_callable می‌تواند منجر به بارگذاری کلاس‌ها شود که در بعضی سناریوها قابل توجه است.

آبجکت‌های قابل‌فراخوانی (__invoke)


class Inv {
    public function __invoke($x){ return $x + 1; }
}
$i = new Inv();
var_dump(is_callable($i)); // true

وجود متد جادویی __invoke باعث می‌شود آبجکت مانند تابع رفتار کند. is_callable در این حالت true خواهد بود.

عملیات امن با call_user_func

قبل از فراخوانی دینامیک، توصیه می‌شود که is_callable بررسی شود تا از خطاهای زمان اجرا جلوگیری شود. مثال:


$cb = $_GET['cb'] ?? null;
if (is_callable($cb)) {
    call_user_func($cb, $data);
} else {
    // رفتار جایگزین یا لاگ
}

استفاده از is_callable باعث می‌شود که ابتدا از سالم بودن callback اطمینان پیدا کنید و از خطاهای توقف برنامه جلوگیری شود.

نکات و ترفندهای حرفه‌ای

  • برای بررسی صرف وجود متد بدون توجه به دسترسی از method_exists استفاده کنید.
  • اگر نمی‌خواهید autoload فعال شود، از syntax_only=true استفاده کنید اما دقت کنید که این حالت تضمین‌کننده قابلیت فراخوانی در کانتکست نیست.
  • برای بررسی کلوزر می‌توانید از instanceof Closure نیز استفاده کنید (اگر دقیقاً می‌خواهید Closure نه هر callable دیگر).
  • استفاده بیش از حد از فراخوانی‌های داینامیک می‌تواند کد را سخت‌خوان کند؛ اگر امکان دارد از وابستگی تزریق یا الگوهای استاتیک/استراتژی استفاده کنید.

مثال پیشرفته: ترکیب با نام کامل تابع (namespaced)


namespace MyApp;

function helper(){ return 'ok'; }

var_dump(is_callable('MyApp\helper')); // true اگر به درستی نام‌گذاری شود

در برنامه‌هایی که از namespace استفاده می‌کنند، مراقب باشید نام کامل تابع یا کلاس را به‌درستی بدهید یا از use و ارجاع مستقیم استفاده کنید.

خلاصه و جمع‌بندی

تابع is_callable ابزار قدرتمندی برای تشخیص قابلیت فراخوانی در PHP است که انواع مختلفی از callables (رشته‌ها، آرایه‌ها، کلوزر، آبجکت‌های invokable) را پشتیبانی می‌کند. دانستن تفاوت آن با method_exists/ function_exists و آگاهی از تاثیر پارامتر syntax_only و اتولود می‌تواند از خطاها و رفتارهای غیرمنتظره جلوگیری کند. در نهایت، قبل از فراخوانی دینامیک callback همواره is_callable را مدنظر داشته باشید تا کد ایمن‌تر و قابل‌پیش‌بینی‌تری داشته باشید.

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

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