PHP তে Namespace কি?

Namespace কি?

Namespace কি? এটা বুঝার জন্য আপনাদেরকে একটা গল্প বলব। মামনুন এবং মুহিব দুই ভাই , তাদের একজনের বয়স ৪ বছর অপরজনের বয়স ৩ বছর। তাদেরকে দেখতে একই রকমের খেলনা দিতে হয় । আর দেখতে হুবহু একই রকম না দিলে কোনটা বেশি সুন্দর বা কোনটা কম সুন্দর তা নিয়ে তারা সারাক্ষন ঝগড়া করে। আর তাই তাদের বাবা সবসময় হুবহু একই রকমের ২ টি খেলনা ই কেনেন। এদিকে একই রকম হওয়ায় তাদের বাবা আরেকটা সমস্যায় পড়লেন, একজন আরেকজনের খেলনা নিয়ে কাড়াকাড়ি করে আর জগড়া করে, কারণ কে কার খেলনা ববহার করছে বুঝতে পারে না। এই সমস্যা সমাধানের জন্য তাদের বাবা তাদের প্রত্যেকের খেলনায় একটি করে লেভেল লাগিয়ে দেয় । যেন প্রত্যেকে তার নিজেরটা চিনে নিতে পারে। এখন আর সমস্যা হয় না । বলা যায় Namespace এক ধরনের লেভেল বা স্টিকার। আবার বলা যায়, PHP তে Namespace ধারণা অনেকটা আমাদের কাছে একইনামের দুটি file কে দুটি ভিন্ন ফোল্ডারে রাখার মতো। অর্থাৎ, foo/info.txt এবং bar/info.txt path এর মতো। যদিও বাস্তবে namespace declare করার জন্য আমাদেরকে এইরকম folder তৈরী এর পরিবর্তে একটা ভার্চুয়াল path দিয়ে access করতে হবে।

মূলতঃ PHP তে Code করতে গেলে আমাদের class,interface, trait, function বা constant নাম নিয়ে প্রায়শই সমস্যায় পড়তে হয় । দেখা যায় কোনো code এ আমি যেই class, function বা constant এর নাম ব্যবহার করেছি সেই নামে আরেকটি লাইব্রেরীতে একই নামের class, interface, trait, function বা constant রয়েছে, অথবা আপনার টিমের অন্য কোনো মেম্বার একই নামের class, interface, trait, function বা constant তৈরী করে রেখেছে, যা পরে হয়তো আপনাকে ব্যবহার করতে হবে। ফলাফল – নাম নিয়ে কনফ্লিক্ট । এই সমস্যা থেকে সমাধান দিতে দিতে PHP 5.3 থেকে namespace সুবিধা যোগ করা হয়েছে।

Namespace দিয়ে প্রত্যেকটি Code Block কে আলাদা আলাদা নাম দেওয়া যায়, এবং পরে সেই নাম ধরে সেই কোডব্লকের কোড ব্যবহার করা যায়। যদি স্ক্রিপ্টের অন্য কোন কোডে এই একই নামের class, interface, trait, function বা constant থাকে তবুও PHP কোনো error দেখাবেনা। Namespace ধরে যখন কোনো class, interface, trait, function বা constant কে call করবেন তখন পিএইচপি ঠিক বুঝে নেবে যে এখন কোন্ কোডকে এক্সিকিউট করাতে হবে।

কিভাবে Php namespace ডিফাইন করবেন?

PHP তে namespace define করতে হলে প্রথমে namespace কিওয়ার্ড এবং তারপর namespace এর নাম দিতে হয় । namespace declare করা শুরু হতে হবে PHP ফাইলের একেবারে উপর থেকে অর্থাৎ অন্য যে কোন কোডের আগে । একমাত্র বিকল্প শুধু declare কিওয়ার্ডটিই শুধু namespace decleration আগে আসতে পারে । আপনি চাইলে একই ফাইলে একাধিক namespace declare করতে পারবেন। আবার ভিন্ন ভিন্ন file এ ভিন্ন ভিন্ন namespace ও declare করতে পারবেন। নিচে namespace ডিক্লেরেশনের এর syntax দেওয়া হলো:

Namespace without subNamespace

<?php
namespace namespaceName;
/*
Your PHP Code Goes hear
*/

Namespace With Sub Namespace

<?php
namespace subNamespace\namespaceName;
/*
Your PHP Code Goes hear
*/

কিভাবে namespace সহ constant, function এবং class কে কল করবেন?

namespace সহ constant, function এবং class কে call ভালো ভাবে বুঝার জন্য প্রথমে আমরা একই নামের constant, function এবং class দিয়ে দুটি ভিন্ন file তৈরী করব দুটি ভিন্ন namespace দিয়ে।

File: myproject1.php

<?php
// define this code in the MyProject1 namespace
namespace MyProject1;
const a="America";
function test(){
    echo "Hello I'm From MyProject1 Namespace";
}
class Test{
    public $b="Bangladesh";
    public function sayHello(){
        echo "Hello Bangladesh! From MyProject1 Namespace<br>";
    }
}

File: myproject2.php

<?php
// define this code in the MyProject2 namespace
namespace MyProject2;
const a="Africa";
function test(){
    echo "Hello I'm From MyProject2 Namespace";
}
class Test{
    public $b="Bharma";
    public function sayHello(){
        echo "Hello Bharma! From MyProject2 Namespace<br>";
    }
}

এখন আমরা myproject1.php এবং myproject2.php file দুটিকে project.php ফাইল এ include করব। এবং namespace সহ call করব।

<?php
include("myproject1.php");
include("myproject2.php");
 
 
echo "<h2>Namespace MyProject1</h2>";
echo MyProject1\a,"<br>";
echo MyProject1\test(),"<br>";
$obj=new MyProject1\Test;
echo $obj->b,"<br>";
$obj->sayHello();
 
 
echo "<h2>Namespace MyProject2</h2>";
echo MyProject2\a,"<br>";
echo MyProject2\test(),"<br>";
$obj=new MyProject2\Test;
echo $obj->b,"<br>";
$obj->sayHello();

একই File এ একাধিক namespace কিভাবে Define করবেন?

আপনি একই File এ একাধিক namespace কে দুইভাবে Define করতে পারেন। প্রথম নিয়মটি হচ্ছে সাধারণ namespace ঘোষণার মতোই , অর্থাৎ namespace keyword এর পর namespace name দিয়ে ঘোষণা করা। এবং প্রথম namespace ঘোষণার পর এর মধ্যে যত code লেখা হয়েছে তা পরবর্তী namespace ঘোষণার আগ পর্যন্ত সব কোডই প্রথম namespace এর অন্তর্গত । নিচের উদাহরণ দেখুন :

<?php
namespace MyProject1;
/*
1st Namespace Code Goes Here
*/
 
namespace MyProject2;
/*
2nd

এ ছাড়া আপনি কারলি ব্রাকেট ব্যবহার করেও একাধিক namespace কে একটি file এ define করতে পারেন। নিচের উদাহরণ দেখুন :

<?php
namespace MyProject1{
/*
1st Namespace Code Goes Here
*/
}
namespace MyProject2{
/*
2nd Namespace Code Goes Here
*/
}

উল্লেখ্য , আপনি চাইলে ব্র্যাকেট namespace এবং আনব্র্যাকেট namespace একসাথে ব্যবহার করতে পারবেন না। করলে PHP একটি fatal error দেখাবে। নিচের উদাহরণটি আপনাকে একটা fatal error দেখাবে।

<?php
 
// You cannot mix bracketed namespace declarations with unbracketed namespace declarations - will result in a Fatal error
 
namespace a;
 
echo "I belong to namespace a";
 
namespace b {
    echo "I'm from namespace b";
}

একাধিক namespace যুক্ত একই file এর namespace গুলোকে কিভাবে call করবেন?

একাধিক Php namespace যুক্ত একই file এর namespace গুলোকে call করতে হলে আপনাকে use keyword টি ব্যবহার করতে হবে। নিচের উদাহরণটি দেখুন :

<?php
// define MyProject1 namespace
namespace MyProject1;
const a="America";
function test(){
    echo "Hello I'm From MyProject1 Namespace";
}
class Test{
    public $b="Bangladesh";
    public function sayHello(){
        echo "Hello Bangladesh! From MyProject1 Namespace<br>";
    }
}
 
// define MyProject2 namespace
namespace MyProject2;
const a="Africa";
function test(){
    echo "Hello I'm From MyProject2 Namespace";
}
class Test{
    public $b="Bharma";
    public function sayHello(){
        echo "Hello Bharma! From MyProject2 Namespace<br>";
    }
}
 
echo "<h2>Namespace MyProject1 Use</h2>";
use MyProject1; // now start using MyProject1 Namespace
 
echo MyProject1\a,"<br>";
echo MyProject1\test(),"<br>";
$obj=new MyProject1\Test;
echo $obj->b,"<br>";
$obj->sayHello();
 
echo "<h2>Namespace MyProject2 Use</h2>";
use MyProject2; //now start using MyProject2 namespace
 
echo MyProject2\a,"<br>";
echo MyProject2\test(),"<br>";
$obj=new MyProject2\Test;
echo $obj->b,"<br>";
$obj->sayHello();

Namespace Importing

PHP তে use keyword দিয়ে namespace কে import করতে পারেন। আর এতে আপনাকে full namespace পাথটি লিখতে হবে না। শুধু সর্বশেষ namespace এর নামটি লিখলেই হবে। namespace import বুঝার জন্য আমরা দুটি ফাইল তৈরী করব।

file1.php

<?php
namespace User\Member\Profile;
class userData{
    private $user_id;
    private $user_name;
    public function __construct($id , $name) {
        $this->user_id = $id;
        $this->user_name = $name;
    }
    public function get_user(){
        return array('id'=>$this->user_id,'name'=> $this->user_name);
    }
}
 
function normalMethod(){
    echo "Yes I'm From Normal Method";
}
 
?>

এখন আমরা “namespace User\Member\Profile” কে file2.php তে use keyword দিয়ে import করব। আর এতে আমাদেরকে পুরো path ব্যবহার করে constant, function এবং class কে call করতে হবেনা। শুধু সর্বেশেষ পাথ Profile ব্যবহার করলেই হবে। নিচের উদাহরণ দেখুন :

file2.php

<?php
use User\Member\Profile;
include 'file1.php';
$usr = new Profile\userData('1', 'Ankur');
echo "<pre>";
print_r($usr->get_user());
Profile\normalMethod();
echo "</pre>";
?>

Output

Array
(
    [id] => 1
    [name] => Ankur
)
Yes I'm From Normal Method

তবে class এর বেলায় , আপনি যদি import করার সময় class name কে সর্বেশেষ path হিসেবে জুড়ে দেন। তাহলে ঐ class থেকে object করার সময় আপনাকে আর namespace এর name ব্যবহার করতে হবেনা। file2.php ফাইলকে নিচের মতো লিখুন:

<?php
use User\Member\Profile\userData;
include 'file1.php';
$usr = new userData('1', 'Ankur');
echo "<pre>";
print_r($usr->get_user());
echo "</pre>";
?>

লক্ষ্য করুন , আগেরবার আমাদেরকে সর্বেশেষ namespace কে দিয়েই class থেকে object করতে হয়েছে , আর এইবার আমাদেরকে সেটি অর্থাৎ সর্বশেষ namespace দিয়ে Class থেকে object তৈরী করতে হয়নি।

Namespace Aliasing

Aliasing অনেকটা windows এর shortcut link অথবা Linux এর symbolic Link এর মতো। অনেক দীর্ঘ namespace path কে short (ছোট) করার জন্য Aliasing ব্যবহার হয়। namespace কে aliasing করার জন্য as কীওয়ার্ড টি ব্যবহৃত হয়। নিচের উদাহরণ দেখুন :

file2.php

<?php
use User\Member\Profile as L;
include 'file1.php';
$usr = new L\userData('1', 'Ankur');
echo "<pre>";
print_r($usr->get_user());
L\normalMethod();
echo "</pre>";
 
?>

Namespace name definitions

Namespace এর ব্যবহারের ভিত্তিতে Namespace name তিন প্রকার :

  1. Unqualified Namespace
  2. Qualified Namespace
  3. Fully Qualified Namespace

Unqualified Namespace

যখন কোনো constant, function বা Method call করার সময় কোনো namespace ব্যবহার হয়না, তাকে Un-Qualified Namespace বলে। নিচে Unqualified Namespace এর উদাহরণ দেওয়া হলো:

<?php
namespace Foods\Oranges;
 
function eat()
{
  echo "eat Orange";
}
 
eat(); //call Unqualified namespace
?>

Qualified Namespace

যখন কোনো constant, function বা Method call করার সময় namespace পাথ গুলো at least ব্যবহার হয়, তাকে Qualified Namespace বলে। নিচে Qualified Namespace এর উদাহরণ দেওয়া হলো:

<?php
require ('apple.php');
require('orange.php');
 
use Foods\Apples;
Apples\eat(); //Qualified Namespace
echo "<br><br>";
use Foods\Oranges;
 Oranges\eat(); //Qualified Namespace

Fully Qualified Namespace

যখন কোনো constant, function বা Method call করার সময় namespace এর full path অথবা Full Path এর alias ব্যবহার হয়, তাকে Fully Qualified Namespace বলে। নিচে Fully Qualified Namespace এর উদাহরণ দেওয়া হলো:

<?php
require ('apple.php');
require('orange.php');
 
Foods\Apples\eat(); //Fully Qualified Namespace
echo "<br><br>";
use Foods\Oranges as o;
 o\eat(); // Fully Qualified Namespace
?>