آموزش اسکوپ متغیر در PHP و انواع محدوده دسترسی

اسکوپ یا محدودهٔ دسترسی متغیرها یک موضوع ساده ولی کاربردی است. در هنگام برنامه‌نویسی باید بدانیم هر متغیری که تعریف می‌کنیم در چه محدوده‌ای در دسترس است. این‌گونه تداخل‌های احتمالی و اشتباهات ناشی از تغییر آن‌ها یا دسترسی نادرست به متغیرها جلوگیری می‌شود. در این آموزش با اسکوپ PHP و ۳ نوع محدوده دسترسی با مثال آشنا می‌شویم.

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

محدوده دسترسی یا اسکوپ در PHP

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

  • اسکوپ محلی (Local): متغیرهایی که درون توابع تعریف می‌شوند فقط در همان تابع در دسترس هستند.
  • اسکوپ سراسری (Global): متغیرهایی که در خارج از بدنه توابع تعریف می‌شوند در همه جای برنامه (سرتاسر اسکریپت) در دسترس‌اند.
  • اسکوپ ایستا (Static): می‌توانیم برخی متغیرها را به‌گونه درون یک تابع تعریف کنیم که مقدارشان پس از خروج از تابع حفظ شود.

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

اسکوپ محلی یا Local

در هنگام تعریف تابع در PHP می‌توانیم یک یا چند متغیر را درون بدنه تابع تعریف کرده و استفاده کنیم. این متغیرها فقط در بدنهٔ همین تابع در دسترس هستند. بنابراین اگر بخواهیم به متغیرهایی که فقط در تابعی تعریف شده‌اند در بیرون از آن دسترسی داشته باشیم با خطا موجه خواهیم شد.

در قطعه کد زیر، متغیری به نام $name در تابع تعریف کرده و از آن استفاده کرده‌ایم. اگر تابع را فراخوانی کنم، این متغیر به‌درستی تعریف و استفاده می‌شود.

<?php
 function local_example(){
     $name = "Omid";
     echo $name;
 }
 
 local_example();   // Omid

اما اگر در خارج از بدنه‌ی این تابع، تلاش کنم تا متغیر $name را چاپ کنم، با خطایی مبنی بر اینکه چنین متغیری تعریف نشده است مواجه خواهم شد:

<?php
 function local_example(){
     $name = "Omid";
     echo $name;
 }
 
 local_example();
 echo $name;   // Error

وقتی تابع local_example() فراخوانی می‌شود، متغیرهایی که درون بدنه تابع تعریف شده‌اند (در این مثال، فقط متغیر $name) تعریف می‌شوند. می‌توانیم از آن‌ها در همان محدوده بدنه تابع (بین } تا {) استفاده کنیم. مثلاً مقدار آن را تغییر داده یا آن را چاپ کنیم. وقتی اجرای تابع به پایان می‌رسد، این نام متغیر نیز از حافظه کامپیوتر حذف می‌شود. انگاری که چنین متغیری تا به حال وجود نداشته است.

انواع خطای PHP: یادگیری ۴ نوع خطا + دلایل و راه‌حل

انواع خطای PHP: یادگیری ۴ نوع خطا + دلایل و راه‌حل

اسکوپ سراسری یا Global در PHP

در PHP می‌توانیم در بیرونی‌ترین اسکوپ هر فایل و خارج از توابع نیز متغیرهایی را تعریف و دستورهای موردنظرمان را اجرا کنیم. متغیرهایی که خارج از تابع یا کلاس PHP تعریف می‌شوند در تمام بخش‌های برنامه در دسترس هستند.

استفاده از متغیرهای سراسری زمانی مناسب است که می‌خواهیم مقدار خاصی را در کل برنامه در اختیار داشته باشیم. به‌طور کلی:

<?php
 $age = 25;
 
 echo $age;

کلمه کلیدی global

متغیرهایی که در اسکوپ سراسری PHP تعریف می‌شوند به‌طور مستقیم درون توابع در دسترس نیستند. برای دسترسی به آن‌ها باید از کلمه کلیدی global استفاده کرد.

به عبارت دیگر، هر گام بخواهیم درون یک تابع، از یک متغیر سراسری که خارج از آن تابع تعریف شده است استفاده کنیم، باید ابتدا آن را با کلمه global تعریف کرده و سپس استفاده کنیم.

در قطعه کد زیر، متغیر $age در اسکوپ سراسری و $name در اسکوپ محلی تعریف شده‌اند. همچنین در بدنه تابع تلاش کرده‌ایم به مقدار $age دسترسی داشته باشیم.

<?php
 $age = 25;
 
 function global_example(){
     $name = "Fatemeh";
     echo $age;
 }
 
 global_example();

اگر این کد را درون فایلی قرار داده و اجرا کنیم، با خطای زیر مواجه می‌شویم:

خطای دسترسی به متغیر اسکوپ سراسری بدون global
خطای دسترسی به متغیر اسکوپ سراسری بدون global
Warning: Undefined variable $age in /home/sabzdanesh/omid/run/scopes.php on line 6

انگاری که چنین متغیری تعریف نشده است. برای اینکه به متغیر $age از اسکوپ سراسری دسترسی پیدا کنیم، می‌بایست آن را با کلمه global در بدنه تابع تعریف کنیم.

<?php
 $age = 25;
 
 function global_example(){
     global $age;
     $name = "Fatemeh";
     echo $age;
 }
 
 global_example();   // 25

در حقیقت در کد بالا می‌گوییم که می‌خواهیم از متغیری به نام $age که در اسکوپ global قرار دارد در این محدوده استفاده کنیم. سپس آن نام و مقدارش در دسترس ما خواهند بود. در این مثال، با echo در php آن را چاپ کرده‌ام.

تغییر متغیر سراسری درون تابع

وقتی با کلمه global در PHP به یک متغیر سراسری دسترسی پیدا می‌کنیم، می‌توانیم مقدار آن را نیز به‌طور سراسری تغییر دهیم.

در قطعه کد زیر، مقدار متغیر را از درون تابع تغییر داده‌ام. هر گاه تابع اجرا شود، مقدار متغیر سراسری (global variable) نیز تغییر می‌کند.

<?php
 $age = 25;
 
 function change_global(){
     global $age;
     $age = 22;
 }
 
 echo $age;   // 25
 change_global();
 echo $age;   // 22

تعریف متغیر سراسری جدید با تابع

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

برای مثال، در کد زیر هیچ متغیر سراسری‌ای به نام $site نداریم. در تابع example() این متغیر را به‌صورت گلوبال تعریف کرده و آن را مقداردهی کرده‌ایم. پس از اجرای تابع، متغیر $site به‌صورت سراسری در خارج از بدنه تابع نیز در دسترس خواهد بود.

<?php
 function example(){
     global $site;
     $site = "SabzDanesh.com";
 }
 
 example();
 echo $site;   // SabzDanesh.com

آرایه سراسری GLOBAL

آرایه $GLOBALS یکی دیگر از روش‌های دسترسی به متغیرهای اسکوپ سراسری در PHP است. این آرایه تمام متغیرهای سراسری را به‌صورت key-value نگهداری می‌کند. اگر به آرایه‌ها آشنا نیستید، جلسه آرایه در PHP از دوره رایگان آموزش PHP را ببینید.

از این آرایه می‌توان در هر جایی از برنامه برای دسترسی به متغیرهای سراسری استفاده کرد. در قطعه کد زیر، مقدار متغیر $message را چاپ کرده‌ام:

<?php
 $message = "PHP Tutorial from SabzDnanesh.com";
 
 function use_global(){
     echo $GLOBALS['message'];
 }
 
 use_global();

کلمه کلیدی global برای دسترسی به متغیرهای موردنظر در اسکوپ تابع استفاده می‌شود؛ در حالی که $GLOBALS یک آرایه سوپرگلوبال است که در هر جایی از برنامه قابل استفاده است. (بیشتر بخوانید: متغیرهای سوپر گلوبال در PHP)

قواعد نام‌گذاری در برنامه‌نویسی: اصول نوشتن کد خوانا + ۶ روش معروف

قواعد نام‌گذاری در برنامه‌نویسی: اصول نوشتن کد خوانا + ۶ روش معروف

اسکوپ ایستا یا Static

اسکوپ استاتیک برای متغیرهایی به کار می‌رود که نیاز داریم مقدار آن‌ها پس از پایان اجرای تابع حفظ شود.

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

یک مثال خیلی ساده: فرض کنید تابعی داریم که در طول اجرای اسکریپت ممکن است چندین بار فراخوانی و اجرا شود. می‌خواهیم تعداد دفعات اجرای این تابع را بشماریم.

در گام اول، تابعی شبیه به زیر می‌نویسم:

<?php
 fucntion sbzd_counter(){
     $count = 0
     $count++;
     echo "Function Call Counter: {$count}";
 }

اگر این تابع را چندین بار (پشتِ سرِ هم یا در بخش‌های مختلف برنامه) اجرا کنیم، همیشه برای ما مقدار 1 را چاپ می‌کند!

چرا؟ چون در هر بار فراخوانی تابع، مقدار متغیر $count برابر صفر شده و سپس یکی افزایش می‌یابد. در نهایت همیشه مقدارش برابر با یک است.

<?php
 sbzd_counter();
 sbzd_counter();
 sbzd_counter();

 // Function Call Counter: 1

برای اینکه پس از هر بار فراخوانی، مقدار متغیر حفظ شود، از کلمه کلیدی static قبل از تعریف آن استفاده می‌کنیم.

در قطعه کد زیر، وقتی خط اول بدنه تابع اجرا می‌شود، اگر قبلاً متغیری به نام $count در اسکوپ تابع sbzd_counter() تعریف شده بود، از مقدار آن استفاده می‌شود، در غیر این‌صورت، مقدارش برابر صفر تعریف شده و سایر کدها اجرا می‌شوند.

<?php
 fucntion sbzd_counter(){
     static $count = 0
     $count++;
     echo "Function Call Counter: {$count}";
 }

 sbzd_counter();   // 1
 sbzd_counter();   // 2
 sbzd_counter();   // 3

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

جمع‌بندی آموزش اسکوپ PHP

اسکوپ متغیر (یا محدوده دسترسی) بسیار مهم است و مشخص می‌کند که هر متغیر، تابع و یا کلاس در چه بخش‌هایی از برنامه در دسترس هستند. scope در PHP مجموعه‌ای از قوانین و شرایط برای دسترسی به نام‌ها است.

در این آموزش سه اسکوپ اصلی پی‌اچ‌پی را با مثال بررسی کردیم. به‌طور خلاصه این سه اسکوپ عبارت‌اند از:

  • Local Scope: متغیرهایی که درون توابع تعریف می‌شوند و فقط درون همان تابع در دسترس هستند.
  • Global Scope: متغیرهایی که خارج از توابع و کلاس‌ها تعریف می‌شوند و در کل برنامه قابل استفاده‌اند. از کلمه global یا آرایه $GLOBALS برای دسترسی به مقادیر سراسری استفاده می‌کنیم.
  • Static Scope: متغیرهای محلی که مقدارشان پس از خروج از تابع حفظ شده و در اجرای بعدی تابع قابل استفاده هستند. از کلمه کلیدی static برای تعریف این نوع متغیرها درون تابع استفاده می‌کنیم.

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

امیدوارم این آموزش کاربردی و مورد استفاده شما بوده باشه. اگر سؤالی دارید، بخش دیدگاه‌ها برای شماست. 🙂