FAQ

Från Wiki.linux.se
Hoppa till navigering Hoppa till sök

Vanliga frågor: saker du behöver veta om namnrymder

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

Denna FAQ är uppdelad i två sektioner: vanliga frågor och några specifika implementationer som är bra att förstå fullt ut.

Först, de vanliga frågorna.

  • Om jag inte använder namnrymder, behöver jag bry mig om detta?
  • Hur använder jag interna eller globala klasser i en namnrymd?
  • Hur använder jag namnrymdsklasser, funktioner eller konstanter i deras egen namnrymd?
  • Hur löses ett namn som \my\name eller \name?
  • Hur löses ett namn som my\name?
  • Hur löses ett okvalificerat klassnamn som name?
  • Hur löses ett okvalificerat funktionsnamn eller okvalificerat konstantnamn som name?

Det finns några implementationdetaljer av namnrymd som är bra att förstå.

  • Importnamn får inte kollidera med klasser definierade i samma fil.
  • Nästlade namnrymder är inte tillåtna.
  • Dynamiska namnrymdsnamn (citerade identifierare) bör flytta omvänt snedstreck.
  • Odefinierade konstanter refererade med något snedstreck leder till ett allvarligt fel.
  • Kan inte åsidosätta specialkonstanterna null, true eller false.

Om jag inte använder namnrymder, behöver jag bry mig om detta?

Nej. Namnrymder påverkar inte någon befintlig kod på något sätt, eller någon kod som ännu inte är skriven och som inte innehåller namnrymder. Du kan skriva denna kod om du vill:

Exempel #1 Åtkomst till globala klasser utanför en namnrymd

<?php
$a = new \stdClass;
?>

Detta är funktionellt ekvivalent med:

Exempel #2 Åtkomst till globala klasser utanför en namnrymd

<?php
$a = new stdClass;
?>

Hur använder jag interna eller globala klasser i en namnrymd?

Exempel #3 Åtkomst till interna klasser i namnrymder

<?php
namespace foo;
$a = new \stdClass;

function test(\ArrayObject $parameter_type_example = null) {}

$a = \DirectoryIterator::CURRENT_AS_FILEINFO;

// utökar en intern eller global klass
class MyException extends \Exception {}
?>

Hur använder jag namnrymdsklasser, funktioner eller konstanter i deras egen namnrymd?

Exempel #4 Åtkomst till interna klasser, funktioner eller konstanter i namnrymder

<?php
namespace foo;

class MyClass {}

// använda en klass från den aktuella namnrymden som en parameter typ
function test(MyClass $parameter_type_example = null) {}
// ett annat sätt att använda en klass från den aktuella namnrymden som en parameter typ
function test(\foo\MyClass $parameter_type_example = null) {}

// utöka en klass från den aktuella namnrymden
class Extended extends MyClass {}

// åtkomst till en global funktion
$a = \globalfunc();

// åtkomst till en global konstant
$b = \INI_ALL;
?>

Hur löses ett namn som \my\name eller \name?

Namn som börjar med ett \ löses alltid till vad de ser ut som, så \my\name är faktiskt my\name, och \Exception är Exception.

Exempel #5 Fullt kvalificerade namn

<?php
namespace foo;
$a = new \my\name(); // instansierar klassen "my\name"
echo \strlen('hi'); // anropar funktionen "strlen"
$a = \INI_ALL; // $a sätts till värdet av konstanten "INI_ALL"
?>

Hur löses ett namn som my\name?

Namn som innehåller ett snedstreck men inte börjar med ett snedstreck som my\name kan lösas på 2 olika sätt.

  • Om det finns en importinstruktion som aliaserar ett annat namn till my, tillämpas importaliaset på my i my\name.
  • Annars läggs den aktuella namnrymden till my\name.

Exempel #6 Kvalificerade namn

<?php
namespace foo;
use blah\blah as foo;

$a = new my\name(); // instansierar klassen "foo\my\name"
foo\bar::name(); // anropar den statiska metoden "name" i klassen "blah\blah\bar"
my\bar(); // anropar funktionen "foo\my\bar"
$a = my\BAR; // sätter $a till värdet av konstanten "foo\my\BAR"
?>

Hur löses ett okvalificerat klassnamn som name?

Klassnamn som inte innehåller ett snedstreck som name kan lösas på 2 olika sätt.

  • Om det finns en importinstruktion som aliaserar ett annat namn till name, tillämpas importaliaset.
  • Annars läggs den aktuella namnrymden till name.

Exempel #7 Okvalificerade klassnamn

<?php
namespace foo;
use blah\blah as foo;

$a = new name(); // instansierar klassen "foo\name"
foo::name(); // anropar den statiska metoden "name" i klassen "blah\blah"
?>

Hur löses ett okvalificerat funktionsnamn eller okvalificerat konstantnamn som name?

Funktions- eller konstantnamn som inte innehåller ett snedstreck som name kan lösas på 2 olika sätt.

  • Först läggs den aktuella namnrymden till name.
  • Slutligen, om konstanten eller funktionsnamnet inte finns i den aktuella namnrymden, används ett globalt konstant- eller funktionsnamn om det finns.

Exempel #8 Okvalificerade funktions- eller konstantnamn

<?php
namespace foo;
use blah\blah as foo;

const FOO = 1;

function my() {}
function foo() {}
function sort(&$a)
{
    \sort($a); // anropar den globala funktionen "sort"
    $a = array_flip($a);
    return $a;
}

my(); // anropar "foo\my"
$a = strlen('hi'); // anropar den globala funktionen "strlen" eftersom "foo\strlen" inte finns
$arr = array(1,3,2);
$b = sort($arr); // anropar funktionen "foo\sort"
$c = foo(); // anropar funktionen "foo\foo" - import tillämpas inte

$a = FOO; // sätter $a till värdet av konstanten "foo\FOO" - import tillämpas inte
$b = INI_ALL; // sätter $b till värdet av den globala konstanten "INI_ALL"
?>

Importnamn får inte kollidera med klasser definierade i samma fil.

Följande skriptkombinationer är tillåtna:

file1.php

<?php
namespace my\stuff;
class MyClass {}
?>

another.php

<?php
namespace another;
class thing {}
?>

file2.php

<?php
namespace my\stuff;
include 'file1.php';
include 'another.php';

use another\thing as MyClass;
$a = new MyClass; // instansierar klassen "thing" från namnrymden another
?>

Det finns ingen namnkonflikt, även om klassen MyClass finns inom namnrymden my\stuff, eftersom definitionen av MyClass är i en separat fil. Däremot orsakar nästa exempel ett allvarligt fel på grund av namnkonflikt eftersom MyClass är definierad i samma fil som use-instruktionen.

<?php
namespace my\stuff;
use another\thing as MyClass;
class MyClass {} // allvarligt fel: MyClass kolliderar med importinstruktionen
$a = new MyClass;
?>

Nästlade namnrymder är inte tillåtna.

PHP tillåter inte nästlade namnrymder

<?php
namespace my\stuff {
    namespace nested {
        class foo {}
    }
}
?>

Det är dock enkelt att simulera nästlade namnrymder på detta sätt:

<?php
namespace my\stuff\nested {
    class foo {}
}
?>

Dynamiska namnrymdsnamn (citerade identifierare) bör flytta omvänt snedstreck

Det är mycket viktigt att inse att eftersom snedstrecket används som en escape-tecken inom strängar, bör det alltid fördubblas när det används inom en sträng. Annars finns risken för oavsiktliga konsekvenser:

Exempel #9 Faran med att använda namnrymdsnamn inom en dubbelciterad sträng

<?php
$a = "dangerous\name"; // \n är en ny rad inom dubbelciterade strängar!
$obj = new $a;

$a = 'not\at\all\dangerous'; // inga problem här.
$obj = new $a;
?>

Inom en enkelciterad sträng är det mycket säkrare att använda escape-tecknet snedstreck, men det rekommenderas ändå att flytta snedstreck i alla strängar som en bästa praxis.

Odefinierade konstanter refererade med något snedstreck leder till ett allvarligt fel

Alla odefinierade konstanter som är okvalificerade som FOO kommer att producera ett meddelande som förklarar att PHP antog att FOO var värdet av konstanten. Alla konstanter, kvalificerade eller fullt kvalificerade, som innehåller ett snedstreck kommer att producera ett allvarligt fel om de inte hittas.

Exempel #10 Odefinierade konstanter

<?php
namespace bar;
$a = FOO; // producerar en notis - odefinierad konstant "FOO" antagen "FOO";
$a = \FOO; // allvarligt fel, odefinierad namnrymdskonstant FOO
$a = Bar\FOO; // allvarligt fel, odefinierad namnrymdskonstant bar\Bar\FOO
$a = \Bar\FOO; // allvarligt fel, odefinierad namnrymdskonstant Bar\FOO
?>

Kan inte åsidosätta specialkonstanterna null, true eller false

Alla försök att definiera en namnrymdskonstant som är en special, inbyggd konstant resulterar i ett allvarligt fel.

Exempel #11 Odefinierade konstanter

<?php
namespace bar;
const NULL = 0; // allvarligt fel;
const true = 'stupid'; // också allvarligt fel;
// etc.
?>


Sidslut

Orginalhemsidan på Engelska : https://www.php.net/manual/en/language.namespaces.faq.php
PHP
Språkreferens
Språkreferens#Namnrymder


Det här är en maskinöversättning av PHP-manualen till svenska. Om du hittar fel är vi tacksamma om du rapporterar dem via formuläret som finns på https://www.linux.se/kontaka-linux-se/