25
تشکر

namespaceها در PHP – بخش اول

namespaces in PHP

namespaces in PHP

یکی از ویژگی های مهمی که در 5.3 PHP اضافه شد، namespace بود. برنامه نویس های #C و جاوا با این ویژگی آشنا هستند.

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

علاوه بر موارد بالا شما را قادر می سازد تا از تمام مزایای autoloaderهایی که از جدیدترین استانداردها پیروی می کنند، که شامل اتولودر کامپوزر (Composer’s autoloader) هم می‌شود بهره ببرید.

در بخش اول به مفهوم و استفاده مقدماتی از namespace می‌پردازیم. در ادامه با ما همراه باشید …

مفهوم و مقدمات namespace

از مزایای namespace گفتیم، اما بیایید کمی دقیق‌تر به موضوع نگاه کنیم. چه زمانی به استفاده از آنها نیاز پیدا می کنیم؟

فضای پیش فرض، که شما در آن به نوشتن کد PHP می‌پردازید فضای سراسری یا global space نام دارد در این فضا شما اجازه تعریف دو کلاس با نام یکسان را ندارید و اگر این کار را انجام دهید با Fatal error روبرو میشوید. این موضوع برای نام تابع‌ها و ثابت‌ها نیز صدق می‌کند.

مثال مشابه برای روشن‌تر شدن موضوع، ساختار دایرکتوری‌ها در سیستم عامل‌ها است که امکان ندارد در یک مسیر واحد دو فایل foo.txt ایجاد کرد ولی برای گروه بندی فایل‌های مرتبط می‌توان دایرکتوری دیگری تعریف کرد و یک فایل foo.txt در یک دایرکتوی و فایل foo.txt دیگر را در دایرکتوری دیگر ایجاد کرد.

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

این احتمال وجود دارد که در کامپوننتی که میخواهید به پروژه اضافه کنید هم، نام چند تا از کلاسها با نام کلاس‌هایی که شما انتخاب کردید یکی باشد.

بنابراین پیامدهایی که بوجود می‌آید شامل موارد زیر هستند:

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

اما حالا براحتی می‌توانیم فضای نام یا namespace تعریف کنیم که با این کار به نوعی کلاس ها و تابع ها و ثابت‌هامون رو بخش بندی خواهیم کرد و دیگر خبری از تداخل نیست.

نکته: داخل یک namespace هم طبیعتا نمی توان کلاس‌ها یا تابع‌ها یا ثابت‌های هم نام تعریف کرد.

تعریف namespace

خط تعریف namespace باید اولین دستور در بالای کدهایتان و قبل از هر کد دیگری باشد. طبق استاندار PSR-2 یک خط خالی بعد از تعریف آن با بقیه کدها باید وجود داشته باشد.

تعریف Sub-namespaces

مانند فایل‌ها و دایرکتوری‌ها، میتوانید یک ساختار سلسله مراتبی و تو در تو برای کدهایتان درست کنید که با کاراکتر backslash (\)  از هم جدا میشوند.

مثال:

در مثال بالا ما دو namespace در یک فایل PHP تعریف کردیم که اینکار امکان پذیر است، اما هرگز توصیه نمی‌شود و برای هر فایل بایستی یک namespace تعریف کرد.

نکته: اگر در یک فایل بخواهید از کد namespace شده و کد namespace نشده (Global code) استفاده کنید. باید از ساختار براکت شده مثل زیر استفاده کنید:

فراخوانی کدهای Namespace شده

در فایل lib1.php، یک ثابت و یک تابع و یک کلاس تعریف کرده ایم و namespace آنرا App\Lib1 قرار داده ایم:

 

حال برای صدا زدن (call) کدهای بالا در فایل دیگر برای مثال فایل myapp.php یک روش استفاده از کدی مشابه کد زیر است:

بسیارخب، در کد myapp.php هیچ namespaceایی تعریف نشده، بنابراین در فضای global هستیم. از آنجاییکه MYCONST و MyFunction و MyClass در فضای نام App\Lib1 تعریف شده‌اند شما به طور مستقیم قادر به فراخوانی آنها نیستید و بایستی پیشوند \App\Lib1 را اضافه کنید تا یک نام fully-qualified داشته باشید. در نهایت خروجی زیر را خواهید داشت:

اما نام های fully-qualified خیلی طولانی هستند و مزیت زیادی نسبت به مثلا نامگذاری کلاس به صورت App-Lib1-MyClass ندارند. در بخش بعدی راجع به حل این موضوع که PHP چطور مشکل نام‌های namespaceها با import کردن آن‌ها و نام‌ گذاری‌های مستعار یا aliasing رفع میکند، صحبت میکنیم.

قبل از اینکه بخواهید استفاده از namespaceها را یاد بگیرید مهم است که بدانید PHP چطور تشخیص میدهد که کدام بخش از کد namespace شده درخواست شده است. یک قیاس ساده بین namespaces در PHP و فایل سیستم می‌تواند مثال خوبی باشد.

در فایل سیستم 3 راه برای دسترسی به یک فایل داریم:

  • نام فایل به صورت نسبی (Relative) باشد مانند foo.txt. که این مسیر به currentdirectory/foo.txt تبدیل می‌شود که currentdirectory همان دایرکتوری جاری است که در آن قرار داریم.
  • آدرس دهی نسبی مثل subdirectory/foo.txt که به currentdirectory/subdirectory/foo.txt تبدیل میشود.
  • آدرس دهی مطلق مانند main/foo.txt/ که تبدیل می‌شود به main/foo.txt/ (یعنی به خودش).

همین قاعده نیز برای عناصر namespace شده PHP کاربرد دارد. مثلا نام کلاس به سه روش زیر معرفی شده:

namespace

namespace

1. Unqualified name یا نام کلاس بدون پیشوند مثل ;()a = new foo$  یا ;()foo::staticmethod.

اگر namespace جاری currentnamespace باشد، تبدیل می‌شود به currentnamespace\foo اگر هم بدون namespace باشد تبدیل می شود به foo.

نکته: وقتی علامت \ را قبل از نام تابع یا ثابت قرار بدهیم تابع یا ثابت global هدف قرار میگیرد.

 

2. Qualified name یا نام کلاس همراه با پیشوند مثل ;()a = new subnamespace\foo$

یا ;()subnamespace\foo::staticmethod.

اگر namespace جاری currentnamespace باشد تبدیل به currentnamespace\subnamespace\foo می‌شود و اگر  بدون namespace باشد، subnamespace\foo اجرا می‌شود.

3. Fully qualified name یا نام پیشوند گذاری شده با پیشوند global \ مثل ;()new \currentnamespace\foo

یا ;()currentnamespace\foo::staticmethod\ همیشه تبدیل می‌شود به همان نام مشخص شده یعنی خودش currentnamespace\foo.

  • امیر می‌گه:

    ممنون از مطالب مفیدتون – خیلی جالبه مطالبتون کوتاه پر از نکته و …

  • harajiha.ir می‌گه:

    عالی بود.
    ممنون.

  • زمان می‌گه:

    ممنون از مطلب مفیدتون

  • آروین می‌گه:

    با سلام. بسیار عالی

  • فایبرکانکس می‌گه:

    واقعا این مطالب بخصوص برای کسانی که در شروع طراحی وب هستند بدرد میخوره. البته حرفه ای ها هم جای خود دارند و باعث مرور و یادآوری مباحث مهم طراحی وب میشه.

    • آرمان می‌گه:

      ممنون لطف دارید. هدف بنده هم از قراردادن این مطالب فقط آشنایی اولیه برای کسانی است که تاحالا آشنایی خاصی با این مقوله ها نداشتند. تا ان شاءالله بعد از این آشنایی اولیه خودشون برن و مستندات کامل رو با دقت بخونن. که حقیقتا هم مستندات php.net و پست های زبان اصلی، بسیار ساده و مفید نوشته شده اند و مطالب بنده هم ترجمه ای بیش نیست.

  • باربد جعفری می‌گه:

    ممنون از مطالب تخصصی که منتشر میکنید. این مطالب برای من که تازه در راه یادگیری طراحی وب هستم خیلی مفیده بازم ادامه بدید.

  • بعضی وقتا هست یه سری کلاس هایی ساخته شده که میشه توش حرکت کرد مثلا:
    string x=new system.application.me
    الان شی رو از کلاس me ساختیم
    بخوایم اینجوری کلاس های سلسله مراتبی بسازیم توی PHP امکانش هست؟

  • وحید می‌گه:

    تشکر به خاطر مطلب خوبتون♥

  • بهزاد عزیزان می‌گه:

    سلام
    ممنون آرمان جان . عالی بود خدا قوت


  • نظرات این مطلب بسته است.