عکس پیش‌فرض نوشته

وقتی در سیستم کامپیوتر برنامه ای اجرا میشود، ممکن است در این برنامه متغیرهایی تعریف شده باشد؛ در هنگام اجرای برنامه این متغیرها در حافظه کامپیوتر ذخیره و نگهداری میشوند.

تمام خانه های حافظه برای آدرس دهی شماره گذاری شده اند. معمولاً این شماره گذاری ها به صورت اعداد Hex هستند.

وقتی متغیری در برنامه تعریف میشود، آدرس خانه حافظه به اسم متغیر داده میشود و مقدار عدد، رشته یا هر نوع دیگری که برای متغیر تعریف کرده بودیم در آن خانه حافظه ذخیره میشود. به این آدرس حافظه رفرنس (Reference) گفته میشود.

ارجاع با رفرنس به تابع در php

 

وقتی ما به این متغیر نیاز داریم، طی عملیات هایی که توسط CPU انجام میشود، آدرسی که به متغیر انتصاب داده شده است را خوانده و به آن خانه میرویم و اطلاعات ذخیره در آن را استفاده میکنیم.

برای مثال، فرض کنید تابعی ساده به شکل زیر داریم:

function plusOne($input){
    $input++;
    return $input;
}

 

در این تابع عددی را به عنوان ورودی گرفته، به آن یکی اضافه میکنیم و سپس به عنوان خروجی تابع آن را برمیگردانیم.

اگر بخواهیم این مقدار جدید را جایگزین مقدار قبلی متغیر کنیم باید از کدی مشابه کد زیر استفاده کرد:

 

$number = 3;
plusOne($number);           // $number = 3
$number = plusOne($number); //$number = 4

 

اما شاید همیشه این محاسبه و انتصاب دوباره زیاد جالب نباشد؛ مخصوصا زمانی که تابعی داشته باشیم که همیشه بخواهیم مقدار تغییر یافته (خروجی تابع) جایگزین مقدار متغیر فعلی شود.

همانطور که گفته شد، در مثال بالا، ما به متغیر $number مقداری را که نشان دهنده آدرس حافظه حاوی مقدار ذخیره شده (در اینجا عدد 3) هست، انتصاب میدهیم.

وقتی تابع plusOne با متغیر $number فراخوانی میشود، در اصل ما مقدار موجود در آن آدرس حافظه که عدد 3 هست را به تابع ارجاع میدهیم.

پس کاملاً مشخص هست که این مقدار فعلی که در $number ذخیره شده ربطی به مقدار ارسال شده به تابع ندارد!

 

حال فرض کنید به جای فراخوانی تابع با مقدار موجود در آدرس حافظه، خودِ آدرس حافظه را به تابع ارسال کنیم.

در این صورت اگر در داخل تابع، روی ورودی تغییراتی اعمال شود، این تغییرات در اصل روی آدرس حافظه اعمال میشود نه روی مقدار ارسالی به تابع …

ولی چگونه به تابع بفهمانیم که ما در حال ارسال رفرنس این متغیر یا شیء هستیم نه مقدار آن ؟!

 

انجام این کار در زبان برنامه نویسی PHP بسیار آسان است.

فقط کافی است در هنگام تعریف مقادیر ورودی تابع، قبل از تعریف اسم آنها علامت & را قرار دهیم.

واضح هست که اگر ما تغییرات را روی مقدار اصلی متغیر در حافظه اعمال کنیم، برای تابعی مثل plusOne نیازی به خروجی دادن نخواهیم داشت؛ زیرا تغییراتی که لازم بوده است در هنگام اجرای تابع اعمال و ذخیره شده است. پس داریم:

 

function plusOne(&$input){
    $input++;
}

 

و برای استفاده از این تابع همانند گذشته عمل میکنیم؛ با این تفاوت که دیگر نیازی به ذخیره مقدار خروجی تابع در متغیر نخواهیم داشت.

 

$number = 3
plusOne($number);    //$number = 4

 

در این نوع تعریف تابع که ورودی آن به صورت ارجاع با رفرنس هست، میتوان هر نوع ورودی را گرفت و هر نوع عملیاتی در آن انجام داد؛ دقیقا مشابه تابع های معمولی دیگر!

حتی این توابع میتوانند برای خود خروجی داشته باشند و مقداری را پس از اجرا بازگردانند.

 

برای مثال به تابع زیر توجه کنید:

 

function lowercase(&$string){
    $string = strtolower($string);
}

$site = 'WWW.SabzElco.IR';

lowercase($site);             //$site = 'www.sabzelco.ir'

 

این تابع پس از فراخوانی، رشته ای که به عنوان ورودی به آن داده شده است را به صورت lowercase یا تماماً حروف کوچک تبدیل میکند.

 

گاهی اوقات از این روش برای فیلتر کردن یا تغییر آرایه ای از داده ها استفاده میشود.

فرض کنید یک آرایه دارید که میخواهید مقدار عبارت موجود در ایندکس اولیه آن را تغییر دهید.

به راحتی میتوانید با کدی مشابه کد زیر این تغییرات را اعمال کنید:

 

function changeFirstArrayIndex(&$array){
    $array[0] = "Changed";
}

$testArray = array("Test 1", "Test 2", "Test 3");
changeFirstArrayIndex($testArray);

 

با روشی مشابه کد بالا به راحتی میتوانید داده های یک آرایه را بررسی کرده و تغییر دهید.

 

با استفاده از این روش میتوان از تعریف بعضی متغیرها به صورت سراسری (Global) چشم پوشی کرد.

توجه داشته باشید که وقتی داده ای را با رفرنس به تابع ارسال میکنیم، ممکن است داده اولیه (قبل از فراخوانی تابع) تغییر کند؛ پس دقت کنید که از فراخوانی تابع به صورت ارجاع با رفرنس (Call by Reference) در کجا استفاده میکنید.