💻 آخرین فرصت یادگیری برنامه‌نویسی با آفر ویژه قبل از افزایش قیمت در ۱۵ آذر ماه (🎁 به همراه یک هدیه ارزشمند )
۰ ثانیه
۰ دقیقه
۰ ساعت
۴ مهدی سراج 😎✌
منظور از closure چیست؟
محسن موحد حل شده توسط محسن موحد

سلام خدمت شما منتور عزیز، در دقیقه 19:50 استاد گفتن یک کلوژر میگیره! یعنی چی کلوژر؟

سلام،

کلوژر (Closure) یه نوع تابع توی برنامه‌نویسیه که می‌تونه به متغیرهای بیرون از خودش دسترسی داشته باشه، حتی اگه اون تابع از جایی که تعریف شده خارج بشه. یعنی یه تابع می‌تونه به متغیرهایی که توی محدوده (scope) خودش نیستن هم دسترسی داشته باشه.

برای اینکه راحت‌تر متوجه بشی، یه مثال ساده میارم:

function createGreeter($name) {
    return function() use ($name) {
        echo "سلام، $name!";
    };
}
$greeting = createGreeter("لقمان");
$greeting(); // سلام، لقمان!

اینجا createGreeter یه تابعیه که یه کلوژر (یه تابع دیگه) رو برمی‌گردونه. توی اون کلوژر از کلمه use استفاده کردیم تا به متغیر $name که بیرون از تابع داخلی تعریف شده، دسترسی داشته باشیم. حتی بعد از اینکه createGreeter تموم می‌شه، اون تابع داخلی هنوز به متغیر $name دسترسی داره.

مدرس وقتی میگه "یک کلوژر می‌گیره"، منظورش اینه که اون تابعی که به عنوان آرگومان به یه تابع دیگه می‌ده، می‌تونه به متغیرهای بیرون از خودش دسترسی داشته باشه. توی روترها و فریم‌ورک‌ها مثل لاراول، این خیلی رایجه و کمک می‌کنه کد تمیزتر و قابل‌فهم‌ بشه.

محسن موحد ۲۱ مرداد ۱۴۰۳، ۰۷:۴۳

سلام مجدد ممنون از توضیح خوبت، منتها چطور میشه که وقتی هر متدی غیر از add دارای برچسب closure object  میشه ولی مابقی متدهایی که تعریف شدن دارای این برچسب نیستن؟ 

App > Core > Routing > Route.php

class Route
{
    private static $routes = [];
    public static function add( $method, $uri, $action = null)
    {
        $methods= is_array($method) ? $method : [$method];
        self::$routes[] = ['mehtods' => $method, 'uri' => $uri, 'action' =>  $action];
    }
        public static function get($uri, $action = null)
    {
        return self::add('get', $uri, $action = null);
    }
        public static function routes()
    {
        return self::$routes;
    }
}

فراخوانی:

routes > web.php 

Route::get('/');
Route::add(['get', 'post'],'/', function(){
    echo 'welcome';
});

فعال کردن روتینگ :

index.php

use App\Core\Routing\Route;
var_dump(Route::routes());

0 => 
    array (size=3)
      'mehtods' => string 'get' (length=3)
      'uri' => string '/' (length=1)
      'action' => null
  1 => 
    array (size=3)
      'mehtods' => 
        array (size=2)
          0 => string 'get' (length=3)
          1 => string 'post' (length=4)
      'uri' => string '/' (length=1)
      'action' => 
        object(Closure)[39]
          virtual 'closure' '{closure}'

🔸 با اینکه متد get خودش دارای متد add در دل خودش هست نباید برپسب کلوژر بندازه تو اندیس 0 ام؟

🔸 دلیلش میتونه این باشه که خود متد add کلوژر متد get به حساب میاد؟

مهدی سراج 😎✌ ۲۱ مرداد ۱۴۰۳، ۱۵:۳۷

وقتی متد get رو صدا می‌زنی، این متد در واقع متد add رو با پارامترهای get, $uri و $action فراخوانی می‌کنه. یعنی وقتی Route::get('/'); رو فراخوانی می‌کنی، در نهایت همون add داره اجرا می‌شه.

اگر پارامتر action به صورت یک تابع ناشناس (که همون کلوژره و به نوعی anonymous هم محسوب میشه) به add ارسال بشه، درون آرایه‌ای که در self::$routes[] ذخیره می‌شه، این تابع به عنوان یک شیء کلوژر نمایش داده می‌شه.

برای مثال، وقتی این کد رو اجرا می‌کنی:

Route::add(['get', 'post'], '/', function(){
    echo 'welcome';
});

تو در واقع یه تابع ناشناس (کلوژر) به عنوان پارامتر سوم (action) به متد add می‌فرستی. این تابع به عنوان یک کلوژر ذخیره می‌شه و وقتی var_dump(Route::routes()); رو اجرا می‌کنی، می‌بینی که action به شکل object(Closure) توی خروجی نمایش داده می‌شه.

اما وقتی این کد رو اجرا می‌کنی:

Route::get('/');

هیچ تابعی به عنوان پارامتر action ارسال نمی‌شه (یعنی به صورت پیش‌فرض null هست). به همین دلیل، خروجی var_dump هیچ کلوژری رو نشون نمی‌ده.

پس نکته اینه که برچسب کلوژر (Closure object) فقط وقتی نشون داده می‌شه که تو به action یک تابع ناشناس یا همون کلوژر پاس داده باشی. در غیر این صورت، وقتی action به صورت null یا یک مقدار غیر تابع (مثل رشته یا عدد) باشه، هیچ کلوژری در خروجی نخواهی دید.

 

نکته: درباره تفاوت جزئی بین Closure و Anonymous

مثال 1: یک تابع Anonymous ساده

$greeting = function($name) {
    echo "سلام، $name!";
};
$greeting("علی"); // سلام، علی!

در اینجا، $greeting یک تابع ناشناس هست که به متغیری اختصاص داده شده و می‌تونه با پارامتر $name کار کنه.

 

مثال 2: یک Closure

$message = "سلام";
$greeting = function($name) use ($message) {
    echo "$message، $name!";
};
$greeting("محسن"); // سلام، محسن!

در اینجا، $greeting یک کلوژر هست، چون علاوه بر اینکه یه تابع ناشناس است، می‌تونه به متغیر $message که بیرون از خودش تعریف شده دسترسی داشته باشه.

 

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

بهترین پاسخ
محسن موحد ۲۲ مرداد ۱۴۰۳، ۱۳:۰۲

اقای موحد خیلیی خیلی سپاسگزارم 💖 متوجه شدم الان، دم شما بسی گرررررممممم

مهدی سراج 😎✌ ۲۲ مرداد ۱۴۰۳، ۱۳:۲۴