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 <literal>const</literal> + + +]]> + + + + + + + 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 <function>range</function> 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 <classname>Generator</classname> + + 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. + + + + + <command>yield</command> 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 <command>yield from</command> + + + 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 <function>iterator_to_array</function>) + + + 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. + + + + <command>yield from</command> z <function>iterator_to_array</function> + + +]]> + + &example.outputs; + + + int(1) + [1]=> + int(4) + [2]=> + int(3) +} +]]> + + + + + + Podstawowe użycie <command>yield from</command> + + +]]> + + &example.outputs; + + + + + + + <command>yield from</command> i zwracane wartości + +getReturn(); +?> +]]> + + &example.outputs; + + + + + + + + + + Porównanie generatorów z obiektami <classname>Iterator</classname> + + + 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 <literal>use</literal> + + 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 <literal>\my\name</literal> lub + <literal>\name</literal>? + + + 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 <literal>my\name</literal>? + + 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 <literal>name</literal>? + + 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 <literal>name</literal>? + + + 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 + + + ]]> + + + + + + + +