با سلام، در این مقاله سعی می کنیم تا با مبحث پایه ای "تعریف 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 my\stuff { namespace nested { class foo {} } } ?>
اگر بخواهید از namespace های تو در تو استفاده کنید باید آن را به شکل زیر پیاده کنید:
<?php namespace my\stuff\nested { class foo {} } ?>
در واقع این یک کد nest شده (تو در تو) نیست، بلکه یک نظام سلسله مراتبی از namespace ها است که در عمل همان کار nest کردن را انجام می دهد.
همچنین می توانید namespace های مختلفی را در یک فایل داشته باشید:
<?php namespace MyProject1; // PHP code for the MyProject1 namespace namespace MyProject2; // PHP code for the MyProject2 namespace // Alternative syntax namespace MyProject3 { // PHP code for the MyProject3 namespace } ?>
اما طبق گفته ی متخصصین و خود وب سایت PHP
این کار اصلا استاندارد نبوده، توصیه نمی شود و تا حد امکان باید از آن دوری کرد. سعی کنید هر namespace را در یک فایل جداگانه داشته باشید.
به نظر من برای نمایش این دستورات بهتر است از یک مثال واقعی استفاده کنیم. ابتدا یک فایل به نام lib1.php می سازیم و در آن یک تابع، یک کلاس و یک ثابت تعریف می کنم. نام namespace آن را نیز App\Lib1 می گذاریم؛ App مخفف Application (به معنی برنامه) و Lib مخفف Library (به معنی کتابخانه) است. محتوای این فایل به شکل زیر است:
<?php // application library 1 namespace App\Lib1; const MYCONST = 'App\Lib1\MYCONST'; function MyFunction() { return __FUNCTION__; } class MyClass { static function WhoAmI() { return __METHOD__; } } ?>
می توانیم برای فراخوانی یا صدا زدن این کد به شکل زیر عمل کنیم:
فایلی به نام myapp.php می سازیم که محتوای زیر را داشته باشد:
<?php header('Content-type: text/plain'); require_once('lib1.php'); echo \App\Lib1\MYCONST . "\n"; echo \App\Lib1\MyFunction() . "\n"; echo \App\Lib1\MyClass::WhoAmI() . "\n"; ?>
ما هیچ namespace ای را در فایل myapp.php تعریف نکرده ایم بنابراین کدهای آن در فضای global قرار گرفته اند. از طرفی دیگر، اگر MYCONST یا ()MyFunction یا MyClass را مستقیما صدا بزنید با یک خطا مواجه خواهید شد. چرا؟ به دلیل اینکه آن ها در namespace ای به آدرس App\Lib1 هستند اما کدهای ما در فضای global قرار دارند.
برای حل این مشکل (همانطور که در کد بالا می بینید) می توانیم از آدرس کامل App\Lib1\ استفاده کنیم. اگر فایل myapp.php را اجرا کنیم خروجی آن به این شکل خواهد بود:
App\Lib1\MYCONST App\Lib1\MyFunction App\Lib1\MyClass::WhoAmI
سوال: مگر قرار نبود یکی از مزایای استفاده از namespace ها این باشد که دیگر مجبور به استفاده از نام های طولانی و غیره نشویم؟ با این پسوند های پشت سر هم، نام ها باز هم طولانی می شوند. این که شد همان آش و همان کاسه!
پاسخ: باید توجه کنید فایده ی اصلی namespace ها این بود که نیازی به حفظ کردن نام توابع، کلاس ها و ... نداشته باشیم و دور شدن از نام های طولانی تنها یکی از فایده های namespace ها است. در عین حال حرف شما کاملا صحیح است! برای حل این مشکل در جلسه ی بعد با دستور use
آشنا می شویم و اما قبل از آن باید چند اصطلاح را توضیح بدهم تا جلسه ی بعد مشکلی نداشته باشیم:
نام ها در namespace ها به این شکل هستند:
نام های Fully qualified برای یک بار صدا زدن چیزی کفاف می کنند اما اگر بخواهیم چیزهای زیادی را صدا بزنیم، استفاده از آن ها بسیار سخت می شود و اینجاست که دستور use
وارد می شود.
در این مقاله سعی شد تا با مبحث پایه ای "تعریف namespace ها" آشنا شویم و نکات ریز مربوط به آن را بشکافیم. همچنین مقدمه ای بر بحث فراخوانی namespace ها ارائه شد که در قسمت بعد به طور مفصل به آن خواهیم پرداخت. امیدوارم از این قسمت لذت برده باشید.
برای دسترسی به تمام مقاله های پیرامون namespace ها در PHP لطفا روی این لینک کلیک کنید.
دیدگاههای شما (1 دیدگاه)
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.