Namespace Nedir?

Namespace(İsim Alanı) Nedir?

Kısaca; aynı isimde farklı sınıflar oluşturmak için kullandığımız küme adlarına namespace denir.

İsim alanlarından; sınıflar, fonksiyonlar ve sabitler etkilenir. Çoğunlukla sınıflara tanımlanır.

Örneğin: Hem satıcı hem alıcı bulunduran bir e-ticaret sistemi yazıyoruz. Böyle bir sistemde kullanıcıların, mantıken birbirinden farklı özelliklere sahip olması gerekir. 

lib/musteri/Kullanici.php

<?php
class Kullanici
{
  const TANIM = "Ben müşteri kullanıcısıyım";
}

lib/magaza/Kullanici.php

<?php
class Kullanici
{
  const TANIM = "Ben mağaza kullanıcısıyım";
}

index.php

<?php
require "lib/musteri/Kullanici.php";
require "lib/magaza/Kullanici.php";

İki ayrı sınıfı, aynı dosyada çalıştırmaya çalıştığımız anda PHP bize; "kafam karıştı, bir tane Kullanici sınıfı tanımla" diyecektir. İşte tam burada namespace devreye giriyor.

 

Namespace(İsim Alanı) nasıl tanımlanır?

İsim alanları, namespace anahtar kelimesi ile tanımlanır.

İsim alanını tüm kodlardan önce yani dosyanın başında tanımlamak gerekir. Bir tek declare anahtar kelimesi istisnadır.

Örnek:

<?php
namespace magaza;

class Kullanici
{
  const TANIM = "Ben mağaza kullanıcısıyım";
}

 lib/magaza/Kullanici.php

Bir diğer tanımlama şekli ise küme parantezlerine  alarak tanımlama.( namespace magaza{ /* ... */ }  ) Bu tanımlamayı genelde bir dosyada birden fazla namespace tanımlaması yaptığımızda kullanırız. Fakat tavsiye edilen bir yöntem olmadığı için bununla kafanızı karıştırmak istemiyorum.

Alt İsim Alanlarının Bildirilmesi

Dizinler ve dosyalardaki gibi PHP isim alanları arasında da bir hiyeraraşi belirtmek mümkündür. Kısaca bir isim alanı başka isim alanlarının altında tanımlanabilir:

<?php
namespace Randwin\Cekirdek\Grup;

class ListeAl { /* ... */ }
function karistir() { /* ... */  }

İsim alanlarının kullanımı

Öncelikle isim alanlarının dizin gibi davrandığını bir kez daha hatırlatayım.

İsim alanı tanımladığınız bir dosya üzerinden başka isim alanına erişecekseniz ve bu isim alanı bulunduğunuz dosyanın altında ise sadece alt isim alanını yazmanız yeterli. Eğer altında değil ise yani global de ise isim alanının başına "\" ekleyip tam nitelikli alan adını yazmalısınız.

İsim alanlarını tanıttığımıza göre, yazımın başında belirttiğim eticaret sistemi sınıflarını şimdi kullanabiliriz.

 

<?php

require "lib/musteri/Kullanici.php";
require "lib/magaza/Kullanici.php";

// Mağaza isim alanındaki Kullanici sınıfı içinde yer alan TANIM sabitini ekranda gösterir
echo Magaza\Kullanici::TANIM .'</br>';

// Musteri isim alanındaki Kullanici sınıfı içinde yer alan TANIM sabitini ekranda gösterir
echo \Musteri\Kullanici::TANIM;

// Musteri isim alanındaki Kullanici sınıfından bir nesne oluşturur.
$x = new Musteri\Kullanici;

index.php

Yukarıda bahsettiğim dizin konusuna bir de örnekle değineyim. index.php dosyamda bir namespace tanımlamadığım için isim alanı globaldir. Bu yüzden yukarıdaki tüm ifadeler çalışacaktır. Eğer index.php'de bir namespace tanımlasaydım; \Musteri\Kullanici::TANIM ifadesi dışındakiler çalışmayacaktı.

Örnek:

<?php
namespace Randwin;

require "lib/musteri/Kullanici.php";
require "lib/magaza/Kullanici.php";

// Randwin isim alanında Magaza ismini bulamayacağı için hata verecektir.
echo Magaza\Kullanici::TANIM .'</br>';

// Global tanımlandığı için Musteri isim alanındaki Kullanici sınıfı içinde yer alan TANIM sabitini ekranda gösterir
echo \Musteri\Kullanici::TANIM;

// Randwin isim alanında Musteri ismini bulamayacağı için hata verecektir.
$x = new Musteri\Kullanici;

Alias(Rumuz Kullanma)

İsim alanlarına takma isimler de verebilirsiniz. Bu hem kodunuzu okumayı kolaylaştırır hemde sürekli uzun isim alanlarını yazmak zorunda bırakmaz. 2 tür tanımlanır

  1. use Test\AltTest as AltTest  
  2. use Test\AltTest

"as" ifadesi kullandığı anda sağ tarafına yazılan takma ismi olur. Eğer "as" ifadesi kullanılmazsa en son isim alanı takma isim olur. Yani ikisinin de takma adı AltTest olur.

use kullanırken isim alanları tam nitelikli olmalıdır. Yani bulunduğu yerden sonrakiler değil nerde olursa olsun yolunu globalden almalısınız. Bu yüzden isim adlarının başına "\" separatörünü koymanız gereksizdir.

<?php
namespace Randwin;

require "lib/musteri/Kullanici.php";
require "lib/magaza/Kullanici.php";

use Magaza\Kullanici as Magaza;
use Musteri\Kullanici;

// Mağaza isim alanındaki Kullanici sınıfı içinde yer alan TANIM sabitini ekranda gösterir
echo Magaza::TANIM .'</br>';

// Musteri isim alanındaki Kullanici sınıfı içinde yer alan TANIM sabitini ekranda gösterir
echo Kullanici::TANIM;

// Musteri isim alanındaki Kullanici sınıfından bir nesne oluşturur.
$x = new Kullanici;

Konu ile ilgili sıkça sorulan soruları php.net sayfasında bulabilirsiniz. Bir de isim alanlarınızı PSR-4 standartlarında yazmaya bakın.

Yorumlarınızı eksik etmeyin. Kendinize iyi bakın :)


Kategoriler: PHP