diff --git a/language/constants.xml b/language/constants.xml
new file mode 100644
index 00000000..0836a97f
--- /dev/null
+++ b/language/constants.xml
@@ -0,0 +1,385 @@
+
+
+
+
+ Constants
+
+
+ Stała jest identyfikatorem (nazwą) prostej wartości. Jak sama
+ nazwa wskazuje, wartość ta nie może się zmienić podczas wykonywania
+ skryptu (z wyjątkiem
+ stałych magicznych, które w rzeczywistości nie są stałymi).
+ Wielkość liter w stałych ma znaczenie. Zgodnie z konwencją, identyfikatory
+ stałych są zawsze pisane wielkimi literami.
+
+
+
+
+ Przed PHP 8.0.0, stałe zdefiniowane przy użyciu funkcji define
+ mogły nie uwzględniać wielkości liter.
+
+
+
+
+ Nazwa stałej podlega tym samym zasadom, co każda etykieta w PHP.
+ Prawidłowa nazwa stałej zaczyna się od litery lub podkreślenia,
+ po których następuje dowolna liczba liter, cyfr lub podkreśleń.
+ Jako wyrażenie regularne, może być wyrażona w następujący sposób:
+ ^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$
+
+
+ Możliwe jest zdefiniowanie za pomocą define satłych z
+ zastrzeżonymi lub nawet nieważnymi nazwami, których wartość można pobrać tylko za
+ pomocą funkcji constant. Nie jest to jednak zalecane.
+
+ &tip.userlandnaming;
+
+
+
+ Prawidłowe i nieprawidłowe nazwy stałych
+
+
+]]>
+
+
+
+
+
+ Dla naszych celów litera to a-z, A-Z i znaki ASCII
+ od 128 do 255 (0x80-0xff).
+
+
+
+
+ Podobnie jak &link.superglobals;, zakres stałej jest globalny.
+ Dostęp do stałych można uzyskać z dowolnego miejsca w skrypcie bez względu na zakres.
+ Aby uzyskać więcej informacji na temat zakresu, przeczytaj sekcję podręcznika dotyczącą
+ zakresu zmiennej.
+
+
+
+
+ Począwszy od PHP 7.1.0, stałe klasowe mogą deklarować widoczność protected
+ lub private, czyniąc je dostępnymi tylko w hierarchicznym zakresie klasy,
+ w której są zdefiniowane.
+
+
+
+
+ Składnia
+
+ Stałe mogą być definiowane za pomocą słowa kluczowego const,
+ lub za pomocą funkcji define.
+ Podczas gdy define pozwala na zdefiniowanie stałej
+ dla dowolnego wyrażenia, słowo kluczowe const ma
+ ograniczenia opisane w następnym akapicie.
+ Gdy stała zostanie zdefiniowana, nigdy nie może zostać
+ zmieniona lub niezdefiniowana.
+
+
+ Podczas używania słowa kluczowego const,
+ akceptowane są tylko wyrażenia skalarne (bool, int,
+ float i string) oraz stałe
+ arrays zawierające tylko wyrażenia skalarne.
+ Możliwe jest zdefiniowanie stałych jako resource,
+ ale należy tego unikać, ponieważ może to spowodować nieoczekiwane wyniki.
+
+
+ Dostęp do wartości stałej uzyskuje się po prostu poprzez podanie jej nazwy.
+ W przeciwieństwie do zmiennych, stała nie jest poprzedzona
+ $.
+ Możliwe jest również użycie funkcji constant do
+ odczytania wartości stałej, jeśli nazwa stałej jest uzyskiwana dynamicznie.
+ Użyj funkcji get_defined_constants, aby uzyskać listę
+ wszystkich zdefiniowanych stałych.
+
+
+
+
+ Stałe i zmienne (globalne) znajdują się w innej przestrzeni nazw.
+ Oznacza to, że na przykład &true; i
+ $TRUE są generalnie różne.
+
+
+
+
+ Jeśli zostanie użyta niezdefiniowana stała, zostanie zgłoszony błąd Error.
+ Przed PHP 8.0.0, niezdefiniowane stałe były interpretowane jako gołe słowo
+ string, t.j. (CONSTANT vs "CONSTANT").
+ To rozwiązanie awaryjne jest przestarzałe od PHP 7.2.0, a błąd poziomu
+ E_WARNING jest zgłaszany, gdy tak się stanie.
+ Przed PHP 7.2.0, zamiast tego zgłaszany był błąd poziomu
+ E_NOTICE.
+ Zobacz także wpis w podręczniku, dlaczego
+ $foo[bar] jest
+ błędne (chyba, że bar jest stałą).
+ Nie dotyczy to (w pełni) kwalifikowanych stałych,
+ które zawsze zgłoszą błąd Error, jeśli są niezdefiniowane.
+
+
+
+
+ Aby sprawdzić, czy stała jest ustawiona, należy użyć funkcji defined.
+
+
+
+
+ To są różnice między stałymi i zmiennymi:
+
+
+
+ Stałe nie mają przed sobą znaku dolara
+ ($);
+
+
+
+
+ Stałe mogą być definiowane i dostępne w dowolnym miejscu bez względu na
+ zasady dotyczące zakresu zmiennych;
+
+
+
+
+ Stałe nie mogą być przedefiniowane lub niezdefiniowane po ich ustawieniu;
+ oraz
+
+
+
+
+ Stałe mogą być oceniane tylko jako wartości skalarne lub tablice.
+
+
+
+
+
+
+
+ Defining Constants
+
+
+]]>
+
+
+
+
+
+
+ Definiowanie Stałych przy użyciu słowa kluczowego const
+
+
+]]>
+
+
+
+
+
+
+ W przeciwieństwie do definiowania stałych za pomocą define,
+ stałe zdefiniowane za pomocą słowa kluczowego const muszą być
+ zadeklarowane w zakresie najwyższego poziomu, ponieważ są definiowane w czasie kompilacji.
+ Oznacza to, że nie można ich zadeklarować wewnątrz funkcji, pętli, instrukcji
+ if lub bloków
+ try/catch.
+
+
+
+
+ &reftitle.seealso;
+
+
+ Stałe Klasy
+
+
+
+
+
+
+ Predefiniowane stałe
+
+
+ PHP udostępnia dużą liczbę predefiniowanych stałych dla każdego
+ uruchamianego skryptu. Wiele z tych stałych jest jednak tworzonych przez
+ różne rozszerzenia i będą one obecne tylko wtedy, gdy te rozszerzenia
+ są dostępne, albo poprzez dynamiczne ładowanie, albo dlatego, że zostały
+ skompilowane.
+
+
+
+
+ Stałe magiczne
+
+ Istnieje kilka magicznych stałych, które zmieniają się w zależności
+ od tego, gdzie są używane. Na przykład wartość stałej
+ __LINE__ zależy od linii, w której jest
+ używana w skrypcie. Wszystkie te „magiczne” stałe są rozwiązywane w
+ czasie kompilacji, w przeciwieństwie do zwykłych stałych, które są rozwiązywane w czasie wykonywania.
+ Te specjalne stałe nie uwzględniają wielkości liter i są następujące:
+
+
+
+ Stałe magiczne PHP
+
+
+
+ &Name;
+ &Description;
+
+
+
+
+ __LINE__
+
+ Bieżący numer linii pliku.
+
+
+
+ __FILE__
+
+ Pełna ścieżka i nazwa pliku z rozwiązanymi dowiązaniami symbolicznymi.
+ W przypadku użycia wewnątrz include, zwracana jest nazwa dołączonego pliku.
+
+
+
+ __DIR__
+
+ Katalog pliku. Jeśli użyta jest wewnątrz include,
+ zwracany jest katalog dołączonego pliku. Jest to równoważne
+ dla dirname(__FILE__). Nazwa katalogu
+ nie zawiera końcowego ukośnika, chyba że jest to katalog główny.
+
+
+
+ __FUNCTION__
+
+ Nazwa funkcji lub {domknięcie} dla funkcji anonimowych.
+
+
+
+ __CLASS__
+
+ Nazwa klasy. Nazwa klasy zawiera przestrzeń nazw, w której
+ została zadeklarowana (n.p. Foo\Bar).
+ W przypadku użycia wewnątrz metody traita,
+ __CLASS__ jest nazwą klasy, w której trait jest
+ używany.
+
+
+
+ __TRAIT__
+
+ Nazwa traita. Nazwa traita zawiera przestrzeń nazw, w
+ której został zadeklarowany (e.g. Foo\Bar).
+
+
+
+ __METHOD__
+
+ Nazwa metody klasy.
+
+
+
+ __PROPERTY__
+
+ Ważne tylko wewnątrz
+ haku właściwości.
+ Jest ona równa nazwie właściwości.
+
+
+
+ __NAMESPACE__
+
+ Nazwa bieżącej przestrzeni nazw.
+
+
+
+ ClassName::class
+
+ W pełni kwalifikowana nazwa klasy.
+
+
+
+
+
+
+
+
+ &reftitle.seealso;
+
+
+ ::class
+ get_class
+ get_object_vars
+ file_exists
+ function_exists
+
+
+
+
+
+
+
+
diff --git a/language/enumerations.xml b/language/enumerations.xml
new file mode 100644
index 00000000..ebaf174d
--- /dev/null
+++ b/language/enumerations.xml
@@ -0,0 +1,990 @@
+
+
+
+
+ Wyliczenia
+
+ Przegląd wyliczeń
+
+
+
+ Wyliczenia lub "Enumy" pozwalają programiście zdefiniować niestandardowy typ, który jest ograniczony
+ do jednej z dyskretnej liczby możliwych wartości. Może to być szczególnie pomocne przy definiowaniu
+ modelu domeny, ponieważ umożliwia "uniemożliwienie reprezentowania nieważnych stanów."
+
+
+
+ Enumy pojawiają się w wielu językach z różnymi funkcjami. W PHP, Enumy są specjalnym
+ rodzajem obiektów. Enum samo w sobie jest klasą, a jego możliwe zbiory wartości są
+ pojedynczymi obiektami tej klasy. Oznacza to, że zbiory wartości Enuma są poprawnymi obiektami
+ i mogą być używane wszędzie tam, gdzie obiekt może być użyty, włączając w to sprawdzanie typów.
+
+
+
+ Najpopularniejszym przykładem wyliczeń jest wbudowany typ boolean, który jest
+ typem wyliczeniowym z legalnymi wartościami &true; i &false;.
+ Enumy pozwalają programistom definiować własne, dowolnie rozbudowane wyliczenia.
+
+
+
+ Podstawowe wyliczenia
+
+
+ Enumy są podobne do klas i dzielą te same przestrzenie nazw co klasy, interfejsy i traity.
+ Są one również automatycznie ładowane w ten sam sposób. Enumy definiują nowy typ, który ma stałą,
+ ograniczoną liczbę możliwych legalnych wartości.
+
+
+
+
+
+]]>
+
+
+
+ Ta deklaracja tworzy nowy typ wyliczeniowy o nazwie Suit, który ma
+ cztery i tylko cztery legalne wartości: Suit::Hearts, Suit::Diamonds,
+ Suit::Clubs i Suit::Spades. Zmienne mogą być przypisane
+ do jednej z tych legalnych wartości. Funkcja może być sprawdzana pod kątem typu wyliczeniowego,
+ w którym to przypadku mogą być przekazywane tylko wartości tego typu.
+
+
+
+
+]]>
+
+
+
+ Wyliczenie może mieć zero lub więcej definicji case, bez maksimum.
+ Enumy o zerowej ilości case są poprawne składniowo, choć raczej bezużyteczne.
+
+
+
+ Dla przypadków wyliczeń obowiązują te same zasady składni, co dla każdej etykiety w PHP, zobacz
+ Stałe.
+
+
+
+ Domyślnie instrukcje case nie są wewnętrznie wspierane przez wartość skalarną.
+ Oznacza to, że Suit::Hearts nie jest równy "0".
+ Zamiast tego, każdy case jest wspierany przez pojedynczy obiekt o tej nazwie. Oznacza to, że:
+
+
+
+
+]]>
+
+
+
+ Oznacza to również, że wartości enumów nigdy nie są < lub > względem siebie,
+ ponieważ te porównania nie mają znaczenia na obiektach. Te porównania zawsze
+ zwrócą &false; podczas pracy z wartościami enuma.
+
+
+
+ Ten typ instrukcji case, bez powiązanych danych, nazywany jest "Pure Case". Enumy zawierające
+ tylko Pure Case nazywane są Pure Enum.
+
+
+
+ Wszystkie Pure Case są zaimplementowane jako instancje ich typu enuma. Typ enuma jest reprezentowany wewnętrznie jako klasa.
+
+
+
+ Wszystkie instrukcje case mają właściwość tylko do odczytu nazwę, która jest rozróżniającą
+ wielkość liter nazwą samej instrukcji case.
+
+
+
+name;
+// prints "Spades"
+?>
+]]>
+
+
+
+ Możliwe jest również użycie funkcji defined i constant
+ do sprawdzenia istnienia lub odczytania case enuma, jeśli nazwa jest uzyskiwana dynamicznie.
+ Jest to jednak odradzane, ponieważ użycie Enuma backed
+ powinno działać w większości przypadków użycia.
+
+
+
+
+
+ Wyliczenia backed
+
+
+ Domyślnie Wyliczone Case nie mają skalarnego odpowiednika. Są to po prostu obiekty singleton. Istnieje
+ jednak wiele przypadków, w których Wyliczony Case musi być w stanie zaokrąglić do bazy danych lub
+ podobnego magazynu danych, więc posiadanie wbudowanej wartoścci skalarnej (a zatem trywialnie serializowalnego)
+ odpowiednika zdefiniowanego wewnętrznie jest przydatne.
+
+
+ Aby zdefiniować skalarny odpowiednik dla Wyliczeń, składnia jest następująca:
+
+
+
+]]>
+
+
+
+ Case, który ma odpowiednik skalarny, nazywany jest Backed Case, ponieważ jest "Utworzony"
+ przez prostszą wartość. Enum, który zawiera wszystkie Backed Case nazywany jest "Backed Enum".
+ Backed Enum może zawierać tylko Backed Cases. Pure Enum może zawierać tylko Pure Case.
+
+
+
+ Backed Enum może być utworzony przez typy int lub string,
+ a dane wyliczenie obsługuje tylko jeden typ w danym czasie (tj. nie ma uni int|string).
+ Jeśli wyliczenie jest oznaczone jako posiadające skalarny odpowiednik, to wszystkie przypadki muszą mieć
+ unikalny skalarny odpowiednik zdefiniowany jawnie. Nie ma automatycznie generowanych odpowiedników
+ skalarnych (np. sekwencyjnych liczb całkowitych). Backed case muszą być unikalne; dwa backed enum case nie mogą
+ mieć tego samego skalarnego odpowiednika. Stała może jednak odnosić się do przypadku, skutecznie
+ tworząc alias. Zobacz Stałe wyliczenia.
+
+
+
+ Równoważne wartości mogą być stałym wyrażeniem skalarnym.
+ Przed PHP 8.2.0 równoważne wartości musiały być literałami lub wyrażeniami literałowymi.
+ Oznacza to, że stałe i wyrażenia stałe nie były obsługiwane.
+ Oznacza to, że 1 + 1 było dozwolone, ale nie 1 + SOME_CONST.
+
+
+
+ Backed Case mają dodatkową właściwość tylko do odczytu value, która jest wartością
+ określoną w definicji.
+
+
+
+value;
+// Prints "C"
+?>
+]]>
+
+
+
+ Aby wymusić właściwość value jako tylko do odczytu, nie można przypisać zmiennej
+ jako odniesienia do niej. Oznacza to, że poniższy kod powoduje błąd:
+
+
+
+value;
+// Błąd: Nie można uzyskać odniesienia do właściwości Suit::$value
+?>
+]]>
+
+
+
+ Enumy backed implementują wewnętrzny interfejs BackedEnum,
+ który udostępnia dwie dodatkowe metody::
+
+
+
+
+ from(int|string): self przyjmie skalar i zwróci odpowiadający mu
+ Case Enuma. Jeśli nie zostanie znaleziony, zostanie zgłoszony błąd ValueError.
+ Jest to przydatne głównie w przypadkach, gdy skalar wejściowy jest zaufany, a brakująca wartość enuma powinna
+ być uznana za błąd zatrzymujący aplikację.
+
+
+ tryFrom(int|string): ?self przyjmie skalar i zwróci
+ odpowiadający mu Case Enuma. Jeśli nie zostanie znaleziony, zwróci null.
+ Jest to przydatne głównie w przypadkach, gdy skalar wejściowy jest niegodny zaufania, a wywołujący chce
+ zaimplementować własną obsługę błędów lub logikę wartości domyślnych.
+
+
+
+
+ Metody from() i tryFrom() stosują się do standardowych
+ reguł słabego/silnego typowania. W trybie słabego typowania, przekazanie liczby całkowitej lub ciągu jest dopuszczalne,
+ a system odpowiednio wymusi wartość. Przekazanie liczby zmiennoprzecinkowej również zadziała i
+ zostanie wymuszone. W trybie ścisłego typowania, przekazanie liczby całkowitej do from() w
+ wyliczeniu opartym na ciągu (lub odwrotnie) spowoduje błąd TypeError,
+ podobnie jak float we wszystkich okolicznościach. Wszystkie inne typy parametrów wyrzucą błąd TypeError
+ w obu trybach.
+
+
+
+value;
+
+$suit = Suit::tryFrom('A') ?? Suit::Spades;
+// Invalid data returns null, so Suit::Spades is used instead.
+print $suit->value;
+?>
+]]>
+
+
+ Ręczne zdefiniowanie metody from() lub tryFrom() w Backed Enum spowoduje błąd krytyczny.
+
+
+
+
+ Metody wyliczeń
+
+
+ Enumy (zarówno Enumy Pure, jak i Enumy Backed) mogą zawierać metody i mogą implementować interfejsy.
+ Jeśli Enum implementuje interfejs, wówczas każde sprawdzenie typu dla tego interfejsu zaakceptuje również
+ wszystkie przypadki tego Enuma.
+
+
+
+ 'Red',
+ Suit::Clubs, Suit::Spades => 'Black',
+ };
+ }
+
+ // Nie jest częścią interfejsu; nie ma problemu.
+ public function shape(): string
+ {
+ return "Rectangle";
+ }
+}
+
+function paint(Colorful $c)
+{
+ /* ... */
+}
+
+paint(Suit::Clubs); // Działa
+
+print Suit::Diamonds->shape(); // Wyświetli "Rectangle"
+?>
+]]>
+
+
+
+ W tym przykładzie wszystkie cztery wystąpienia Suit mają dwie metody
+ color() i shape(). Jeśli chodzi o wywoływanie kodu
+ i sprawdzanie typów, zachowują się one dokładnie tak samo, jak każde inna instancja obiektu.
+
+
+
+ W przypadku Backed Enum deklaracja interfejsu następuje po deklaracji typu backed.
+
+
+
+ 'Red',
+ Suit::Clubs, Suit::Spades => 'Black',
+ };
+ }
+}
+?>
+]]>
+
+
+
+ Wewnątrz metody zdefiniowana jest zmienna $this która odwołuje się do instancji Case.
+
+
+
+ Metody mogą być dowolnie złożone, ale w praktyce zazwyczaj zwracają wartość statyczną lub
+ &match; dla $this aby zapewnić
+ różne wyniki w różnych przypadkach.
+
+
+
+ Należy zauważyć, że w tym przypadku lepszą praktyką modelowania danych byłoby również zdefiniowanie
+ Typu Enum SuitColor z wartościami Red i Black i zwrócenie go zamiast tego.
+ Jednak skomplikowałoby to ten przykład.
+
+
+
+ Powyższa hierarchia jest logicznie podobna do następującej struktury klas
+ (choć nie jest to faktyczny kod, który jest uruchamiany):
+
+
+
+ 'Red',
+ Suit::Clubs, Suit::Spades => 'Black',
+ };
+ }
+
+ public function shape(): string
+ {
+ return "Rectangle";
+ }
+
+ public static function cases(): array
+ {
+ // Nielegalna metoda, ponieważ ręczne definiowanie metody cases() na Enumie jest niedozwolone.
+ // Zobacz także sekcję "Listowanie wartości".
+ }
+}
+?>
+]]>
+
+
+
+ Metody mogą być publiczne, prywatne lub chronione, chociaż w praktyce prywatne i
+ chronione są równoważne, ponieważ dziedziczenie nie jest dozwolone.
+
+
+
+
+
+ Statyczne metody wyliczeń
+
+
+ Wyliczenia mogą również posiadać metody statyczne. Użycie metod statycznych na
+ samym wyliczeniu jest przede wszystkim dla alternatywnych konstruktorów. Np:
+
+
+
+ self::Small,
+ $cm < 100 => self::Medium,
+ default => self::Large,
+ };
+ }
+}
+?>
+]]>
+
+
+
+ Metody statyczne mogą być publiczne, prywatne lub chronione, chociaż w praktyce prywatne
+ i chronione są równoważne, ponieważ dziedziczenie nie jest dozwolone.
+
+
+
+
+
+ Stałe wyliczeń
+
+
+ Wyliczenia mogą zawierać stałe, które mogą być publiczne, prywatne lub chronione,
+ chociaż w praktyce prywatne i chronione są równoważne, ponieważ dziedziczenie nie jest dozwolone.
+
+
+ Stała enuma może odnosić się do przypadku enuma:
+
+
+
+]]>
+
+
+
+
+ Traity
+
+ Wyliczenia mogą wykorzystywać cechy, które będą zachowywać się tak samo jak w przypadku klas.
+ Zastrzeżeniem jest to, że traity używane w enum nie mogą zawierać właściwości.
+ Mogą one zawierać jedynie metody, metody statyczne i stałe. Traity z właściwościami
+ spowodują błąd krytyczny.
+
+
+
+ 'Red',
+ Suit::Clubs, Suit::Spades => 'Black',
+ };
+ }
+}
+?>
+]]>
+
+
+
+
+ Wartości Enum w wyrażeniach stałych
+
+
+ Ponieważ case są reprezentowane jako stałe w samym wyliczeniu, mogą być używane jako wartości
+ statyczne w większości wyrażeń stałych: wartości domyślne właściwości, wartości domyślne zmiennych
+ statycznych, wartości domyślne parametrów, wartości stałe globalne i klasowe. Nie mogą być używane
+ w innych wartościach case wyliczenia, ale normalne stałe mogą odnosić się do case wyliczenia.
+
+
+
+ Jednak niejawne magiczne wywołania metod, takie jak ArrayAccess na enumach,
+ nie są dozwolone w definicjach statycznych lub stałych, ponieważ nie można absolutnie zagwarantować, że
+ wynikowa wartość jest deterministyczna lub że wywołanie metody jest wolne od skutków ubocznych. Wywołania
+ funkcji, metod i dostęp do właściwości nadal są nieprawidłowymi operacjami w stałych wyrażeniach.
+
+
+
+
+]]>
+
+
+
+
+ Różnice w stosunku do obiektów
+
+
+ Chociaż enumy są zbudowane na klasach i obiektach, nie obsługują wszystkich funkcji związanych z obiektami.
+ W szczególności case Enuma nie mogą posiadać stanu.
+
+
+
+ Konstruktory i Destruktory są zabronione.
+ Dziedziczenie nie jest obsługiwane. Wyliczenia nie mogą rozszerzać ani być rozszerzane.
+ Właściwości statyczne lub obiektowe nie są dozwolone.
+ Klonowanie przypadku Enum nie jest obsługiwane, ponieważ przypadki muszą być pojedynczymi instancjami.
+ Metody magicznez wyjątkiem tych wymienionych poniżej są niedozwolone.
+ Enumy muszą być zawsze zadeklarowane przed ich użyciem.
+
+
+ Następujące funkcje obiektu są dostępne i zachowują się tak samo, jak w przypadku każdego innego obiektu:
+
+
+ Metody publiczne, prywatne i chronione.
+ Publiczne, prywatne i chronione metody statyczne.
+ Stałe publiczne, prywatne i chronione
+ Enum może implementować dowolną liczbę interfejsów.
+
+ Enumy i przypadki mogą mieć dołączone atrybuty.
+ Filtr docelowy TARGET_CLASS
+ obejmuje same wyliczenia. Filtr docelowy TARGET_CLASS_CONST
+ obejmuje przypadki Enumów.
+
+
+ Magiczn metody __call, __callStatic,
+ i __invoke
+
+ __CLASS__ i __FUNCTION__ stałe zachowują się jak zwykle
+
+
+
+ Stała magiczna ::class na typie Enum jest oceniana na nazwę typu,
+ w tym dowolną przestrzeń nazw, dokładnie tak samo jak obiekt. Stała magiczna ::class
+ na instancji Case również jest wartościowana na typ Enum, ponieważ jest
+ instancją tego typu.
+
+
+
+ Dodatkowo case enuma nie mogą być instancjonowane bezpośrednio za pomocą new, ani za pomocą
+ ReflectionClass::newInstanceWithoutConstructor w refleksji. W obu przypadkach wystąpi błąd.
+
+
+
+newInstanceWithoutConstructor()
+// Błąd: Nie można utworzyć instancji enum Suit
+?>
+]]>
+
+
+
+
+ Wykaz wartości
+
+
+ Zarówno Pure Enums, jak i Backed Enums implementują wewnętrzny interfejs o nazwie
+ UnitEnum. UnitEnum zawiera statyczną metodę
+ cases(). cases() returns a packed array of
+ zwraca spakowaną tablicę wszystkich zdefiniowanych Cases w kolejności deklaracji.
+
+
+
+
+]]>
+
+
+ Ręczne zdefiniowanie metody cases() na Enum spowoduje błąd krytyczny.
+
+
+
+ Serializacja
+
+
+ Wyliczenia są serializowane inaczej niż obiekty. W szczególności mają one nowy kod serializacji,
+ "E", który określa nazwę case enuma. Procedura deserializacji może następnie
+ użyć tego do ustawienia zmiennej na istniejącą pojedynczą wartość. Zapewnia to, że:
+
+
+
+
+]]>
+
+
+
+ Podczas deserializacji, jeśli nie można znaleźć enuma i case pasującego do zserializowanej
+ wartości, zostanie wyświetlone ostrzeżenie i zwrócone &false;.
+
+
+ Jeśli Pure Enum jest serializowane do JSON, zostanie zgłoszony błąd. Jeśli Backed Enum
+ jest serializowane do JSON, będzie reprezentowane tylko przez jego wartość skalarną
+ w odpowiednim typie. Zachowanie obu może zostać zastąpione przez implementację
+ JsonSerializable.
+
+
+ Dla print_r, wynik case enuma jest nieco inny
+ niż obiektów, aby zminimalizować zamieszanie.
+
+
+
+ Bar
+)
+Baz Enum:int {
+ [name] => Beep
+ [value] => 5
+}
+*/
+?>
+]]>
+
+
+
+
+
+ Dlaczego enumy nie są rozszerzalne
+
+
+ Klasy mają umowy dotyczące swoich metod:
+
+
+
+
+]]>
+
+
+
+ Ten kod jest bezpieczny dla typów, ponieważ B podąża za kontraktem A, a dzięki magii
+ współbieżności/kontrawariancji, wszelkie oczekiwania, jakie można mieć wobec metod,
+ zostaną zachowane, z wyjątkiem wyjątków.
+
+
+
+ Enumy mają kontrakty dotycząc case, a nie metody:
+
+
+
+ true,
+ };
+}
+
+?>
+]]>
+
+
+
+ Instrukcja &match; w funkcji quux może być analizowana statycznie, aby objąć
+ wszystkie przypadki w ErrorCode.
+
+
+
+ Ale wyobraźmy sobie, że można rozszerzyć enumy:
+
+
+
+
+
+]]>
+
+
+
+ Zgodnie z normalnymi zasadami dziedziczenia, klasa, która rozszerza inną, przejdzie
+ kontrolę typu.
+
+
+
+ Problemem byłoby to, że instrukcja &match; w quux() nie obejmuje już wszystkich
+ case. Ponieważ nie wie o MoreErrorCode::PEBKAC match zgłosi wyjątek.
+
+
+
+ Z tego powodu wyliczenia są ostateczne i nie mogą być rozszerzane.
+
+
+
+
+ &reftitle.examples;
+
+
+
+ Podstawowe wartości ograniczone
+
+
+]]>
+
+
+ Funkcja query() może teraz działać bezpiecznie, wiedząc, że
+ $order jest gwarantowane jako SortOrder::Asc
+ lub SortOrder::Desc. Każda inna wartość spowodowałaby błąd
+ TypeError, więc nie jest potrzebne dalsze sprawdzanie błędów ani testowanie.
+
+
+
+
+
+
+
+ Zaawansowane wyłączne wartości
+
+
+ 'Pending',
+ self::Active => 'Active',
+ self::Suspended => 'Suspended',
+ self::CanceledByUser => 'Canceled by user',
+ };
+ }
+}
+?>
+]]>
+
+
+
+ W tym przykładzie status użytkownika może być jednym z, i wyłącznie UserStatus::Pending,
+ UserStatus::Active, UserStatus::Suspended, lub
+ UserStatus::CanceledByUser. Funkcja może wpisać parametr względem
+ UserStatus a następnie zaakceptować tylko te cztery wartości.
+
+
+
+ Wszystkie cztery wartości mają metodę label(), która zwraca ciąg znaków czytelny dla człowieka.
+ Ciąg ten jest niezależny od skalarnego odpowiednika ciągu "machine name", który może być użyty na przykład
+ w polu bazy danych lub polu wyboru HTML.
+
+
+
+%s\n', $case->value, $case->label());
+}
+?>
+]]>
+
+
+
+
+
+
+
+
+
diff --git a/language/fibers.xml b/language/fibers.xml
new file mode 100644
index 00000000..9fac1445
--- /dev/null
+++ b/language/fibers.xml
@@ -0,0 +1,97 @@
+
+
+
+
+ Fibers
+
+
+ Przegląd fiberów
+
+
+ Fibery reprezentują pełnostosowe, przerywalne funkcje. Fibery mogą być zawieszane z dowolnego miejsca
+ w stosie wywołań, wstrzymując wykonywanie w ramach fiber do momentu wznowienia fiber w późniejszym czasie.
+
+
+ Fibery wstrzymują cały stos wykonawczy, więc bezpośredni wywołujący funkcję nie musi zmieniać
+ sposobu jej wywoływania.
+
+
+ Wykonanie może zostać przerwane w dowolnym miejscu stosu wywołań przy użyciu Fiber::suspend
+ (oznacz to, że wywołanie Fiber::suspend może znajdować się w głęboko zagnieżdżonej funkcji
+ lub w ogóle nie istnieć).
+
+
+ W przeciwieństwie do bezstosowych Generatorów, każdy Fiber ma swój własny stos wywołań,
+ co pozwala na ich wstrzymywanie w ramach głęboko zagnieżdżonych wywołań funkcji. Funkcja deklarująca punkt przerwania
+ (czyli wywołująca Fiber::suspend) nie musi zmieniać swojego typu zwracanego, w przeciwieństwie do funkcji używającej
+ &yield; która musi zwracać instancję Generator.
+
+
+ Fibery można zawiesić w dowolnym wywołaniu funkcji, w tym tych wywoływanych z poziomu maszyny wirtualnej PHP, takich jak funkcje
+ przekazywane do array_map lub metody wywoływane przez &foreach; na obiekcie
+ Iterator.
+
+
+ Po zawieszeniu, wykonywanie fiber może zostać wznowione z dowolną wartością przy użyciu Fiber::resume
+ lub poprzez rzucenie wyjątku do fiber przy użyciu Fiber::throw. Wartość jest zwracana
+ (lub rzucany jest wyjątek) z Fiber::suspend.
+
+
+
+ Przed PHP 8.4.0, przełączanie fiber podczas wykonywania obiektu
+ destructor nie było
+ dozwolone.
+
+
+
+
+ Podstawowe użycie
+
+ start();
+
+echo "Value from fiber suspending: ", $value, PHP_EOL;
+
+$fiber->resume('test');
+?>
+]]>
+
+ &example.outputs;
+
+
+
+
+
+
+
+
+
+
diff --git a/language/generators.xml b/language/generators.xml
new file mode 100644
index 00000000..76c6f056
--- /dev/null
+++ b/language/generators.xml
@@ -0,0 +1,606 @@
+
+
+
+
+ Generators
+
+
+ Przegląd generatorów
+
+
+
+ Generatory zapewniają łatwy sposób implementacji prostych
+ iteratorów without the
+ bez narzutu lub złożoności implementacji klasy, która implementuje interfejs
+ Iterator.
+
+
+
+ Generator oferuje wygodny sposób dostarczania danych do pętli &foreach; bez konieczności
+ budowania tablicy w pamięci z wyprzedzeniem, co może spowodować przekroczenie limitu pamięci
+ przez program lub wymagać znacznej ilości czasu przetwarzania w celu wygenerowania.
+ Zamiast tego można użyć funkcji generatora,
+ która jest taka sama jak zwykła
+ funkcja, z tym wyjątkiem,
+ że zamiast
+ zwracaćraz,
+ generator może &yield; tyle razy, ile potrzebuje, aby dostarczyć
+ wartości do iteracji.
+ Podobnie jak w przypadku iteratorów, losowy dostęp do danych nie jest możliwy.
+
+
+
+ Prostym tego przykładem jest ponowne zaimplementowanie funkcji range
+ jako generatora. Standardowa funkcja range
+ musi wygenerować tablicę z każdą wartością i zwrócić ją, co może
+ skutkować dużymi tablicami: na przykład wywołanie
+ range(0, 1000000) spowoduje użycie ponad
+ 100 MB pamięci.
+
+
+
+ Alternatywnie, możemy zaimplementować generator xrange(),
+ który będzie potrzebował tylko tyle pamięci, aby utworzyć obiekt
+ Iterator i śledzenia bieżącego stanu
+ generatora wewnętrznie, co okazuje się być mniej niż 1 kilobajt..
+
+
+
+ Implementowanie range jako generator
+
+= 0) {
+ throw new LogicException('Step must be negative');
+ }
+
+ for ($i = $start; $i >= $limit; $i += $step) {
+ yield $i;
+ }
+ }
+}
+
+/*
+ * Zauważ, że zarówno range() jak i xrange() dają ten sam
+ * wynik poniżej.
+ */
+
+echo 'Single digit odd numbers from range(): ';
+foreach (range(1, 9, 2) as $number) {
+ echo "$number ";
+}
+echo "\n";
+
+echo 'Single digit odd numbers from xrange(): ';
+foreach (xrange(1, 9, 2) as $number) {
+ echo "$number ";
+}
+?>
+]]>
+
+ &example.outputs;
+
+
+
+
+
+
+ Obiekty Generator
+
+ Po wywołaniu funkcji generatora zwracany jest nowy obiekt wewnętrznej klasy
+ Generator. Obiekt ten implementuje interfejs
+ Iterator w taki sam sposób, jak obiekt iteratora
+ typu forward-only i udostępnia metody, które mogą być
+ wywoływane w celu manipulowania stanem generatora, w tym wysyłania do niego
+ wartości i zwracania z niego wartości.
+
+
+
+
+
+ Składnia generatora
+
+
+ Funkcja generatora wygląda jak zwykła funkcja, z tą różnicą, że zamiast zwracać wartość,
+ instrukcja generatora &yield; zwraca tyle wartości, ile potrzebuje.
+ Każda funkcja zawierająca &yield; jest funkcją generatora.
+
+
+
+ Gdy wywoływana jest funkcja generatora, zwraca ona obiekt, nad którym
+ można iterować. Podczas iteracji nad tym obiektem (na przykład za pomocą pętli
+ &foreach;), PHP wywoła metody iteracyjne obiektu za każdym razem, gdy będzie potrzebować
+ wartości, a następnie zapisze stan generatora, gdy generator zwróci wartość,
+ aby można go było wznowić, gdy wymagana jest następna wartość.
+
+
+
+ Gdy nie ma już więcej wartości do zwrócenia, generator
+ może po prostu powrócić, a kod wywołujący jest kontynuowany tak,
+ jakby skończyły się wartości tablicy.
+
+
+
+
+ Generator może zwracać wartości, które mogą być pobierane za pomocą
+ Generator::getReturn.
+
+
+
+
+ yield keyword
+
+
+ Sercem funkcji generatora jest słowo kluczowe yield.
+ W swojej najprostszej formie, instrukcja yield wygląda podobnie
+ do instrukcji return, z tą różnicą, że zamiast zatrzymywać wykonywanie funkcji i
+ powracać, yield zamiast tego dostarcza wartość do kodu pętli nad generatorem i
+ wstrzymuje wykonywanie funkcji generatora.
+
+
+
+ Prosty przykład zwracania wartości
+
+
+]]>
+
+ &example.outputs;
+
+
+
+
+
+
+
+ Wewnętrznie, sekwencyjne klucze całkowite zostaną sparowane z zwracanymi
+ wartościami, tak jak w przypadku tablicy nieasocjacyjnej.
+
+
+
+
+ Zwracanie wartości z kluczami
+
+
+ PHP również obsługuje tablice asocjacyjne, a generatory niczym się od nich nie różnią.
+ Oprócz zwracania prostych wartości, jak pokazano powyżej, można również zwracać
+ klucz w tym samym czasie.
+
+
+
+ Składnia do zwracania pary klucz/wartość jest bardzo podobna do tej używanej do
+ definiowania tablicy asocjacyjnej, jak pokazano poniżej.
+
+
+
+ Zwracanie pary klucz/wartość
+
+ $fields;
+ }
+}
+
+foreach (input_parser($input) as $id => $fields) {
+ echo "$id:\n";
+ echo " $fields[0]\n";
+ echo " $fields[1]\n";
+}
+?>
+]]>
+
+ &example.outputs;
+
+
+
+
+
+
+
+ Zwracanie wartości null
+
+
+ Yield można wywołać bez argumentu, aby zwrócić wartość &null; z
+ automatycznym kluczem.
+
+
+
+ Zwracanie &null;
+
+
+]]>
+
+ &example.outputs;
+
+
+ NULL
+ [1]=>
+ NULL
+ [2]=>
+ NULL
+}
+]]>
+
+
+
+
+
+ Zwracanie przez referencję
+
+
+ Funkcje generatora są w stanie zwrócić wartości przez odniesienie, jak również przez
+ wartość. Odbywa się to w taki sam sposób jak
+ zwracanie referencji z funkcji:
+ poprzez dodanie znaku ampersand do nazwy funkcji.
+
+
+
+ Zwracanie wartości przez referencję
+
+ 0) {
+ yield $value;
+ }
+}
+
+/*
+ * Zauważ, że możemy zmienić $number wewnątrz pętli, i
+ * ponieważ generator zwraca referencje, $value
+ * w gen_reference() ulega zmianie.
+ */
+foreach (gen_reference() as &$number) {
+ echo (--$number).'... ';
+}
+?>
+]]>
+
+ &example.outputs;
+
+
+
+
+
+
+
+ Delegacja generatora poprzez yield from
+
+
+ Delegacja generatora pozwala na uzyskanie wartości z innego
+ generatora, obiektu Traversable lub
+ tablicy za pomocą słowa kluczowego yield from.
+ Zewnętrzny generator zwróci następnie wszystkie wartości z wewnętrznego generatora,
+ obiektu lub tablicy, dopóki nie przestaną one być ważne, po czym wykonanie
+ będzie kontynuowane w zewnętrznym generatorze.
+
+
+
+ Jeśli generator jest używany z yield from, wyrażenie
+ yield from zwróci również każdą wartość zwróconą
+ przez wewnętrzny generator.
+
+
+
+ Zapisywanie do tablicy (np. za pomocą funkcji iterator_to_array)
+
+
+ yield from nie resetuje kluczy. Zachowuje
+ klucze zwrócone przez obiekt Traversable lub
+ tablicę. Tak więc niektóre wartości mogą mieć wspólny klucz z innym
+ yield lub yield from, który po
+ wstawieniu do tablicy nadpisze poprzednie wartości tym kluczem.
+
+
+
+ Częstym przypadkiem, w którym ma to znaczenie jest funkcja iterator_to_array
+ zwracająca domyślnie tablicę z kluczem, co może prowadzić do nieoczekiwanych wyników.
+ iterator_to_array ma drugi parametr
+ preserve_keys który można ustawić na &false;, aby zebrać
+ wszystkie wartości, ignorując klucze zwrócone przez Generator.
+
+
+
+ yield from z iterator_to_array
+
+
+]]>
+
+ &example.outputs;
+
+
+ int(1)
+ [1]=>
+ int(4)
+ [2]=>
+ int(3)
+}
+]]>
+
+
+
+
+
+ Podstawowe użycie yield from
+
+
+]]>
+
+ &example.outputs;
+
+
+
+
+
+
+ yield from i zwracane wartości
+
+getReturn();
+?>
+]]>
+
+ &example.outputs;
+
+
+
+
+
+
+
+
+
+ Porównanie generatorów z obiektami Iterator
+
+
+ Podstawową zaletą generatorów jest ich prostota. W porównaniu
+ do implementacji klasy Iterator należy napisać znacznie
+ mniej standardowego kodu, a kod jest ogólnie bardziej czytelny.
+ readable. Na przykład, poniższa funkcja i klasa są równoważne:
+
+
+
+
+fileHandle = fopen($fileName, 'r')) {
+ throw new RuntimeException('Couldn\'t open file "' . $fileName . '"');
+ }
+ }
+
+ public function rewind() {
+ fseek($this->fileHandle, 0);
+ $this->line = fgets($this->fileHandle);
+ $this->i = 0;
+ }
+
+ public function valid() {
+ return false !== $this->line;
+ }
+
+ public function current() {
+ return $this->line;
+ }
+
+ public function key() {
+ return $this->i;
+ }
+
+ public function next() {
+ if (false !== $this->line) {
+ $this->line = fgets($this->fileHandle);
+ $this->i++;
+ }
+ }
+
+ public function __destruct() {
+ fclose($this->fileHandle);
+ }
+}
+?>
+]]>
+
+
+
+
+ Ta elastyczność ma jednak swoją cenę: generatory są iteratorami tylko do przodu
+ i nie można ich przewinąć po rozpoczęciu iteracji. Oznacza to również,
+ że ten sam generator nie może być iterowany wielokrotnie:
+ generator będzie musiał zostać odbudowany poprzez ponowne wywołanie funkcji generatora.
+
+
+
+ &reftitle.seealso;
+
+
+ Iteracja obiektu
+
+
+
+
+
+
+
+
diff --git a/language/namespaces.xml b/language/namespaces.xml
new file mode 100644
index 00000000..9a13f1cd
--- /dev/null
+++ b/language/namespaces.xml
@@ -0,0 +1,1567 @@
+
+
+
+
+ Przestrzenie nazw
+
+
+ Przegląd przestrzeni nazw
+ Przegląd
+
+
+ Czym są przestrzenie nazw? W najszerszej definicji przestrzenie nazw są sposobem enkapsulacji
+ elementów. Może to być postrzegane jako abstrakcyjna koncepcja w wielu miejscach. Na przykład w każdym
+ ystemie 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
+ może istnieć zarówno w katalogu /home/greg jak i w /home/other,
+ ale dwie kopie foo.txt nie mogą współistnieć 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
+ rozciąga się na przestrzenie nazw w świecie programowania.
+
+
+
+ W świecie PHP przestrzenie nazw zostały zaprojektowane w celu rozwiązania dwóch problemów,
+ które napotykają autorzy bibliotek i aplikacji podczas tworzenia elementów kodu wielokrotnego użytku,
+ takich jak klasy lub funkcje:
+
+
+
+
+
+ Kolizje nazw między tworzonym kodem a wewnętrznymi
+ klasami/funkcjami/stałymi PHP lub klasami/funkcjami/stałymi innych firm.
+
+
+
+
+ Możliwość aliasowania (lub skracania) Extra_Long_Names ma na celu złagodzenie pierwszego problemu,
+ poprawiając czytelność kodu źródłowego.
+
+
+
+
+
+ Przestrzenie nazw PHP umożliwiają grupowanie powiązanych klas, interfejsów,
+ funkcji i stałych. Oto przykład składni przestrzeni nazw w PHP:
+
+
+ Przykład składni przestrzeni nazw
+
+
+ ]]>
+
+
+
+
+ Wielkość liter w nazwach przestrzeni nazw nie ma znaczenia.
+
+
+
+
+ Nazwa przestrzeni nazw PHP i nazwy złożone zaczynające się
+ od tej nazwy (jak PHP\Classes) są zarezerwowane do wewnętrznego użytku języka
+ i nie powinny być używane w kodzie przestrzeni użytkownika.
+
+
+
+
+
+ Definiowanie przestrzeni nazw
+ Przestrzenie nazw
+
+
+ Chociaż każdy poprawny kod PHP może być zawarty w przestrzeni nazw, tylko następujące typy kodu
+ podlegają wpływowi przestrzeni nazw: klasy (w tym abstrakcje i traity), interfejsy, funkcje i stałe.
+
+
+ Przestrzenie nazw są deklarowane za pomocą słowa namespace
+ Plik zawierający przestrzeń nazw musi zadeklarować przestrzeń nazw na
+ początku pliku przed jakimkolwiek innym kodem - z jednym wyjątkiem:
+ słowem kluczowym .
+
+ Deklarowanie pojedynczej przestrzeni nazw
+
+
+]]>
+
+
+
+
+ W pełni kwalifikowane nazwy (tj. nazwy zaczynające się od odwrotnego ukośnika) nie są dozwolone
+ w deklaracjach przestrzeni nazw, ponieważ takie konstrukcje są interpretowane jako względne wyrażenia przestrzeni nazw.
+
+
+ Jedyną konstrukcją kodu dozwoloną przed deklaracją przestrzeni nazw jest instrukcja
+ declare służąca do definiowania kodowania pliku źródłowego.
+ Ponadto żaden kod spoza PHP nie może poprzedzać deklaracji przestrzeni nazw, w tym dodatkowe białe znaki:
+
+ Deklarowanie pojedynczej przestrzeni nazw
+
+
+
+]]>
+
+
+
+
+ Ponadto, w przeciwieństwie do innych konstrukcji PHP, ta sama przestrzeń nazw może być zdefiniowana
+ w wielu plikach, umożliwiając podział zawartości przestrzeni nazw w systemie plików.
+
+
+
+ Deklarowanie podprzestrzeni nazw
+ Podprzestrzenie nazw
+
+
+ Podobnie jak katalogi i pliki, przestrzenie nazw PHP również zawierają możliwość określenia
+ hierarchii nazw przestrzeni nazw. Tak więc, nazwa przestrzeni nazw może być zdefiniowana
+ z podpoziomami:
+
+ Deklarowanie pojedynczej przestrzeni nazw z hierarchią
+
+
+]]>
+
+
+ Powyższy przykład tworzy stałą MyProject\Sub\Level\CONNECT_OK,
+ klasę MyProject\Sub\Level\Connection i funkcję
+ MyProject\Sub\Level\connect.
+
+
+
+ Definiowanie wielu przestrzeni nazw w tym samym pliku
+ Definiowanie wielu przestrzeni nazw w tym samym pliku
+
+
+ W tym samym pliku można również zadeklarować wiele przestrzeni nazw. Istnieją dwie
+ dozwolone składnie.
+
+
+
+ Deklarowanie wielu przestrzeni nazw, prosta składnia kombinacji
+
+
+]]>
+
+
+
+
+ Ta składnia nie jest zalecana do łączenia przestrzeni nazw w jednym pliku.
+ Zamiast tego zaleca się użycie alternatywnej składni z nawiasami klamrowymi.
+
+
+
+ Deklarowanie wielu przestrzeni nazw, składnia z nawiasami klamrowymi
+
+
+]]>
+
+
+
+
+ Zdecydowanie odradza się łączenie wielu przestrzeni nazw w tym samym pliku.
+ Podstawowym przypadkiem użycia jest łączenie wielu skryptów PHP w tym samym
+ pliku.
+
+
+ W celu połączenia globalnego kodu bez przestrzeni nazw z kodem z przestrzenią nazw,
+ obsługiwana jest tylko składnia z nawiasami klamrowymi. Kod globalny powinien być
+ zawarty w instrukcji przestrzeni nazw bez nazwy przestrzeni nazw, jak w:
+
+ Deklarowanie wielu przestrzeni nazw i kod bez przestrzeni nazw
+
+
+]]>
+
+
+
+
+ Żaden kod PHP nie może istnieć poza nawiasami przestrzeni nazw, z wyjątkiem
+ otwierającej instrukcji declare.
+
+ Deklarowanie wielu przestrzeni nazw i kod bez przestrzeni nazw
+
+
+]]>
+
+
+
+
+
+ Korzystanie z przestrzeni nazw: Podstawy
+ Podstawy
+
+
+ Przed omówieniem korzystania z przestrzeni nazw, ważne jest, aby zrozumieć, w jaki sposób PHP
+ wie, który element przestrzeni nazw jest żądany przez kod. Można dokonać prostej analogii
+ między przestrzeniami nazw PHP a systemem plików. Istnieją trzy sposoby dostępu do pliku w
+ systemie plików:
+
+
+
+ Względna nazwa pliku, taka jak foo.txt. Jest ona rozwiązana do
+ currentdirectory/foo.txt, gdzie currentdirectory jest
+ aktualnie zajmowanym katalogiem. Jeśli więc bieżącym katalogiem jest
+ /home/foo nazwa zostanie rozwiązana do /home/foo/foo.txt.
+
+
+
+
+ Względna nazwa ścieżki, taka jak subdirectory/foo.txt. To rozwiązuje do
+ currentdirectory/subdirectory/foo.txt.
+
+
+
+
+ Bezwzględna nazwa ścieżki, taka jak /main/foo.txt. To rozwiązuje się do
+ /main/foo.txt.
+
+
+
+ Ta sama zasada może być zastosowana do elementów w PHP. Na
+ przykład, nazwa klasy może być określona na trzy sposoby:
+
+
+
+ Niekwalifikowana nazwa lub nazwa klasy bez przedrostka, np.
+ $a = new foo(); lub
+ foo::staticmethod();. Jeśli bieżącą przestrzenią nazw jest
+ currentnamespace, to rozwiązuje do
+ currentnamespace\foo. Jeśli
+ kod jest kodem globalnym, bez przestrzeni nazw, jest to rozwiązuje do foo.
+
+
+ Jedno zastrzeżenie: niewykwalifikowane nazwy funkcji i stałych będą rozwiązywane
+ na globalne funkcje i stałe, jeśli funkcja lub stała z przestrzenią nazw nie jest
+ zdefiniowana. Zobacz Używanie przestrzeni
+ nazw: powrót do globalnej funkcji/stałej po szczegóły.
+
+
+
+
+ Nazwa kwalifikowana lub nazwa klasy z prefiksem, np.
+ $a = new subnamespace\foo(); lub
+ subnamespace\foo::staticmethod();. Jeśli bieżącą przestrzenią nazw jest
+ currentnamespace, rozwiązuje to do
+ currentnamespace\subnamespace\foo. Jeśli
+ kod jest kodem globalnym, bez przestrzeni nazw, to rozwiązuje do subnamespace\foo.
+
+
+
+
+ W pełni kwalifikowana nazwa lub nazwa z prefiksem z globalnym operatorem prefiksu,
+ takim jak $a = new \currentnamespace\foo(); lub
+ \currentnamespace\foo::staticmethod();. To zawsze rozwiązuje
+ do dosłownej nazwy określonej w kodzie currentnamespace\foo.
+
+
+
+
+
+ Oto przykład trzech rodzajów składni w rzeczywistym kodzie:
+
+ file1.php
+
+
+ ]]>
+
+ file2.php
+
+
+ ]]>
+
+
+
+
+ Należy pamiętać, że aby uzyskać dostęp do dowolnej globalnej
+ klasy, funkcji lub stałej, można użyć w pełni kwalifikowanej nazwy, takiej jak
+ \strlen lub \Exception lub
+ \INI_ALL.
+
+ Dostęp do globalnych klas, funkcji i stałych z przestrzeni nazw
+
+
+ ]]>
+
+
+
+
+
+ Przestrzenie nazw i dynamiczne funkcje języka
+ Przestrzenie nazw i dynamiczne funkcje języka
+
+
+ Na implementację przestrzeni nazw w PHP wpływa jego dynamiczna natura jako języka
+ programowania. Tak więc, aby przekonwertować kod taki jak poniższy przykład na kod z przestrzenią nazw:
+
+ Dynamiczny dostęp do elementów
+ example1.php:
+
+
+ ]]>
+
+
+ Należy użyć w pełni kwalifikowanej nazwy (nazwa klasy z prefiksem przestrzeni nazw).
+ Zauważ, że ponieważ nie ma różnicy między kwalifikowaną i w pełni kwalifikowaną Nazwą
+ wewnątrz dynamicznej nazwy klasy, nazwy funkcji lub nazwy stałej, wiodący odwrotny
+ ukośnik nie jest konieczny.
+
+ Dynamiczny dostęp do elementów z przestrzenią nazw
+
+
+ ]]>
+
+
+
+
+ Koniecznie przeczytaj uwagę o
+ uciekaniu nazw przestrzeni nazw w ciągach znaków.
+
+
+
+ Słowo kluczowe namespace i stała magiczna __NAMESPACE__
+ Słowo kluczowe namespace i stała magiczna __NAMESPACE__
+
+
+ PHP obsługuje dwa sposoby abstrakcyjnego dostępu do elementów w bieżącej przestrzeni nazw,
+ magiczną stałą __NAMESPACE__ i słowo kluczowe namespace
+ keyword.
+
+
+ Wartość __NAMESPACE__ jest ciągiem znaków, który zawiera bieżącą
+ namespace name. nazwę przestrzeni nazw. W globalnym kodzie bez przestrzeni nazw zawiera
+ on pusty ciąg znaków.
+
+ Przykłąd __NAMESPACE__, kod z przestrzenią nazw
+
+
+]]>
+
+
+
+ Przykład __NAMESPACE__, kod globalny
+
+
+]]>
+
+
+ Stała __NAMESPACE__ constant jest przydatna na przykład do dynamicznego
+ konstruowania nazw:
+
+ użycie __NAMESPACE__ do dynamicznego tworzenia nazw
+
+
+]]>
+
+
+
+
+ Słowo kluczowe namespace może być użyte do jawnego żądania
+ elementu z bieżącej przestrzeni nazw lub podprzestrzeni. Jest to odpowiednik
+ przestrzeni nazw operatora self dla klas.
+
+ operator namespace wewnątrz przestrzeni nazw
+
+
+]]>
+
+
+
+ operator namespace w kodzie globalnym
+
+
+]]>
+
+
+
+
+
+
+ Korzystanie z przestrzeni nazw: Aliasowanie/Importowanie
+ Aliasowanie i Importowanie
+
+
+ Możliwość odwoływania się do zewnętrznej w pełni kwalifikowanej nazwy za pomocą aliasu lub importowania
+ jest ważną cechą przestrzeni nazw. Jest to podobne do
+ zdolności uniksowych systemów plików do tworzenia dowiązań symbolicznych do pliku lub katalogu.
+
+
+ PHP może aliasować (/importować) stałe, funkcje, klasy, interfejsy, traity, enumy i przestrzenie nazw.
+
+
+ Aliasing jest wykonywany za pomocą operatora use.
+ Oto przykład pokazujący wszystkie 5 rodzajów importowania:
+
+ importowanie/aliasowanie za pomocą operatora use
+
+
+]]>
+
+
+ Należy zauważyć, że w przypadku nazw z przestrzenią nazw (w pełni kwalifikowane nazwy
+ przestrzeni nazw zawierające separator przestrzeni nazw, takie jak Foo\Bar
+ w przeciwieństwie do nazw globalnych, które tego nie robią, takich jak FooBar),
+ wiodący odwrotny ukośnik jest niepotrzebny i nie jest zalecany, ponieważ nazwy importu muszą być
+ w pełni kwalifikowane i nie są przetwarzane względem bieżącej przestrzeni nazw.
+
+
+ PHP dodatkowo obsługuje wygodny skrót do umieszczania wielu instrukcji
+ use w tej samej linii
+
+ importowanie/aliasing z operatorem use, wiele instrukcji use połączonych
+
+
+]]>
+
+
+
+
+ Importowanie jest wykonywane w czasie kompilacji, a więc nie ma wpływu na
+ dynamiczne nazwy klas, funkcji lub stałych.
+
+ Importowanie i nazwy dynamiczne
+
+
+]]>
+
+
+
+
+ Ponadto importowanie wpływa tylko na nazwy niewykwalifikowane i kwalifikowane. W pełni
+ kwalifikowane nazwy są bezwzględne i import nie ma na nie wpływu.
+
+ Importowanie i w pełni kwalifikowane nazwy
+
+
+]]>
+
+
+
+
+ Zasady dotyczące zakresu importowania
+
+ Słowo kluczowe use musi być zadeklarowane w najbardziej
+ zewnętrznym zakresie pliku (zakres globalny) lub wewnątrz deklaracji
+ przestrzeni nazw. Dzieje się tak, ponieważ importowanie odbywa się w czasie
+ kompilacji, a nie w czasie wykonywania, więc nie można go ograniczyć do zakresu bloku.
+ Poniższy przykład pokazuje nielegalne użycie słowa kluczowego
+ use:
+
+
+
+ Nielegalne zasady importowania
+
+
+]]>
+
+
+
+
+
+ Reguły importowania są oparte na plikach, co oznacza, że dołączone pliki
+ NIE odziedziczą reguły importowania pliku nadrzędnego.
+
+
+
+
+ Grupowe deklaracje use
+
+ Klasy, funkcje i stałe importowane z tej samej
+ &namespace; mogą być zgrupowane w jednej instrukcji
+ &use.namespace;.
+
+
+
+
+
+
+
+
+
+ Global space
+ Global space
+
+
+ Bez definicji przestrzeni nazw, wszystkie definicje klas i funkcji są
+ umieszczane w przestrzeni globalnej - tak jak to było w PHP przed obsługą
+ przestrzeni nazw. Przedrostek nazwy \ określi, że
+ nazwa jest wymagana z przestrzeni globalnej nawet w kontekście przestrzeni
+ nazw.
+
+ Używanie specyfikacji przestrzeni globalnej
+
+
+ ]]>
+
+
+
+
+
+ Korzystanie z przestrzeni nazw: powrót do przestrzeni globalnej dla funkcji i stałych
+ Powrót do przestrzeni globalnej
+
+
+ Wewnątrz przestrzeni nazw, gdy PHP napotka niewykwalifikowaną nazwę w kontekście nazwy klasy,
+ funkcji lub stałej, rozwiązuje je z różnymi priorytetami. Nazwy klas zawsze rozwiązywane są do
+ bieżącej nazwy przestrzeni nazw. Tak więc, aby uzyskać dostęp do wewnętrznych lub nieobjętych
+ przestrzenią nazw klas użytkownika, należy odwołać się do nich za pomocą ich w pełni kwalifikowanej nazwy, tak jak w:
+
+ Dostęp do klas globalnych wewnątrz przestrzeni nazw
+
+
+ ]]>
+
+
+
+
+ W przypadku funkcji i stałych, PHP powróci do funkcji lub stałych
+ globalnych, jeśli taka funkcja lub stała nie istnieje.
+
+ globalny powrót funkcji/stałych w przestrzeni nazw
+
+
+ ]]>
+
+
+
+
+
+
+ Zasady rozstrzygania nazw
+ Zasady rozstrzygania nazw
+
+
+ Dla celów niniejszych zasad dotyczących rozstrzygania, oto kilka ważnych definicji:
+
+ Definicje nazw przestrzeni nazw
+
+ Nazwa niekwalifikowana
+
+
+ Jest to identyfikator bez separatora przestrzeni nazw taki jak Foo
+
+
+
+
+ Nazwa kwalifikowana
+
+
+ Jest to identyfikator z separatorem przestrzeni nazw, taki jak Foo\Bar
+
+
+
+
+ W pełni kwalifikowana nazwa
+
+
+ Jest to identyfikator z separatorem przestrzeni nazw, który zaczyna się od separatora
+ przestrzeni nazw, na przykład \Foo\Bar. Przestrzeń nazw
+ \Foo jest również w pełni kwalifikowaną nazwą.
+
+
+
+
+ Nazwa względna
+
+
+ Jest to identyfikator zaczynający się od namespace, taki jak
+ namespace\Foo\Bar.
+
+
+
+
+
+
+ Nazwy są rozwiązywane zgodnie z tymi zasadami rozstrzygania:
+
+
+
+ W pełni kwalifikowane nazwy zawsze rozwiązują się do nazwy bez wiodącego separatora przestrzeni nazw.
+ Na przykład \A\B rozwiązuje do A\B.
+
+
+
+
+ Nazwy względne zawsze rozwiązują się do nazwy z namespace zastąpionym przez
+ bieżącą przestrzeń nazw. Jeśli nazwa występuje w globalnej przestrzeni nazw, prefiks
+ namespace\ jest usuwany. Na przykład namespace\A
+ wewnątrz przestrzeni nazw X\Y rozwiązuje do X\Y\A. Ta sama nazwa
+ wewnątrz globalnej przestrzeni nazw jest rozwiązywana jako A.
+
+
+
+
+ W przypadku nazw kwalifikowanych pierwszy segment nazwy jest tłumaczony zgodnie z bieżącą
+ tabelą importu klas/przestrzeni nazw. Na przykład, jeśli przestrzeń nazw A\B\C jest
+ importowana jako C, nazwa C\D\E jest tłumaczona na
+ A\B\C\D\E.
+
+
+
+
+ W przypadku nazw kwalifikowanych, jeśli nie ma zastosowania żadna reguła importu, bieżąca przestrzeń nazw
+ jest dodawana do nazwy. Na przykład, nazwa C\D\E wewnątrz przestrzeni nazw A\B,
+ rozwiązuje do A\B\C\D\E.
+
+
+
+
+ W przypadku nazw niewykwalifikowanych nazwa jest tłumaczona zgodnie z bieżącą tabelą importu
+ dla odpowiedniego typu symbolu. Oznacza to, że nazwy podobne do klas są tłumaczone zgodnie z
+ tabelą importu klas/przestrzeni nazw, nazwy funkcji zgodnie z tabelą importu funkcji, a stałe
+ zgodnie z tabelą importu stałych. Na przykład, po
+ use A\B\C; użycie takie jak new C() rozwiązuje się do nazwy
+ A\B\C(). Podobnie, po use function A\B\foo; użycie
+ takie jak foo() rozwiązuje do nazwy A\B\foo.
+
+
+
+
+ W przypadku nazw niewykwalifikowanych, jeśli nie ma zastosowania żadna reguła importu, a nazwa odnosi
+ się do symbolu podobnego do klasy, bieżąca przestrzeń nazw jest dodawana. Na przykład new C()
+ wewnątrz przestrzeni nazw A\B rozwiązuje do nazwy A\B\C.
+
+
+
+
+ W przypadku niewykwalifikowanych nazw, jeśli nie ma zastosowania żadna reguła importu, a nazwa
+ odnosi się do funkcji lub stałej, a kod znajduje się poza globalną przestrzenią nazw, nazwa jest rozwiązywana
+ w czasie wykonywania. Zakładając, że kod znajduje się w przestrzeni nazw A\B, oto jak
+ rozwiązywane jest wywołanie funkcji foo():
+
+
+
+
+ Wyszukuje funkcję z bieżącej przestrzeni nazw:
+ A\B\foo().
+
+
+
+
+ Próbuje znaleźć i wywołać funkcję globalną
+ foo().
+
+
+
+
+
+
+
+ Zilustrowane rozstrzygnięcia dotyczące nazw
+
+
+]]>
+
+
+
+
+ FAQ: rzeczy, które musisz wiedzieć o przestrzeniach nazw
+ FAQ
+
+
+ Ten FAQ jest podzielony na dwie sekcje: najczęściej zadawane pytania i niektóre szczegóły
+ implementacji, które są pomocne w pełnym zrozumieniu.
+
+
+ Po pierwsze, najczęstsze pytania.
+
+
+
+ Jeśli nie używam przestrzeni nazw, czy
+ powinienem się tym przejmować?
+
+
+
+
+ Jak używać klas wewnętrznych lub globalnych
+ przestrzeni nazw?
+
+
+
+
+ Jak używać klas przestrzeni
+ azw, funkcji lub stałych w ich własnych przestrzeniach nazw?
+
+
+
+
+
+ Jak rozwiązywana jest nazwa taka jak \my\name lub
+ \name?
+
+
+
+
+
+ W jaki sposób rozwiązywana jest
+ nazwa taka jak my\name?
+
+
+
+
+ W jaki sposób rozwiązywana jest
+ niewykwalifikowana nazwa klasy, taka jak name?
+
+
+
+
+ Jak rozwiązywana jest niewykwalifikowana
+ nazwa funkcji lub niewykwalifikowana nazwa stałej, taka jak
+ name?
+
+
+
+
+
+ Istnieje kilka szczegółów implementacji przestrzeni nazw,
+ które są pomocne do zrozumienia.
+
+
+
+ Nazwy importu nie mogą kolidować z
+ klasami zdefiniowanymi w tym samym pliku.
+
+
+
+
+ Zagnieżdżone przestrzenie nazw nie są dozwolone.
+
+
+
+
+
+ Dynamiczne nazwy przestrzeni nazw
+ (cytowane identyfikatory) powinny unikać odwrotnego ukośnika.
+
+
+
+
+ Niezdefiniowane stałe, do których
+ odwołuje się dowolny odwrotny ukośnik, giną z błędem krytycznym
+
+
+
+
+ Nie można nadpisać stałych
+ specjalnych &null;, &true; or &false;
+
+
+
+
+
+ Jeśli nie używam przestrzeni nazw, czy powinienem się tym przejmować?
+
+ nie. Przestrzenie nazw nie wpływają w żaden sposób na istniejący kod ani na kod,
+ który ma zostać napisany, a który nie zawiera przestrzeni nazw. Możesz
+ napisać taki kod, jeśli chcesz:
+
+
+
+ Dostęp do klas globalnych poza przestrzenią nazw
+
+
+]]>
+
+
+
+
+ Jest to funkcjonalnie równoważne:
+
+
+
+ Dostęp do klas globalnych poza przestrzenią nazw
+
+
+]]>
+
+
+
+
+
+ Jak używać klas wewnętrznych lub globalnych w przestrzeni nazw?
+
+
+ Dostęp do klas wewnętrznych w przestrzeniach nazw
+
+
+]]>
+
+
+
+
+
+
+ Jak używać klas, funkcji lub stałych przestrzeni nazw w ich własnych
+ przestrzeniach nazw?
+
+
+
+ Dostęp do wewnętrznych klas, funkcji lub stałych w przestrzeniach nazw
+
+
+]]>
+
+
+
+
+
+
+ Jak rozwiązywana jest nazwa taka jak \my\name lub
+ \name?
+
+
+ Nazwy rozpoczynające się od \ zawsze rozwiązują się tak,
+ jak wyglądają, więc \my\name to w rzeczywistości my\name,
+ i \Exception to Exception.
+
+ W pełni kwalifikowane nazwy
+
+
+]]>
+
+
+
+
+
+ Jak rozwiązywana jest nazwa taka jak my\name?
+
+ Nazwy zawierające odwrotny ukośnik, ale nie zaczynające się od odwrotnego ukośnika,
+ takie jak my\name mogą być rozwiązywane na 2 różne sposoby.
+
+
+ Jeśli istnieje
+ instrukcja importu, która aliasuje inną nazwę do my, to
+ alias importu jest stosowany do my w my\name.
+
+
+ W przeciwnym razie bieżąca nazwa przestrzeni nazw jest dodawana do my\name.
+
+
+
+ Kwalifikowane nazwy
+
+
+]]>
+
+
+
+
+
+ Jak rozwiązywana jest niewykwalifikowana nazwa klasy, taka jak name?
+
+ Nazwy klas, które nie zawierają odwrotnego ukośnika jak
+ name mogą być rozwiązywane na 2 różne sposoby.
+
+
+ Jeśli istnieje
+ instrukcja importu, która aliasuje inną nazwę do name, wówczas
+ alias importu jest stosowany.
+
+
+ W przeciwnym razie bieżąca nazwa przestrzeni nazw jest dodawana do name.
+
+
+
+ Niekwalifikowane nazwy klas
+
+
+]]>
+
+
+
+
+
+
+ Jak rozwiązywana jest niekwalifikowana nazwa funkcji lub niekwalifikowana nazwa stałej,
+ taka jak name?
+
+
+ Nazwy funkcji lub stałych, które nie zawierają odwrotnego ukośnika jak
+ name mogą być rozwiązywane na 2 różne sposoby.
+
+
+ Po pierwsze, bieżąca nazwa przestrzeni nazw jest dodawana do name.
+
+
+ Wreszcie, jeśli stała lub funkcja name nie istnieje
+ w bieżącej przestrzeni nazw, używana jest globalna stała lub funkcja name,
+ jeśli istnieje.
+
+
+
+ Niekwalifikowane nazwy funkcji lub stałych
+
+
+]]>
+
+
+
+
+
+ Nazwy importu nie mogą kolidować z klasami zdefiniowanymi w tym samym pliku.
+
+ Następujące kombinacje skryptów są legalne:
+
+ file1.php
+
+
+ ]]>
+
+ another.php
+
+
+ ]]>
+
+ file2.php
+
+
+ ]]>
+
+
+
+
+ Nie ma konfliktu nazw, mimo że klasa MyClass istnieje w
+ przestrzeni nazw my\stuff ponieważ definicja MyClass znajduje
+ się w osobnym pliku. Jednak następny przykład powoduje błąd krytyczny dotyczący
+ konfliktu nazw, ponieważ klasa MyClass jest zdefiniowana w tym samym pliku co instrukcja use.
+
+
+
+ ]]>
+
+
+
+
+
+ Zagnieżdżone przestrzenie nazw nie są dozwolone.
+
+ PHP nie pozwala na zagnieżdżanie przestrzeni nazw
+
+
+
+ ]]>
+
+
+ Łatwo jest jednak symulować zagnieżdżone przestrzenie nazw w ten sposób:
+
+
+
+ ]]>
+
+
+
+
+
+
+ Dynamiczne nazwy przestrzeni nazw (cytowane identyfikatory) powinny unikać odwrotnego ukośnika
+
+ Bardzo ważne jest, aby zdać sobie sprawę, że ponieważ odwrotny ukośnik jest używany jako znak ucieczki
+ w łańcuchach, zawsze powinien być podwojony, gdy jest używany wewnątrz łańcucha. W przeciwnym
+ razie istnieje ryzyko niezamierzonych konsekwencji:
+
+ Niebezpieczeństwa związane z używaniem nazw wewnątrz podwójnie cytowanego ciągu znaków
+
+
+ ]]>
+
+
+ Wewnątrz ciągów zanków w pojedynczych cudzysłowach, sekwencja ucieczki
+ odwrotnego ukośnika jest znacznie bezpieczniejsza w użyciu, ale nadal
+ zaleca się ucieczkę odwrotnego ukośnika we wszystkich ciągach znaków jako najlepszą praktykę.
+
+
+
+ Niezdefiniowane stałe, do których odwołuje się dowolny odwrotny ukośnik, giną z błędem krytycznym
+
+ Każda niezdefiniowana stała, która nie jest kwalifikowana, jak FOO spowoduje
+ wyświetlenie powiadomienia wyjaśniającego, że PHP przyjęło FOO was the value
+ jako wartość stałej. Każda stała, kwalifikowana lub w pełni kwalifikowana, która zawiera
+ odwrotny ukośnik, spowoduje błąd krytyczny, jeśli nie zostanie znaleziona.
+
+ Niezdefiniowane stałe
+
+
+ ]]>
+
+
+
+
+
+ Nie można nadpisać stałych specjalnych &null;, &true; or &false;
+
+ Każda próba zdefiniowania stałej w przestrzeni nazw, która jest specjalną, wbudowaną
+ stałą, skutkuje błędem krytycznym
+
+ Undefined constants
+
+
+ ]]>
+
+
+
+
+
+
+
+