PHP 8.2 - sprawdź co nowego!

Programowanie obiektowe > Lekcja 9

Przestrzenie nazw

To w zasadzie ostatnia kwestia, jaką chcę na ten moment omówić w sprawie podstaw obiektowości. Przestrzenie nazw umożliwiają zadeklarowanie wielu klas o takiej samej nazwie, wprowadzają też swego rodzaju porządek i grupowanie. W jakich sytuacjach to się może przydać? Przede wszystkim, gdy dodajemy do naszego kodu biblioteki innych programistów. Nie mamy wpływu na nazewnictwo w tym kodzie, a więc ryzyko powielenia nazwy klasy wzrasta. Poza tym, dzięki przestrzeniom nazw czytelność kodu jest lepsza - widzimy od razu, która klasa czego dotyczy.

Przestrzeń nazw musimy zadeklarować jako pierwszą instrukcję w pliku (no, prawie, mogą się wcześniej pojawić przykładowo komentarze czy declare()). Robimy to bardzo prosto, przy użyciu namespace.

<?php

namespace PHPDevs;

Możemy też zadeklarować podprzestrzeń, na przykład:

<?php

namespace PHPDevs\Course;

Oraz oczywiście kontynuować kolejne poziomy jeszcze „głębiej”. W momencie takiej deklaracji klasy, funkcje i stałe zdefiniowane przez const w tym pliku nie będą domyślnie widoczne w innej. Zobaczmy to w praktyce.

<?php // lesson.php

namespace PHPDevs\Course;

class Lesson
{

}
<?php // index.php

require_once 'lesson.php';

$lesson = new Lesson();

Efekt?

Fatal error: Uncaught Error: Class 'Lesson' not found in ...

Jak skorzystać z elementów znajdujących się w przestrzeni nazw PHPDevs poza nią? Musimy je zaimportować.

<?php // index.php

require_once 'lesson.php';

use PHPDevs\Course\Lesson;

$lesson = new Lesson();

W powyższym przykładzie przy użyciu use wskazujemy klasę do zaimportowania. Po tej operacji odwołujemy się do niej normalnie, po samej nazwie. Możemy też zrobić to bezpośrednio w momencie jej tworzenia, na przykład tak:

<?php

require_once 'lesson.php';

use Lesson;

$lesson = new PHPDevs\Course\Lesson();

Użycie use jest w większości przypadków po prostu czytelniejsze, tym bardziej, gdy użycie danej klasy powtarza się wiele razy. Podobnie sytuacja wygląda z funkcjami i stałymi, ale żeby je importować, dodajemy odpowiednio słowo function lub const.

<?php

use function PHPDevs\Course\getTitle;

getTitle();

// -----

PHPDevs\Course\getTitle();
<?php

use const PHPDevs\Course\NUMBER;

echo NUMBER;

// -----

echo PHPDevs\Course\NUMBER;

Jak zadeklarowana przestrzeń nazw może być tylko jedna, tak importować możemy dowolną ilość razy. Ważne jednak, aby nie powtórzyły się elementy o takiej samej nazwie. A jeśli zdarzyłoby się, że musimy powtórzyć, to i na to jest rozwiązanie: aliasy. Umożliwiają one nadanie jakby innej nazwy, poinformowanie, że tutaj to zaimportowane coś ma nazywać się o tak.

<?php

require_once 'lesson.php';

use PHPDevs\Course\Lesson as PHPLesson;

$lesson = new PHPLesson();
$lesson = new Lesson(); // error

Warto wiedzieć

Standard PSR-12 mówi, że zarówno za deklaracją przestrzeni nazw, jak i blokiem importów musi nastąpić linia przerwy.

Od php >=7 mamy także możliwość importu wielu klas, funkcji czy stałych w jednym use. Mam jednak wrażenie, że taki zapis jest mało powszechny. Większość i tak importuje jedną rzecz na linię, jak pokazywałem wyżej.

<?php

use PHPDevs\Course\{Lesson, Category};

$lesson = new Lesson();
$category = new Category();

Teoretycznie istnieje też możliwość deklaracji wielu przestrzeni nazw w jednym pliku. Zostało to opisane w dokumentacji. Teoretycznie, ponieważ w praktyce się tego nie spotyka, ale w razie czego warto wiedzieć.

Praktyka?

No właśnie, jak to wszystko wygląda w praktyce? Obecnie każdy poważny projekt korzysta z Composera i autoloadingu wg PSR-4, o którym powiemy sobie już w następnym rozdziale. Polega to w skrócie na tym, że umieszczamy klasy w odpowiednich folderach, tak, aby były zgodne z przestrzeniami nazw, dzięki czemu są automatycznie dodawane. Ręcznie dołączamy tylko jeden plik, reszta robi się sama :) Co za tym idzie, w jednym pliku deklaruje się jedną klasę i jedną przestrzeń nazw. To na spokojnie, zrobimy razem kolejny projekt, będzie to dokładnie widać.

Przestrzenie nazw są rzeczą, którą z pewnością trzeba znać w obecnym stanie programowania w PHP. Ich wykorzystanie wydaje się chyba dość łatwe i nie wymaga specjalnej nauki. Więcej czasu będziesz myślał jak dobrze aplikację podzielić albo jakie nazwy nadać, niż jak tu użyć samego mechanizmu.

Poprzednia lekcja

Udostępnij

  • Facebook
  • Twitter

Komentarze