با سلام، در این مقاله سعی می کنیم تا با مبحث پایه ای “تعریف namespace ها” آشنا شویم و همچنین کلیتی از فراخوانی namespace ها ارائه دهیم. در قسمت قبل توضیح دادیم که:
نحوه ی تعریف namespace ها
تمامی ثابت ها، توابع و کلاس های PHP به صورت پیش فرض در فضای global قرار می گیرند. این همان فضایی است که قبل از ساخته شدن namespace ها وجود داشت و نام ها در آن قرار می گرفتند. برای تعریف یک namespace باید از دستور namespace در بالای فایل PHP خود استفاده کنید. توجه کنید که این دستور باید اولین خط در فایل PHP شما باشد (البته به استثناء دستور declare) و اجازه ندارید قبل از آن هیچ whitespace (فضای خالی مانند اسپیس یا اینتر) یا کدهایی به غیر از کد PHP قرار دهید. مثال از کد صحیح:
|
|
<?php // define this code in the MyProject namespace namespace MyProject; |
هر کدی که پس از این کد نوشته شود مربوط به namespace ای به نام MyProject خواهد بود.
مثال از کد غلط:
|
|
<html> <?php namespace MyProject; // fatal error - namespace must be the first statement in the script ?> |
در این کد قبل از کدهای PHP از کدِ HTML استفاده شده است که باعث بروز خطا می شود.
نکته: ما نمی توانیم برای یک گروه از کدها دو یا تعداد بیشتری namespace داشته باشیم. همچنین نمی توانیم به شیوه ی عادی از namespace ها به صورت “تو در تو” (nested) استفاده کنیم.
کد زیر در PHP غلط است:
|
|
<?php namespace mystuff { namespace nested { class foo {} } } ?> |
اگر بخواهید از namespace های تو در تو استفاده کنید باید آن را به شکل زیر پیاده کنید:
|
|
<?php namespace mystuffnested { class foo {} } ?> |
در واقع این یک کد nest شده (تو در تو) نیست، بلکه یک نظام سلسله مراتبی از namespace ها است که در عمل همان کار nest کردن را انجام می دهد.
همچنین می توانید namespace های مختلفی را در یک فایل داشته باشید:
|
|
<?php namespace MyProject1; // PHP code for the MyProject1 namespace namespace MyProject2; // PHP code for the MyProject2 namespace // Alteative syntax namespace MyProject3 { // PHP code for the MyProject3 namespace } ?> |
اما طبق گفته ی متخصصین و خود وب سایت PHP این کار اصلا استاندارد نبوده، توصیه نمی شود و تا حد امکان باید از آن دوری کرد. سعی کنید هر namespace را در یک فایل جداگانه داشته باشید.
فراخوانی namespace ها
به نظر من برای نمایش این دستورات بهتر است از یک مثال واقعی استفاده کنیم. ابتدا یک فایل به نام lib1.php می سازیم و در آن یک تابع، یک کلاس و یک ثابت تعریف می کنم. نام namespace آن را نیز AppLib1 می گذاریم؛ App مخفف Application (به معنی برنامه) و Lib مخفف Library (به معنی کتابخانه) است. محتوای این فایل به شکل زیر است:
|
|
<?php // application library 1 namespace AppLib1; const MYCONST = 'AppLib1MYCONST'; function MyFunction() { retu __FUNCTION__; } class MyClass { static function WhoAmI() { retu __METHOD__; } } ?> |
می توانیم برای فراخوانی یا صدا زدن این کد به شکل زیر عمل کنیم:
فایلی به نام myapp.php می سازیم که محتوای زیر را داشته باشد:
|
|
<?php header('Content-type: text/plain'); require_once('lib1.php'); echo AppLib1MYCONST . "n"; echo AppLib1MyFunction() . "n"; echo AppLib1MyClass::WhoAmI() . "n"; ?> |
ما هیچ namespace ای را در فایل myapp.php تعریف نکرده ایم بنابراین کدهای آن در فضای global قرار گرفته اند. از طرفی دیگر، اگر MYCONST یا ()MyFunction یا MyClass را مستقیما صدا بزنید با یک خطا مواجه خواهید شد. چرا؟ به دلیل اینکه آن ها در namespace ای به آدرس AppLib1 هستند اما کدهای ما در فضای global قرار دارند.
برای حل این مشکل (همانطور که در کد بالا می بینید) می توانیم از آدرس کامل AppLib1 استفاده کنیم. اگر فایل myapp.php را اجرا کنیم خروجی آن به این شکل خواهد بود:
|
|
AppLib1MYCONST AppLib1MyFunction AppLib1MyClass::WhoAmI |
سوال: مگر قرار نبود یکی از مزایای استفاده از namespace ها این باشد که دیگر مجبور به استفاده از نام های طولانی و غیره نشویم؟ با این پسوند های پشت سر هم، نام ها باز هم طولانی می شوند. این که شد همان آش و همان کاسه!
پاسخ: باید توجه کنید فایده ی اصلی namespace ها این بود که نیازی به حفظ کردن نام توابع، کلاس ها و … نداشته باشیم و دور شدن از نام های طولانی تنها یکی از فایده های namespace ها است. در عین حال حرف شما کاملا صحیح است! برای حل این مشکل در جلسه ی بعد با دستور use آشنا می شویم و اما قبل از آن باید چند اصطلاح را توضیح بدهم تا جلسه ی بعد مشکلی نداشته باشیم:
نام ها در namespace ها به این شکل هستند:
- Unqualified name: این نوع نام ها، نام هایی هستند که جدا کننده ی namespace را ندارند. جدا کننده ی namespace همان علامت بک اسلش “” است. مثال: ()MyFunction یا Foo
- Qualified name: این نوع نام ها، نام هایی هستند که حداقل یک جداکننده ی namespace دارند. مثال: ()Lib1MyFunction یا FooBar
- Fully qualified name: این نوع نام ها، کامل ترین شکل نام هستند و قبل از هر چیز با یک جداکننده ی namespace شروع می شوند. مانند: ()AppLib2MyFunction یا FooBar و … . اگر قبلا با اندروید و ویندوز (مخصوصا در زمینه ی دیرکتوری ها) آشنا باشید می دانید که بک اسلش اولیه که قبل از همه چیز می آید به معنی root (در لغت به معنی “ریشه”) یا مبدا دستگاه است. این بک اسلش در namespace ها به معنی namespace اصلی و ریشه ای، یعنی همان فضای global، اشاره می کند.
نام های Fully qualified برای یک بار صدا زدن چیزی کفاف می کنند اما اگر بخواهیم چیزهای زیادی را صدا بزنیم، استفاده از آن ها بسیار سخت می شود و اینجاست که دستور use وارد می شود.
خلاصه ی مقاله
در این مقاله سعی شد تا با مبحث پایه ای “تعریف namespace ها” آشنا شویم و نکات ریز مربوط به آن را بشکافیم. همچنین مقدمه ای بر بحث فراخوانی namespace ها ارائه شد که در قسمت بعد به طور مفصل به آن خواهیم پرداخت. امیدوارم از این قسمت لذت برده باشید.
برای دسترسی به تمام مقاله های پیرامون namespace ها در PHP لطفا روی این لینک کلیک کنید.
کارت ویزیت لایه باز...
ما را در سایت کارت ویزیت لایه باز دنبال میکنید
برچسب:
نویسنده:
بازدید: 142
تاريخ: سه
شنبه
30 بهمن
1397 ساعت: 8:44