Was sind Namespaces?

241

Was sind PHP-Namespaces?

Was sind Namespaces im Allgemeinen?

Eine Laienantwort mit einem Beispiel wäre großartig.

Imran
quelle

Antworten:

573

Der Namensraum funktioniert für Funktionen und Klassen genauso wie der Gültigkeitsbereich für Variablen. Sie können denselben Funktions- oder Klassennamen in verschiedenen Teilen desselben Programms verwenden, ohne eine Namenskollision zu verursachen.

Stellen Sie sich einen Namespace in einfachen Worten als den Nachnamen einer Person vor . Wenn es zwei Personen mit dem Namen "John" gibt, können Sie ihre Nachnamen verwenden, um sie voneinander zu unterscheiden.

Das Szenario

Angenommen, Sie schreiben eine Anwendung, die eine Funktion mit dem Namen verwendet output(). Ihre output()Funktion nimmt den gesamten HTML-Code auf Ihrer Seite und sendet ihn an den Benutzer.

Später wird Ihre Anwendung größer und Sie möchten neue Funktionen hinzufügen. Sie fügen eine Bibliothek hinzu, mit der Sie RSS-Feeds generieren können. Diese Bibliothek verwendet auch eine Funktion namens, output()um den endgültigen Feed auszugeben.

output()Woher weiß PHP beim Aufrufen , ob Ihre output()Funktion oder die Funktion der RSS-Bibliothek verwendet output()werden soll? Das tut es nicht. Es sei denn, Sie verwenden Namespaces.

Beispiel

Wie lösen wir zwei output()Funktionen? Einfach. Wir stecken jede output()Funktion in einen eigenen Namespace .

Das würde ungefähr so ​​aussehen:

namespace MyProject;

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

namespace RSSLibrary;

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

Wenn wir später die verschiedenen Funktionen verwenden möchten, verwenden wir:

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

Oder wir können erklären, dass wir uns in einem der Namespaces befinden, und dann können wir einfach diesen Namespace aufrufen output():

namespace MyProject;

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

Keine Namespaces?

Wenn wir keine Namespaces hätten, müssten wir (möglicherweise) jedes Mal, wenn wir eine Bibliothek hinzufügen, viel Code ändern oder uns mühsame Präfixe einfallen lassen, um unsere Funktionsnamen eindeutig zu machen. Mit Namespaces können wir die Kopfschmerzen beim Benennen von Kollisionen vermeiden, wenn wir Code von Drittanbietern mit unseren eigenen Projekten mischen.

cbednarski
quelle
Aus irgendeinem Grund dachte ich, wenn Sie Namespaces in Datei1 verwenden würden, müssten Sie die Datei nicht benötigen oder in Datei2 aufnehmen. Unit-Tests haben gezeigt, dass dies nicht der Fall ist.
Aaron Bell
1
@AaronBell Vielleicht möchten Sie auschecken das automatische Laden .
Cbednarski
21

Mit einem Namespace können Sie eine Reihe von Codes unter einem Namen platzieren und haben keine Namenskonflikte mit Klassen, Funktionen und Konstanten.

Es ermöglicht Ihrem Code, in diesem Namespace zu leben .

PHP verwendet das etwas kontroverse Zeichen \ , um Namespace-Ebenen anzuzeigen. Die Leute sind in den Armen aufgestanden, weil es auch als Fluchtcharakter benutzt wird.

Um den Namespace in PHP zu verwenden, verwenden Sie so etwas oben in Ihrer Datei.

namespace my\namespace;

Weitere Informationen finden Sie in der offiziellen PHP-Dokumentation für Namespaces .

Alex
quelle
11

Da es einfacher ist, das Schlüsselwort "Verwendung" zu kennen, wenn Sie sich mit "Namespace" auskennen, lassen Sie mich zunächst den Namespace anhand eines grundlegenden Laravel-Projekts erläutern.

Es gibt eine Controller-Klasse mit dem Namen: Controller.php im Pfad: app / Http / Controllers aus dem Stammverzeichnis des Projekts. Es gibt auch eine andere Controller-Klasse mit dem Namen: Controller.php , aber diese befindet sich im Pfad: vendor / laravel / framework / src / Illuminate / Routing aus dem Stammverzeichnis des Projekts

Sie müssen sich den Quellcode noch nicht ansehen, wenn Sie neu in PHP sind, da er Sie verwirren kann. Lassen Sie mich Ihnen stattdessen den Teil erklären, der uns wichtig ist und der uns hilft, „Namespace“ und „Verwendung“ zu verstehen ”.

Tatsächlich muss unsere erste Controller-Klasse: app / Http / Controllers / Controller.php den Hersteller der zweiten Controller-Klasse / laravel / framework / src / Illuminate / Routing / Controller.php verwenden . Diese Klasse muss tatsächlich erweitert werden, um Zugriff auf ihren Inhalt für die Verwaltung einiger wichtiger Routing-Funktionen zu erhalten.

Wie kann eine Klasse eine andere Klasse mit demselben Namen erweitern? class Controller extends Controller? Dies wird NICHT funktionieren, es sei denn , es gibt eine Möglichkeit, diese beiden Klassen zu unterscheiden. Hier ist es namespacepraktisch, und das useSchlüsselwort hilft dabei, die Mission von zu erfüllen und die Verwendung von zu ermöglichen. (Klassen; Methoden; Schnittstellen und Konstanten) mit demselben Namen im selben Bereich.

Wie wird es nun im Code gemacht? sehr einfach! Wenn wir uns denQuellcode von app / Http / Controllers / Controller.php ansehen, sehen wir oben im Klassennamensraum, der als: deklariertnamespace App\Http\Controllersist. Auf diese Weise geben Sie Ihrer Klasse einen Namespace, damit sie jetzt von anderen Klassen referenziert werden kann Dies sieht genauso aus wie der Pfad zu dieser Klasse aus dem Stammverzeichnis des Projekts, mit wenig Unterschied und das ist die Verwendung von "\" anstelle von "/" (wie die Eingabeaufforderung in Windows) , aber es gibt einen anderen Unterschied und das ist die App mit Großbuchstaben 'A' im Namespace versus 'App' mit Kleinbuchstaben 'a' im Pfad. Beachten Sie auch, dass im Namespace zwischen Groß- und Kleinschreibung unterschieden wird.

Der Namespace ist also ein anderes Konzept als der Pfad. Er kann der Pfadstruktur folgen, wenn dies hilfreich ist. Es muss sich jedoch nicht um einen genauen Pfad zur Klasse, Methode, Schnittstellen oder Konstanten handeln. Schauen Sie sich beispielsweise Folgendes an: vendor / laravel / framework /src/Illuminate/Routing/Controller.php Quellcode,

Wir sehen oben in der Klasse, dass der Namespace wie folgt deklariert ist: Illuminate\Routing

Schauen usewir uns nun das Schlüsselwort " " an, das wir verwenden, das useSchlüsselwort " ", um unsere Klasse auf eine bestimmte Klasse oder Funktion aufmerksam zu machen, die wir in unserer Klasse verwenden möchten

Wir importieren oder schließen also nichts ein, sondern lassen unsere Klasse nur wissen, dass wir eine bestimmte Klasse oder Methode verwenden werden, indem wir sie anhand ihres Namespace referenzieren. Schauen wir uns den Quellcode von app / Http / Controllers / Controller.php als an Sie können aus der Zeile ersehen : " use Illuminate\Routing\Controller as BaseController", das useSchlüsselwort " " gefolgt von einem Namespace für die Zielklasse (beachten Sie, dass Illuminate \ Routing \ Controller.php und Illuminate \ Routing \ Controller "ohne .php-Erweiterung" austauschbar sind).

Wir können das asSchlüsselwort " " zusammen mit dem useSchlüsselwort " " verwenden, um einer bestimmten Klasse, Methode, Schnittstellen oder Konstanten einen Alias ​​zu geben, der es app / Http / Controllers / Controller.php ermöglicht, Illuminate \ Routing \ Controller.php als BaseController im zu erweitern Zeile: " class Controller extends BaseController".

Bahman.A
quelle
9

Es gibt Techniken wie Namespaces in anderen Programmiersprachen (wie Pakete in Java). Sie werden verwendet, um in einem Projekt mehrere gleichnamige Klassen zu haben.

Aus der PHP-Dokumentation ( http://www.php.net/manual/en/language.namespaces.rationale.php ):

Was sind Namespaces? In der weitesten Definition sind Namespaces eine Möglichkeit, Elemente zu kapseln. Dies kann vielerorts als abstraktes Konzept angesehen werden. Beispielsweise dienen Verzeichnisse in jedem Betriebssystem dazu, verwandte Dateien zu gruppieren und als Namespace für die darin enthaltenen Dateien zu fungieren. Als konkretes Beispiel kann die Datei foo.txt sowohl im Verzeichnis / home / greg als auch in / home / other vorhanden sein, aber zwei Kopien von foo.txt können nicht gleichzeitig im selben Verzeichnis vorhanden sein. Um auf die Datei foo.txt außerhalb des Verzeichnisses / home / greg zuzugreifen, müssen wir den Verzeichnisnamen mithilfe des Verzeichnis-Trennzeichens dem Dateinamen voranstellen, um /home/greg/foo.txt abzurufen. Das gleiche Prinzip gilt auch für Namespaces in der Programmierwelt.

2ndkauboy
quelle
1
Ein Vergleich mit Java ist eine schlechte Idee. Java hat Pakete und es gibt Paketsichtbarkeitsklassen. Die Sichtbarkeit geschützter Mitglieder hängt auch vom Paket ab, das darauf zugreift.
Artefacto
1
Sie sind nicht gleich Pakete, aber sie teilen die gleiche Idee.
Kauboy
Da in der Frage auch gefragt wird, welche Namespaces im Allgemeinen vorhanden sind, ist die Antwort sinnvoll.
Kiamlaluno
@kiam Sie teilen eine Idee - nicht kollidierende Klassennamen. Sie teilen nicht die Idee der Sichtbarkeit.
Artefacto
@Artefacto: Kau-Boy hat nicht gesagt, dass die Namespaces in beiden Sprachen gleich sind.
Kiamlaluno
4

Ähnlich wie Verzeichnisse und Dateien dient der Namespace in PHP zum Gruppieren von Klassen , Funktionen , Schnittstellen und Konstanten .

Beispiel:

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

Es bietet eine Möglichkeit, Elemente aus dem globalen Bereich zu verpacken, und ermöglicht die Verwendung eines einfachen Elementnamens, ohne eine Namenskollision in einem Programm zu verursachen. Es wird in PHP 5.3.0, PHP 7 unterstützt.

In Analogie zwischen dem PHP-Namespace und dem Unix-basierten Dateisystem gibt es jedoch einige Grenzen:

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

Das Prinzip erstreckt sich auf den Namespace im Programmierwort.


quelle
3

Ein Namespace funktioniert wie ein Verzeichnis. Sie wissen, wie Sie Dateien in ein Verzeichnis mit denselben Namen wie Dateien im übergeordneten (oder einem anderen) Verzeichnis einfügen können? Mit einem Namespace können Sie dies in einer Anwendung für Variablen, Funktionen und Klassen tun.

Vor einiger Zeit gab es in PHP einen gewissen Trend für große Klassen statischer Funktionen. Die einzige Möglichkeit, eine dieser Funktionen aufzurufen, bestand darin, einem Aufruf den Klassennamen voranzustellen. Dies war ein primitiver Versuch, Namespaces zu nutzen, aber mit nicht sehr vielen Vorteilen.

staticsan
quelle
2

Mit einem Namespace können Sie Code in einen Container einfügen. Dies verhindert Probleme mit zwei Funktionen (sowie Klassen und Variablen), die denselben Namen haben.

Diese sind nützlich, wenn Sie mit größeren Anwendungen arbeiten, um Probleme mit gleichnamigen Codeteilen zu vermeiden.

Nehmen wir zum Beispiel an, wir wollten zwei Funktionen namens "TheMessage". Diese beiden würden jeweils unterschiedliche Nachrichten drucken (echo). Normalerweise würde dies einen Syntaxfehler verursachen, da Sie nicht zwei Funktionen haben können, die denselben Namen haben.

Um dies zu beheben, können Sie diese Funktionen in separate Namespaces einfügen. Auf diese Weise können Sie beide Funktionen fehlerfrei verwenden.

Alexander
quelle
2

Namespace ist wie das Packen vieler Dinge in eine einzige Packung. Stellen Sie sich einen Namespace als Schublade vor, in die Sie alle möglichen Dinge stecken können: einen Bleistift, ein Lineal, ein Stück Papier und so weiter. Um zu vermeiden, dass sich die Gegenstände gegenseitig verwenden, beschriften Sie die Schubladen, damit klar ist, was zu wem gehört.

Mamun Sabuj
quelle
0

Der Namespace wird verwendet, um eine Gruppe von Codes einzuschließen, damit sie ohne Namenskonflikte an verschiedenen Orten verwendet werden können. Stellen Sie sich dies als jQuery No Conflict-Methode vor und Sie werden es besser verstehen.

Emmanuel David
quelle
Was meinst du mit "jQuery keine Konfliktmethode"? Wie hängt das mit PHP zusammen?
Nico Haase
0

Ein Namespace ist ein einfaches System zur Steuerung der Namen in einem Programm.
Es stellt sicher, dass Namen eindeutig sind und nicht zu Konflikten führen.

humaid
quelle
Über welche Arten von "Namen" sprechen Sie?
Nico Haase
0

Sie können den Namespace verwenden, um Namenskollisionen zwischen dem von Ihnen erstellten Code und internen PHP-Klassen / Funktionen / Konstanten oder Klassen / Funktionen / Konstanten von Drittanbietern zu vermeiden. Namespaces können auch Extra_Long_Names aliasen (oder verkürzen), um das erste Problem zu reduzieren und die Lesbarkeit des Quellcodes zu verbessern.

Wie wir alle wissen, sind Namespaces und Eigenschaften in PHP nicht neu, aber dennoch verwenden viele PHP-Entwickler diese großartigen Konzepte aufgrund ihrer Komplexität nicht. Also, in diesem Beitrag. Ich werde versuchen, sie mit Beispielen zu klären. Was sind Namespace und Merkmale?

Wie können Sie sie in Ihren Code implementieren, um Ihren Code wiederverwendbar und erweiterbar zu machen?

Vorteile von Namespaces

Sie können den Namespace verwenden, um Namenskollisionen zwischen dem von Ihnen erstellten Code und internen PHP-Klassen / Funktionen / Konstanten oder Klassen / Funktionen / Konstanten von Drittanbietern zu vermeiden.

Namespaces können auch Extra_Long_Names aliasen (oder verkürzen), um das erste Problem zu reduzieren und die Lesbarkeit des Quellcodes zu verbessern. Lassen Sie uns Namespaces anhand eines Beispiels verstehen. Erstellen Sie einen Ordnernamen "php_oops" in htdocs (xampp) oder www (xwamp). Erstellen Sie einen neuen Ordner im Stammverzeichnis mit dem Namen "Namespaces" und erstellen Sie dann eine Datei index.php im Ordner "Namespaces".

<?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

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

Ashwani Garg
quelle
1
Bitte seien Sie vorsichtig, wenn Sie auf verschiedenen Websites auf Ihre eigenen Inhalte verlinken. Sie möchten kein Spammer sein . Sie sollten den größten Teil des Inhalts hier einfügen und den Link nur als Referenz verwenden.
Dharman