آموزش Namespaces در php

Image تحقیقات

آموزش Namespaces در php

با سلام و درود

دوستان امروز میریم سراغ فضای نامی در php یا همان  Namespaces.

در ورژن های قبلی php وقتی دو تا کتابخانه  php رو باهم تلفیق میکردیم.. احتمال اینکه نام بعضی از کلاس های نوشته شده در هر در کتابخانه یکسان باشه..یعنی هر کدوم از کتابخانه ها مثلا کلاسی به اسم User داستن..خب این نام مشترک مشکل آفرین می شد.

فضای نام‌گذاری (Namespace) این مشکل را حل می‌کند. همان‌طور که در راهنمای رسمی PHP توضیح داده شده است، فضای نام‌گذاری در PHP مانند ساختار دایرکتوری در سیستم‌عامل عمل می‌کند. همان‌طور که دو فایل با نام‌های یکسان در دو دایرکتوری می‌توانند وجود داشته باشند، دو کلاس PHP با نام‌های یکسان در دو فضای نام‌گذاری جداگونه می‌توانند وجود داشته باشند. به همین سادگی!

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

این قابلیت برای این طراحی شده که 2 مشکل نویسندگان کتابخانه ها و برنامه های کاربردی را حل کند:
1. جلوگیری از name collision ( جلوگیری از نامگذاری مشابه برای توابع یا کلاسها یی که ایجاد کرده اید با کلاسها و توابع داخلی php)
2. کوتاه کردن نامهای طولانی که برای کلاسها ایجاد کرده اید برای خوانایی بهتر کد.

یک روش توصیه شده در استفاده از فضای‌ نام‌گذاری (namespace )  در راهنمای PSR-0 موجود است، که ساختاری استاندارد برای فایل و کلاس ایجاد می‌کند.

در دی ماه ۱۳۹۲ PHP-FIG استانداردی جدید را به وجود آورد: PSR-4 که روزی جایگزین PSR-0 خواهد شد. هم‌اکنون هر دو قابل استفاده هستند با این تفاوت که PSR-4 به PHP 5.3 نیازمند است در حالی بسیاری پروژه‌های مبتنی بر PhP 5.2 از PSR-0 استفاده می‌کنند. اگر قصد استفاده از این استاندارد برای نرم‌افزار جدید خود را دارید بهتر است به PSR-4 نگاهی بیندازید.

فضای نامگذاری (namespace ) مربوط به classes, interfaces, functions وconstants می باشد.یعنی فقط این موارد را می توان داخل namespace ها ذخیره کرد .

حالا شروع می کنیم به مثال زدن :

اول یه مثال ساده از تعریف nameSpace :

 

مثال : این جور تعریف کردن namespace خطا می دهد زیرا باید حتما در خط اول بعد از تگ php باشد و قبل از ان چیزی نباشد.


<?php
namespace MyProject; // fatal error - namespace must be the first statement in the script

 

مثال : می توانیم در یک فایل php بیش از یک namespace داشته باشیم.البته یادمون باشه در یک بلاک کد نمیشه بیش از یک namespace داشت. کدهای زیر نحوه تعریف  چند namespace رو بیان می کنن.

<?php
namespace tamrin;
class Test
{

    function __construct()
    {

        echo 'Class 1';
    }
}

namespace tamrin1;
class Test2{
    
    function __construct()
    {
        echo 'Class 2';
    }
}

Namespace Aliases

aliases در namespace ها باعث میشه نام طولانی آن را به یک نام خلاصه  تغییر دهیم تا از این به بعد به جای اون نام طولانی ، از نام خلاصه شده استفاده کنیم :

<?php
use App\Lib1 as L;
use App\Lib2\MyClass as Obj;

header('Content-type: text/plain');
require_once('lib1.php');
require_once('lib2.php');

echo L\MYCONST . "\n";
echo L\MyFunction() . "\n";
echo L\MyClass::WhoAmI() . "\n";
echo Obj::WhoAmI() . "\n";

 

  •  در خط 2 : یک namespace تعریف کردیم و سپس با استفاده از as یک اسم جانشین به نام L برای انتخاب کردیم.
  • در خط  9 و 10 و 11 نیز با استفاده از اسم خلاصه شده ی L به توابع و ثبات ها و … اون کلاس دسترسی داریم.

 

 Autoloading Namespaced Classes

تابع  autoload __ به ما کمک میکنه تا کلاس هارو لود کنیم و دیگر لازم نباشد به صورت دستی کلاس هایی که لازم داریم رو include کنیم.

این تابع خودش به صورت اتوماتیک کلاس هایی که صدا زده میشن رو لود میکنه…ساختار تابع به صورت زیر است :

<?php
function __autoload($class_name) {
    include $class_name . '.php';
}

$obj  = new MyClass1();
$obj2 = new MyClass2(); 

 

  •  در خط 6 و 7 دو کلاس رو صدا زدیم.. این کلاس ها جهت شناسایی شدن نیاز دارن که Include شوند.
  • در خط 2 تابع autoload__ رو تعریف کردیم..یک پاراکتر ورودی میگیره که نام کلاس است و داخل تابع فایل کلاس رو include می کند..این تابع به صورت اتوماتیک موقع صدا زدن کلاس اجرا می شد.

مثال : در مثال بالا از تابع autoload__ استفاده کردیم ولی کلاس هامون namespace نداشت.در این مثال namespace هم به کلاس امون اضافه کنیم تا ببینیم چجوری میشه namespace را با استفاده از تابع autoload__  فراخوانی کرد.

ابتدا یه کلاس اینجاد می کنیم :

<?php
namespace App\Lib1;

class MyClass {
	public function WhoAmI() {
		return __METHOD__;
	}
}

 

حالا در کلاس دوم یعنی myapp.php میخواهیم از کلاس بالا استفاده کنیم و با استفاده از تابع autoload__ اون رو فراخوانی نماییم.

<?php
use App\Lib1\MyClass as MC;

$obj = new MC();
echo $obj->WhoAmI();

// autoload function
function __autoload($class) {

	// convert namespace to full file path
	$class = 'classes\' . str_replace('\\', '/', $class) . '.php';
	require_once($class);

}

 

  •  در خط شماره 2 namespace رو فراخونی کردیم و با استفاده اس as یک نام مستعار جهت راحتی بهش دادیم.
  • در خط 4 کلاس امون رو صدا زدیم.
  • نکته مهم در خط شماره 11 است که اومدیم نام فایل کلاس رو شبیه سازی کردیم تا بتونیم اون رو Include کنیم و بک اسلش هارو به اسلش تبدیل کردیم.

مثال : تو این مثال میخوام با استفاده از try – catch  بررسی کنیم می شود از کلاس مورد نظر شی ساخت یا خیر و اگر به هر دلیل نتوانست بسازد.یه Exception  دلخواه به کاربر نشان می دهیم.

<?php
function __autoload($name) {
    echo "Want to load $name.\n";
    throw new Exception("Unable to load $name.");
}

try {
    $obj = new NonLoadableClass();
} catch (Exception $e) {
    echo $e->getMessage(), "\n";
}

خروجی :

Want to load NonLoadableClass. Unable to load NonLoadableClass.

 

خب تا اینجا برای آشنایی با namespace ها کافیه به نظرم.

امیدوارم مفید باشه مثل همیشه.

شاد و سربلند باشید.