Jakie są przestrzenie nazw?

241

Co to są przestrzenie nazw PHP?

Jakie są ogólnie przestrzenie nazw?

Odpowiedź Laika z przykładem byłaby świetna.

Imran
źródło

Odpowiedzi:

573

Przestrzeń nazw działa dla funkcji i klas co zakres dla zmiennych. Pozwala na użycie tej samej funkcji lub nazwy klasy w różnych częściach tego samego programu bez powodowania kolizji nazw.

Mówiąc prościej, pomyśl o przestrzeni nazwisk jako nazwisku osoby . Jeśli są dwie osoby o imieniu „John”, możesz użyć ich nazwisk, aby je rozróżnić.

Scenariusz

Załóżmy, że piszesz aplikację korzystającą z funkcji o nazwie output(). Twoja output()funkcja pobiera cały kod HTML z twojej strony i wysyła go do użytkownika.

Później Twoja aplikacja staje się większa i chcesz dodać nowe funkcje. Dodajesz bibliotekę, która pozwala generować kanały RSS. Ta biblioteka korzysta również z funkcji o nazwie output()wyjściowej kanału końcowego.

Kiedy dzwonisz output(), skąd PHP wie, czy użyć twojej output()funkcji, czy funkcji biblioteki RSS output()? Tak nie jest. Chyba że używasz przestrzeni nazw.

Przykład

Jak rozwiązać dwie output()funkcje? Prosty. Trzymamy każdą output()funkcję we własnej przestrzeni nazw .

To by wyglądało mniej więcej tak:

namespace MyProject;

function output() {
    # Output HTML page
    echo 'HTML!';
}

namespace RSSLibrary;

function output(){
    # Output RSS feed
    echo 'RSS!';
}

Później, gdy chcemy korzystać z różnych funkcji, używamy:

\MyProject\output();
\RSSLibrary\output();

Lub możemy zadeklarować, że jesteśmy w jednej z przestrzeni nazw, a następnie możemy po prostu wywołać tę przestrzeń nazw output():

namespace MyProject;

output(); # Output HTML page
\RSSLibrary\output();

Brak przestrzeni nazw?

Gdybyśmy nie mieli przestrzeni nazw, musielibyśmy (potencjalnie) zmienić dużo kodu za każdym razem, gdy dodawaliśmy bibliotekę, lub wymyślaliśmy nużące prefiksy, aby nasze nazwy funkcji były unikalne. Dzięki przestrzeniom nazw możemy uniknąć problemów związanych z kolizjami nazw podczas mieszania kodu innej firmy z naszymi własnymi projektami.

cbednarski
źródło
Z jakiegoś powodu pomyślałem, że jeśli użyjesz przestrzeni nazw w pliku 1, nie będziesz musiał wymagać ani dołączać pliku do pliku 2. Testy jednostkowe wykazały, że tak nie jest.
Aaron Bell
1
@AaronBell Możesz sprawdzić automatyczne ładowanie .
cbednarski
21

Przestrzeń nazw pozwala na umieszczenie wiązki kodu pod nazwą i unikanie konfliktów nazw z klasami, funkcjami i stałymi.

Pozwala to żyć kodowi w tej przestrzeni nazw.

PHP wykorzystuje nieco kontrowersyjny znak \ do wyświetlania poziomów przestrzeni nazw. Ludzie wstali w ramiona, ponieważ jest również używany jako postać ucieczki.

Aby użyć przestrzeni nazw w PHP, użyj czegoś takiego na górze pliku.

namespace my\namespace;

Możesz znaleźć o wiele więcej informacji na temat oficjalnej dokumentacji PHP dla przestrzeni nazw .

alex
źródło
11

Ponieważ łatwiej jest poznać słowo kluczowe „use”, wiedząc o „przestrzeni nazw”, pozwól mi najpierw wyjaśnić przestrzeń nazw, patrząc na podstawowy projekt Laravel.

Istnieje ścieżka kontrolera o nazwie: Controller.php, która znajduje się na ścieżce: app / Http / Controllers z katalogu głównego projektu. Istnieje również inna klasa kontrolera o nazwie: Controller.php , ale ta znajduje się na ścieżce: vendor / laravel / framework / src / Illuminate / Routing z katalogu głównego projektu

Nie musisz jeszcze patrzeć na kod źródłowy, jeśli dopiero zaczynasz korzystać z php, ponieważ może Cię on pomylić, zamiast tego pozwól, że wyjaśnię ci tę część, na której nam zależy, i pomoże nam zrozumieć „przestrzeń nazw” i „używać” ”.

W rzeczywistości nasza pierwsza klasa kontrolera: app / Http / Controllers / Controller.php musi korzystać z dostawcy drugiej klasy kontrolera / laravel / framework / src / Illuminate / Routing / Controller.php . w rzeczywistości musi rozszerzyć tę klasę, aby mieć dostęp do jej zawartości do obsługi niektórych kluczowych funkcji routingu.

Jak więc klasa może rozszerzyć inną klasę o tej samej nazwie? class Controller extends Controller? to NIE zadziała, chyba że istnieje sposób na rozróżnienie tych dwóch klas i tam namespaceprzydaje się, a usesłowo kluczowe pomaga wypełnić misję, umożliwiając użycie; (klasy; metody; interfejsy i stałe), o tej samej nazwie, w tym samym zakresie.

jak to się dzieje w kodzie? bardzo prosty! jeśli spojrzymy nakod źródłowy app / Http / Controllers / Controller.php , możemy zobaczyć, że u góry obszaru nazw klasy jest zadeklarowany jako:,namespace App\Http\Controllerswięc w ten sposób nadajesz swojej klasie przestrzeń nazw, aby mogła się do niej odwoływać inne klasy teraz wygląda to tak samo jak ścieżka do tej klasy z katalogu głównego projektu, z niewielką różnicą, a to użycie „\” zamiast „/ (to samo co wiersz poleceń w Windows) , ale jest inna różnica i jest to aplikacja z kapitałem „A” w przestrzeni nazw kontra „aplikacja” z małymi literami „a” na ścieżce. Pamiętaj też, że w przestrzeni nazw rozróżniana jest wielkość liter.

Przestrzeń nazw jest więc odrębną koncepcją niż ścieżka, może podążać za strukturą ścieżki, jeśli to pomaga, ale nie musi to być dokładna ścieżka do klasy, metody, interfejsów lub stałych, na przykład spójrz na: vendor / laravel / framework /src/Illuminate/Routing/Controller.php kod źródłowy,

widzimy na górze klasy, że przestrzeń nazw jest zadeklarowana jako: Illuminate\Routing

teraz spójrzmy na usesłowo kluczowe „ ”, którego używamy, usesłowo kluczowe „ ”, aby uświadomić naszej klasie konkretną klasę lub funkcję, której chcemy użyć w naszej klasie

więc nie importujemy ani nie włączamy niczego , po prostu informujemy naszą klasę, że będziemy używać konkretnej klasy lub metody, odwołując się do ich przestrzeni nazw, spójrzmy na kod źródłowy app / Http / Controllers / Controller.php , jak widać z wiersza: „ use Illuminate\Routing\Controller as BaseController”, usesłowo kluczowe „ ”, po którym następuje przestrzeń nazw dla klasy docelowej (zwróć uwagę, że Illuminate \ Routing \ Controller.php i Illuminate \ Routing \ Controller „bez rozszerzenia .php” są wymienne)

możemy użyć assłowa kluczowego „ ” wraz ze słowem kluczowym „ use”, aby nadać określonej klasie, metodzie, interfejsom lub stałym alias, który pozwala app / Http / Controllers / Controller.php rozszerzyć Illuminate \ Routing \ Controller.php jako BaseController w wiersz: „ class Controller extends BaseController”.

Bahman.A
źródło
9

Istnieją techniki takie jak przestrzenie nazw w innych językach programowania (np. Pakiety w Javie). Służą do tego, aby mieć w projekcie wiele klas o tej samej nazwie.

Z dokumentacji php ( http://www.php.net/manual/en/language.namespaces.rationale.php ):

Jakie są przestrzenie nazw? W najszerszej definicji przestrzenie nazw są sposobem kapsułkowania elementów. W wielu miejscach można to postrzegać jako abstrakcyjną koncepcję. Na przykład w dowolnym systemie operacyjnym katalogi służą do grupowania powiązanych plików i działają jako przestrzeń nazw dla plików w nich zawartych. Jako konkretny przykład plik foo.txt może istnieć zarówno w katalogu / home / greg, jak i / home / other, ale dwie kopie pliku foo.txt nie mogą istnieć jednocześnie w tym samym katalogu. Ponadto, aby uzyskać dostęp do pliku foo.txt poza katalogiem / home / greg, musimy dodać nazwę katalogu do nazwy pliku za pomocą separatora katalogów, aby uzyskać /home/greg/foo.txt. Ta sama zasada dotyczy przestrzeni nazw w świecie programowania.

2ndkauboy
źródło
1
Porównywanie do Javy jest złym pomysłem. Java ma pakiety i istnieją klasy widoczności pakietów. Widoczność chronionych członków zależy również od pakietu, który uzyskuje do nich dostęp.
Artefacto
1
Nie są równe pakietom, ale mają ten sam pomysł.
2ndkauboy
Ponieważ pytanie dotyczy również ogólnie nazw przestrzeni, odpowiedź ma sens.
kiamlaluno
@kiam Łączy ich wspólny pomysł - nazwy kolidujących ze sobą klas. Nie podzielają idei widoczności.
Artefacto
@Artefacto: Kau-Boy nie powiedział, że przestrzenie nazw w obu językach są takie same.
kiamlaluno
4

Podobnie jak katalogi i pliki , przestrzeń nazw w PHP służy do grupowania klas , funkcji , interfejsów i stałych .

Przykład:

Filesystem      |   PHP Namespace
----------------|------------------
/Dir/File.txt   |  \Namespace\Class

Zapewnia sposób owijania elementów z globalnej przestrzeni i pozwala na użycie zwykłej nazwy elementu bez powodowania kolizji nazw w programie. Jest obsługiwany w PHP 5.3.0, PHP 7.

Istnieją jednak pewne ograniczenia w analogii między przestrzenią nazw PHP a systemem plików opartym na Uniksie:

                          | Filesystem            |        PHP Namespace
--------------------------|-----------------------|-------------------------
Cas sensitive             |       No              |        Yes                
--------------------------|-----------------------|-------------------------
Name with plain number    |       Yes             |        No
--------------------------|-----------------------|-------------------------
Path level                |       Yes             |        Yes   
--------------------------|-----------------------|-------------------------
Plain metacharacters name |       Yes             |        No        

Zasada obejmuje przestrzeń nazw w słowie programowym.


źródło
3

Przestrzeń nazw działa jak katalog. Wiesz, jak umieścić pliki w katalogu o takich samych nazwach, jak pliki w katalogu nadrzędnym (lub innym)? Przestrzeń nazw pozwala to zrobić w aplikacji dla zmiennych, funkcji i klas.

Jakiś czas temu w PHP pojawił się pewien trend dla ogromnych klas funkcji statycznych. Jedynym sposobem wywołania którejkolwiek z tych funkcji było poprzedzenie wywołania nazwą klasy. Była to prymitywna próba przestrzeni nazw, ale nie przyniosła wiele korzyści.

staticsan
źródło
2

Przestrzeń nazw pozwala zasadniczo umieścić kod w kontenerze. Zapobiegnie to problemom z dwiema funkcjami (a także klasami i zmiennymi) o tej samej nazwie.

Są one przydatne podczas pracy, gdy większe aplikacje zapobiegają problemom z fragmentami kodu o tej samej nazwie.

Załóżmy na przykład, że chcieliśmy dwóch funkcji o nazwie „TheMessage”. Obie drukowałyby (echo) różne wiadomości. Zwykle spowodowałoby to błąd składniowy, ponieważ nie można mieć dwóch funkcji o tej samej nazwie.

Aby to naprawić, możesz umieścić te funkcje w osobnych przestrzeniach nazw. Umożliwiłoby to korzystanie z obu funkcji bez żadnych błędów.

Alexander
źródło
2

Przestrzeń nazw przypomina pakowanie wielu rzeczy w jedną paczkę. Wyobraź sobie przestrzeń nazw jako szufladę, w której możesz umieścić różne rzeczy: ołówek, linijkę, kartkę papieru i tak dalej. Aby uniknąć wzajemnego używania przedmiotów, decydujesz się na etykietowanie szuflad, aby było jasne, do kogo należy.

Mamun Sabuj
źródło
0

Przestrzeń nazw służy do zamykania grupy kodów, dzięki czemu można ich używać w różnych miejscach bez konfliktów nazw. Pomyśl o tym jako o metodzie jQuery bez konfliktu, a zrozumiesz to lepiej.

Emmanuel David
źródło
Co rozumiesz przez „jQuery brak metody konfliktu”? Jak to się ma do PHP?
Nico Haase
0

Przestrzeń nazw to prosty system do kontrolowania nazw w programie.
Zapewnia to, że nazwy są unikalne i nie doprowadzą do żadnego konfliktu.

humaid
źródło
O jakich „imionach” mówisz?
Nico Haase
0

Możesz użyć przestrzeni nazw, aby uniknąć kolizji nazw między tworzonym kodem a wewnętrznymi klasami / funkcjami / stałymi PHP lub klasami / funkcjami / stałymi innych firm. Przestrzenie nazw mają również możliwość aliasu (lub skrócenia) Extra_Long_Names zaprojektowanego w celu zmniejszenia pierwszego problemu, poprawiając czytelność kodu źródłowego.

Jak wszyscy wiemy, przestrzenie nazw i cechy nie są nowe w PHP, ale wciąż wielu programistów php nie używa tych wielkich pojęć ze względu na ich złożoność. Więc w tym poście. Spróbuję je wyczyścić przykładami. Co to jest przestrzeń nazw i cechy?

Jak możesz zaimplementować je w kodzie, aby kod był wielokrotnego użytku i rozszerzalny?

Korzyści z przestrzeni nazw

Możesz użyć przestrzeni nazw, aby uniknąć kolizji nazw między tworzonym kodem a wewnętrznymi klasami / funkcjami / stałymi PHP lub klasami / funkcjami / stałymi innych firm.

Przestrzenie nazw mają również możliwość aliasu (lub skrócenia) Extra_Long_Names zaprojektowanego w celu zmniejszenia pierwszego problemu, poprawiając czytelność kodu źródłowego. Rozumiem przestrzenie nazw na przykładzie. utwórz nazwę folderu „php_oops” w htdocs (xampp) lub www (xwamp) utwórz nowy folder w katalogu głównym o nazwie „przestrzenie nazw”, a następnie utwórz plik index.php w folderze przestrzeni nazw.

<?php
// FilePath:- namespaces/index.php

// let's say, we have two classes in index,
// here, these two classes have global space
class A 
{ 
   function __construct()
   { 
      echo "I am at Global space, Class A";
   }
}
class B
{
   function __construct()
   {
      echo "I am at Global space, Class B";
   }
}
// now create an object of class and 
$object = new A; // unqualified class name
echo "<br/>";
$object = new \B; // fully qualified class name
// output: 
I am at Global space, Class A
I am at Global space, Class B

Odniesienie- https://medium.com/@akgarg007/php-laravel-namespaces-and-traits-01-9540fe2969cb

Ashwani Garg
źródło
1
Zachowaj ostrożność przy tworzeniu linków do własnych treści na różnych stronach, nie chcesz być spamerem . Powinieneś dołączyć tutaj większość treści i używać linku wyłącznie jako odniesienia.
Dharman