Namespaces

Το namespace είναι ένα διακριτικό γνώρισμα που προσθέτουμε σε ένα αρχείο προκειμένου τα περιεχόμενά του (classes, functions, interfaces, constants) να ξεχωρίζουν από άλλα περιεχόμενα.

Οι λόγοι είναι δύο:

  • Αποφυγή συγκρούσεων ονομάτων (Name collisions)
  • Συντομότερη και κατανοητότερη γραφή.

Για να ξεχωρίσουμε τα περιεχόμενα ενός αρχείου από άλλα, χρησιμοποιούμε τη λέξη namespace και προσθέτουμε στην πρώτη γραμμή του αρχείου μια πρόταση όπως:

namespace root

Όπου root το όνομα ή το διακριτικό του namespace το οποίο επιλέγουμε εμείς.

Έστω η παρακάτω δομή φακέλων και αρχείων.

root
	classes
		person.php
	app.php

Και έστω το αρχείο person.php:

<?php
namespace market;

class Person {
    private $current_year;

    function __construct() {
        $this->current_year=date('Y'); 
    }

    function get_age($birth_year) {
        return $this->current_year - $birth_year;
    }
}

Και το αρχείο app.php.

<?php
include_once("classes/person.php");

$person = new market\Person();
echo $person->get_age(2000);

Δηλαδή, για να δημιουργήσουμε το αντικείμενο person, θα πρέπει να καλέσουμε την Person με το namespace και backslash πριν (market\). Σε διαφορετική περίπτωση θα προκύψει λάθος.

Εναλλακτικά μπορούμε να γράψουμε:

<?php
namespace market;
include_once("classes/person.php");

$person = new Person();
echo $person->get_age(2000);

Δηλαδή, προσθέτουμε στην κορυφή την πρόταση: namespace market; και έτσι δεν χρειάζεται το πρόθεμα: market\

Η λέξη use

Μία ακόμα εναλλακτική επιλογή είναι αυτή με τη χρήση της λέξης use.

Δηλαδή, δηλώνουμε με την εντολή use market\Person; ότι μπορούμε να χρησιμοποιήσουμε την κλάση Person χωρίς το πρόθεμα \market.

<?php
use market\Person;
include_once("classes/person.php");

$person = new Person();
echo $person->get_age(2000);

Η λέξη use ... as

Με τη use ... as μπορούμε να έχουμε μια σύντομη γραφή (alias) όταν το namespace είναι μακρύ.

Είναι δηλαδή πάλι μια εναλλακτική λύση στις παραπάνω που είδαμε. Έτσι έχουμε:

<?php
use market as M;
include_once("classes/person.php");

$person = new M\Person();
echo $person->get_age(2000);

Τα ονόματα namespace είναι case-insensitive. Άρα (MARKET = market) όπως και use market\person; = use market\Person;.

Ένα όνομα namespace δεν μπορεί να αρχίζει από αριθμό.

Συνηθίζεται να χρησιμοποιούμε τη διαδρομή (path) του αρχείου όπως: namespace classes/market ή namespace classes/person αν πρόκειται για αρχείο που περιέχει την κλάση Person αντί για κάποιο άλλο άσχετο όνομα όπως namespace hello.

Στο namespace και στο use ο διαχωριστικός χαρακτήρας είναι η κάθετος \ αντί της /.