
با سلام، در قسمت قبل به طور کامل با دستور use و مبحث aliasing آشنا شدیم. در این قسمت به سراغ مباحث متعددی می رویم که اولین آن ها بحث Name resolution (تجزیه یا ترجمه ی نام ها) است.
زمانی که کد شما کامپایل می شود بسیاری از نام هایی که ما به صورت قرار دادی تعیین کرده ایم (مثل alias ها) تبدیل به نام های اصلی می شوند، به این فرآیند Name resolution می گوییم.
برای درک کردن این بحث باید با مفاهیم Unqualified name (مانند ()MyFunction) و Qualified name (مانند ()Lib1MyFunction) و Fully qualified name مانند (()AppLib2MyFunction) آشنا باشید.
اگر با این موارد آشنایی ندارید لطفا این فصل را مطالعه کنید:
البته یک نوع نامگذاری دیگر نیز وجود دارد که به آن Relative name می گوییم؛ در این نام گذاری namespace نیز ذکر می شود. مثال: namespaceFooBar
چند مورد از قوانین اصلی name resolution به این شرح هستند:
as به C تبدیل کرده باشیم، فراخوانی CDE به ABCDE تبدیل می شود؛ یعنی به نام کامل و صحیحش برمیگردد.سعی می کنم این قوانین را که بیشتر از دو مورد بالا هستند در یک مثال توضیح دهم تا مطلب کاملا مفهوم شود. من تنها قوانین مهم و کاربردی را ذکر می کنم. می توانید دیگر قوانین را در صفحه ی رسمی مربوطه در سایت PHP ببینید.
تصور کنید در ابتدای فایل ما این کد وجود دارد:
<?php namespace A; use BD, CE as F; |
با توجه به کد بالا صدا زدن توابع به این شکل اجرا می شود:
foo(); foo(); myfoo(); F(); |
برای تابع ;()foo
برای تابع ;()foo
سعی می کند این تابع را در فضای گلوبال پیدا کند.
برای تابع ;()myfoo
سعی می کند تابع foo را در namespace به آدرس Amy پیدا کند.
برای تابع ;()F
این دستور همیشه نام namespace فعلی را به صورت یک رشته بر میگرداند:
<?php namespace AppLib1; echo __NAMESPACE__; // outputs: AppLib1 ?> |
همانطور که در خود کد توضیح دادیم عبارت “AppLib1” را به ما برمیگرداند.
نکته: اگر کدهای ما در فضای global باشند، یک رشته ی خالی به ما برگردانده می شود.
جدا از مزایایی که این دستور در هنگام دیباگ کردن سیستم به ما می دهد، می توان از آن برای تولید نام برای کلاس ها به صورت fully qualified و پویا استفاده کرد:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?php namespace AppLib1; class MyClass { public function WhoAmI() { retu __METHOD__; } } $c = __NAMESPACE__ . '\MyClass'; $m = new $c; echo $m->WhoAmI(); // outputs: AppLib1MyClass::WhoAmI ?> |
در اینجا منظور ما مفهوم namespace (به معنی فضای نام) نیست بلکه منظورمان یک دستور برنامه نویسی به نام namespace است! این دو را اشتباه نگیرید!
میتوانیم از دستور namespace برای اشاره ی مستقیم به یک namespace یا namespace های زیرین (nested شده ها و …) استفاده کنیم، بنابراین این دستور معادل همان دستور self در کلاس ها است.
اگر از دستور self در کلاس ها چیزی به خاطر ندارید به مقاله ی زیر مراجعه کنید:
مثال:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
<?php namespace AppLib1; class MyClass { public function WhoAmI() { retu __METHOD__; } } $m = new namespaceMyClass; echo $m->WhoAmI(); // outputs: AppLib1MyClass::WhoAmI ?> |
نکته: در خط دوم از کد بالا با کلمه ی namespace مواجه می شویم. این کلمه در اینجا برای تعریف کردن namespace ها است (همان چیزی که قبلا خوانده ایم). اما در خط های پایانی با دستور “new namespaceMyClass” مواجه می شویم. این همان دستوری است که به namespace فعلی اشاره دارد؛ اگر دقت کنید خروجی این کد نیز AppLib1 را به ما برگردانده است.
کلمه ی Autoload به معنی “بارگذاری خودکار” است. این ویژگی زبان PHP هیچ اختصاصی به namespace ها و غیر آن ندارد بلکه یک قابلیت همگانی در این زبان است. در حالت عادی و فضای global، توابع autoload به این شکل نوشته می شوند:
<?php $obj1 = new MyClass1(); // classes/MyClass1.php is auto-loaded $obj2 = new MyClass2(); // classes/MyClass2.php is auto-loaded // autoload function function __autoload($class_name) { require_once("classes/$class_name.php"); } ?> |
اما از PHP 5.3 به بعد شما می توانید یک نمونه از یک کلاس namespace شده را بسازید. در چنین حالتی نام namespace و کلاس، به صورت fully qualified، به تابع autoload__ تحویل داده می شود.
به طور مثال، در کد بالا مقدار class_name$ می تواند AppLib1MyClass باشد. شما می توانید تمام فایل های کلاس هایتان را در یک فولدر قرار دهید و namespace را از رشته ی برگردانده شده حذف کنید اما این کار توصیه نمی شود چرا که ممکن است باعث تصادم نام فایل ها شود (فایل هایی با نام یکسان و در یک محل).
از طرفی نظام سلسه مراتبی در فایل های کلاس های شما، می توانند دارای ساختاری مشابه با ساختار namespace ها باشند؛ به طور مثال میتوانید فایل MyClass.php را در آدرس classes/App/Lib1/ قرار دهید. به مثال زیر توجه کنید:
محتویات classesAppLib1MyClass.php به این شکل است:
<?php namespace AppLib1; class MyClass { public function WhoAmI() { retu __METHOD__; } } ?> |
حال، فایلی که در مسیر root (مسیر اصلی و ریشه ای) قرار دارد می تواند از کد زیر استفاده کند:
محتویات فایل myapp.php
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<?php use AppLib1MyClass as MC; $obj = new MC(); echo $obj->WhoAmI(); // autoload function function __autoload($class) { // به آدرس کامل فایل namespace تبدیل $class = 'classes' . str_replace('', '/', $class) . '.php'; require_once($class); } ?> |
نکات این کد:
()new MC در هنگام کامپایل شدن کد، تبدیل به ()new AppLib1MyClass می شود.در این قسمت با برخی مباحث جسته و گریخته از namespace ها آشنا شدیم که برخی از آن ها عبارت اند از name resolution (ترجمه یا تجزیه ی نام ها)، برخی کلمات کلیدی و دستورات مانند __NAMESPACE__ و مبحث autoload یا بارگذاری خودکار. امیدوارم از این قسمت لذت برده باشید.
برای دسترسی به تمام مقاله های پیرامون namespace ها در PHP لطفا روی این لینک کلیک کنید.
برچسب:
نویسنده: آتنا فراهانی