Jaka jest użyteczność słowa kluczowego global ?
Czy są jakieś powody, aby preferować jedną metodę od drugiej?
- Bezpieczeństwo?
- Występ?
- Coś jeszcze?
Metoda 1:
function exempleConcat($str1, $str2)
{
return $str1.$str2;
}
Metoda 2:
function exempleConcat()
{
global $str1, $str2;
return $str1.$str2;
}
Kiedy warto używać global
?
Dla mnie wydaje się to niebezpieczne ... ale może to być po prostu brak wiedzy. Interesują mnie udokumentowane (np. Przykład kodu, link do dokumentacji ...) przyczyny techniczne.
Z góry dziękuję!
Hojność
To fajne ogólne pytanie na ten temat, ja (@Gordon) oferuję nagrodę za dodatkowe odpowiedzi. Nie ma znaczenia, czy twoja odpowiedź jest zgodna z moją, czy też przedstawia inny punkt widzenia. Ponieważ global
temat pojawia się od czasu do czasu, możemy użyć dobrej „kanonicznej” odpowiedzi, aby utworzyć link.
php
language-design
Pascal Qyy
źródło
źródło
goto
? Dlaczego ludzie go używają? Nie używają go (przynajmniej mam nadzieję): POdpowiedzi:
Globale są źli
Dotyczy to
global
słowa kluczowego, a także wszystkiego, co sięga od zakresu lokalnego do zasięgu globalnego (statystyki, pojedyncze, rejestry, stałe). Nie chcesz ich używać. Wywołanie funkcji nie powinno polegać na niczym zewnętrznym, npWszystko to sprawi, że Twój kod będzie zależał od zewnątrz. Oznacza to, że musisz znać pełny stan globalny aplikacji, zanim będziesz mógł niezawodnie wywołać którykolwiek z nich. Funkcja nie może istnieć bez tego środowiska.
Używanie superglobali może nie być oczywistą wadą, ale jeśli wywołujesz swój kod z wiersza poleceń, nie masz
$_GET
lub$_POST
. Jeśli Twój kod opiera się na danych wejściowych z nich, ograniczasz się do środowiska internetowego. Po prostu wyodrębnij żądanie do obiektu i użyj go zamiast tego.W przypadku łączenia nazw klas zakodowanych na stałe (statyczne, stałe), Twoja funkcja również nie może istnieć bez tej klasy. To mniejszy problem, gdy są to klasy z tej samej przestrzeni nazw, ale kiedy zaczynasz mieszać z różnych przestrzeni nazw, tworzysz zagmatwany bałagan.
Ponowne wykorzystanie jest poważnie utrudnione przez wszystkie powyższe. Podobnie jest z testowaniem jednostkowym .
Ponadto sygnatury funkcji kłamią, gdy łączysz się z zakresem globalnym
jest kłamcą, ponieważ twierdzi, że mogę wywołać tę funkcję bez przekazywania jej czegokolwiek. Dopiero gdy patrzę na ciało funkcyjne, dowiaduję się, że muszę ustawić środowisko w określony stan.
Jeśli twoja funkcja wymaga argumentów do działania, wyraź je i przekaż w:
jasno przekazuje z podpisu, czego wymaga nazwa. Znajdowanie się w określonym stanie nie jest zależne od środowiska. Nie musisz tego robić
To kwestia wciągania (globalne słowo kluczowe), a nie wciskania (argumenty). Kiedy wciskasz / wstrzykujesz zależności, funkcja nie polega już na zewnętrzności. Kiedy to robisz
fn(1)
, nie musisz mieć zmiennej przechowującej 1 gdzieś na zewnątrz. Ale kiedy wciągasz global$one
wewnątrz funkcji, łączysz się z zakresem globalnym i oczekujesz, że będzie miał gdzieś zdefiniowaną zmienną. Funkcja nie jest już wtedy niezależna.Co gorsza, kiedy zmieniasz globale wewnątrz swojej funkcji, twój kod szybko stanie się całkowicie niezrozumiały, ponieważ twoje funkcje mają wszędzie skutki uboczne.
Wobec braku lepszego przykładu, zastanów się
A potem robisz
Nie ma sposobu, aby zobaczyć, że
$foo
zmieniło się to z tych trzech linii. Dlaczego wywołanie tej samej funkcji z tymi samymi argumentami nagle zmieniało jej dane wyjściowe lub zmieniało wartość w stanie globalnym? Funkcja powinna wykonać X dla zdefiniowanego wejścia Y. Zawsze.Staje się to jeszcze poważniejsze, gdy używasz OOP, ponieważ OOP dotyczy hermetyzacji i sięgając do zakresu globalnego, przerywasz hermetyzację. Wszystkie te singletony i rejestry, które widzisz w frameworkach to zapachy kodu, które powinny zostać usunięte na korzyść Dependency Injection. Odłącz swój kod.
Więcej zasobów:
static
uważane za szkodliweźródło
Jedynym ważnym powodem
global
jest to, że oznacza to, że funkcja jest zależna od innego zakresu. To bardzo szybko się zabrudzi.vs.
Wymaganie
$str1
i$str2
ustawienie w zakresie wywoływania, aby funkcja działała, oznacza wprowadzenie niepotrzebnych zależności. Nie możesz już zmieniać nazw tych zmiennych w tym zakresie bez zmiany ich nazw również w funkcji, a tym samym we wszystkich innych zakresach, których używasz tej funkcji. Wkrótce zamienia się to w chaos, gdy próbujesz śledzić nazwy swoich zmiennych.global
to zły wzorzec, nawet jeśli chodzi o uwzględnianie globalnych rzeczy, takich jak$db
zasoby. Nie będzie nadejdzie dzień, gdy chcesz zmienić nazwę$db
, ale nie mogę, bo cała aplikacja zależy od imienia.Ograniczanie i oddzielanie zakresu zmiennych jest niezbędne do pisania dowolnej częściowo złożonej aplikacji.
źródło
$db
? To PDO, rozpowszechniane wszędzie. Dlaczego miałoby się to zmieniać, skoro mogę oddzielnie aktualizować informacje o połączeniu?$db
zmiennej globalnej ? Ponieważ pewnego dnia odkryjesz testy jednostkowe i będziesz musiał zarządzać więcej niż jednym połączeniem z bazą danych naraz? Wiele, wiele powodów.Globale są nieuniknione.
To stara dyskusja, ale nadal chciałbym dodać kilka myśli, ponieważ brakuje mi ich w powyższych odpowiedziach. Te odpowiedzi upraszczają to, czym globalność jest za dużo i przedstawiają rozwiązania, które wcale nie są rozwiązaniami problemu. Problem w tym, że jaki jest właściwy sposób radzenia sobie ze zmienną globalną i użycie słowa kluczowego global? W tym celu musimy najpierw zbadać i opisać, czym jest globalność.
Spójrz na ten kod Zend - i proszę zrozumieć, że nie sugeruję, że Zend jest źle napisany:
Jest tu wiele niewidocznych zależności. Te stałe są w rzeczywistości klasami. Możesz również zobaczyć require_once na niektórych stronach tego frameworka. Require_once to zależność globalna, stąd tworzenie zależności zewnętrznych. Jest to nieuniknione w przypadku ram. Jak możesz stworzyć klasę taką jak DecoratorPluginManager bez dużej ilości zewnętrznego kodu, od którego to zależy? Nie może funkcjonować bez wielu dodatków. Używając frameworka Zend, czy kiedykolwiek zmieniłeś implementację interfejsu? Interfejs jest w rzeczywistości globalny.
Inną aplikacją używaną na całym świecie jest Drupal. Bardzo zależy im na odpowiednim zaprojektowaniu, ale tak jak w przypadku każdego dużego frameworka mają wiele zewnętrznych zależności. Spójrz na globale na tej stronie:
Napisałeś kiedyś przekierowanie do strony logowania? To zmienia globalną wartość. (A więc czy nie mówisz „WTF”, co uważam za dobrą reakcję na złą dokumentację twojej aplikacji). Problem z globalnymi nie polega na tym, że są one globalne, potrzebujesz ich, aby mieć sensowną aplikację. Problem polega na złożoności całej aplikacji, która może sprawić, że obsługa jest koszmarem. Sesje są globalne, $ _POST to globalny, DRUPAL_ROOT to globalny, a include / install.core.inc 'jest globalną niemodyfikowalną. Istnieje duży świat poza jakąkolwiek funkcją, która jest wymagana, aby pozwolić tej funkcji wykonać swoją pracę.
Odpowiedź Gordona jest nieprawidłowa, ponieważ przecenia niezależność funkcji, a nazwanie funkcji kłamcą zbytnio upraszcza sytuację. Funkcje nie kłamią, a kiedy spojrzymy na jego przykład, funkcja jest zaprojektowana nieprawidłowo - jego przykładem jest błąd. (Nawiasem mówiąc, zgadzam się z tym wnioskiem, że należy oddzielić kod.) Odpowiedź deceze nie jest tak naprawdę właściwą definicją sytuacji. Funkcje zawsze działają w szerszym zakresie, a jego przykład jest zbyt uproszczony. Wszyscy zgodzimy się z nim, że ta funkcja jest całkowicie bezużyteczna, ponieważ zwraca stałą. Ta funkcja jest w każdym razie złym projektem. Jeśli chcesz pokazać, że praktyka jest zła, podaj odpowiedni przykład. Zmiana nazw zmiennych w całej aplikacji to nic wielkiego, mając dobre IDE (lub narzędzie). Pytanie dotyczy zakresu zmiennej, a nie różnicy w zakresie z funkcją. Jest odpowiedni czas, aby funkcja spełniała swoją rolę w procesie (dlatego jest tworzona w pierwszej kolejności) i w tym odpowiednim czasie może wpływać na działanie aplikacji jako całości, a więc również na zmienne globalne . Odpowiedzią xzyfera jest stwierdzenie bez argumentacji. Globale są tak samo obecne w aplikacji, jeśli masz funkcje proceduralne lub projekt OOP. Kolejne dwa sposoby zmiany wartości globalnej są zasadniczo takie same: stąd też pracuje nad zmiennymi globalnymi. Odpowiedzią xzyfera jest stwierdzenie bez argumentacji. Globale są tak samo obecne w aplikacji, jeśli masz funkcje proceduralne lub projekt OOP. Kolejne dwa sposoby zmiany wartości globalnej są zasadniczo takie same: stąd też praca nad zmiennymi globalnymi. Odpowiedzią xzyfera jest stwierdzenie bez argumentacji. Globale są tak samo obecne w aplikacji, jeśli masz funkcje proceduralne lub projekt OOP. Kolejne dwa sposoby zmiany wartości globalnej są zasadniczo takie same:
W obu przypadkach wartość $ z zmienia się w ramach określonej funkcji. Na oba sposoby programowania możesz wprowadzić te zmiany w wielu innych miejscach w kodzie. Można powiedzieć, że używając global, możesz zadzwonić do $ z gdziekolwiek i tam się zmienić. Tak, możesz. Ale czy będziesz? A kiedy zrobi się to w nieodpowiednich miejscach, czy nie należy tego nazwać błędem?
Bob Fanger komentuje xzyfer.
Czy zatem ktoś powinien po prostu użyć czegokolwiek, a zwłaszcza słowa kluczowego „globalny”? Nie, ale tak jak w przypadku każdego rodzaju projektu, spróbuj przeanalizować, od czego to zależy, a co od tego zależy. Spróbuj dowiedzieć się, kiedy się zmienia i jak się zmienia. Zmiana wartości globalnych powinna mieć miejsce tylko w przypadku tych zmiennych, które mogą się zmieniać przy każdym żądaniu / odpowiedzi. To znaczy tylko do tych zmiennych, które należą do funkcjonalnego przepływu procesu, a nie do jego technicznej realizacji. Przekierowanie adresu URL do strony logowania należy do funkcjonalnego przepływu procesu, klasy implementacji używanej jako interfejs do implementacji technicznej. Możesz zmienić to drugie podczas różnych wersji aplikacji, ale nie należy zmieniać tych przy każdym żądaniu / odpowiedzi.
Aby lepiej zrozumieć, kiedy jest problem z pracą z globalnymi i słowem kluczowym global, a kiedy nie, przedstawię następne zdanie, które pochodzi od Wim de Bie pisząc o blogach: „Osobiste tak, prywatne nie”. Kiedy funkcja zmienia wartość zmiennej globalnej ze względu na swoje własne działanie, wtedy będę nazywać to prywatne użycie zmiennej globalnej i błąd. Ale kiedy zmiana zmiennej globalnej ma na celu poprawne przetworzenie aplikacji jako całości, jak przekierowanie użytkownika na stronę logowania, to moim zdaniem jest to możliwie dobry projekt, nie z definicji zły i na pewno nie anty-wzór.
Patrząc wstecz na odpowiedzi Gordona, deceze and xzyfer: wszyscy mają „prywatne tak” (i błędy) jako przykłady. Dlatego sprzeciwiają się używaniu globali. Ja też bym zrobił. Nie zawierają jednak przykładów „osobistych tak, prywatnych nie”, jak to robiłem w tej odpowiedzi kilka razy.
źródło
xyz
isetZ
. Pierwsza zmienia stan globalny, druga jest metodą klasową i zmienia tylko stan instancji, do której została wywołana.global
w drupal 7.26 (który jest najnowszą wersją), niektóre z tych trafień są w komentarzach, a kilka innych wydaje się być w kodzie, który nie był zmieniany od lat. Mam nadzieję, że nie użyjąglobal
s w drupal 8.Mówiąc najprościej, rzadko istnieje powód
global
i nigdy nie jest dobry we współczesnym kodzie PHP IMHO. Zwłaszcza jeśli używasz PHP 5. A szczególnie, jeśli tworzysz kod zorientowany obiektowo.Globale negatywnie wpływają na łatwość utrzymania, czytelność i testowalność kodu. Wiele zastosowań
global
można i należy zastąpić iniekcją zależności lub po prostu przekazaniem obiektu globalnego jako parametru.źródło
Nie wahaj się przed użyciem globalnego słowa kluczowego w funkcjach PHP. Szczególnie nie przyjmuj ludzi, którzy dziwnie nauczają / krzyczą, że globaliści są „źli” i tak dalej.
Po pierwsze, ponieważ to, czego używasz, całkowicie zależy od sytuacji i problemu, i nie ma jednego rozwiązania / sposobu, aby cokolwiek zrobić w kodowaniu. Całkowicie pomijając w równaniu błąd związany z nieokreślonymi, subiektywnymi, religijnymi przymiotnikami, takimi jak „zło”.
Przykładem :
Wordpress i jego ekosystem używają w swoich funkcjach globalnego słowa kluczowego. Bądź kodem OOP lub nie OOP.
Obecnie Wordpress stanowi w zasadzie 18,9% internetu i obsługuje ogromne megasites / aplikacje niezliczonych gigantów, od Reutera po Sony, NYT i CNN.
I robi to dobrze.
Użycie globalnego słowa kluczowego w funkcjach uwalnia Wordpress od MASYWNEGO nadmiaru, który miałby miejsce, biorąc pod uwagę jego ogromny ekosystem. Wyobraź sobie, że każda funkcja żądała / przekazywała dowolną zmienną, która jest potrzebna z innej wtyczki, rdzenia i zwracała. Dodane z współzależnościami wtyczek, które skończyłyby się koszmarem zmiennych lub koszmarem tablic przekazywanych jako zmienne. PIEKŁO do śledzenia, piekło do debugowania, piekło do opracowania. Niesamowicie olbrzymi ślad pamięci z powodu rozdęcia kodu i zmiennego rozdęcia. Trudniej też pisać.
Mogą pojawić się ludzie, którzy podejdą i krytykują Wordpress, jego ekosystem, ich praktyki i to, co dzieje się w tych częściach.
Bezcelowe, ponieważ ten ekosystem to prawie 20% mniej więcej całego internetu. Najwyraźniej DZIAŁA, wykonuje swoją pracę i nie tylko. Co oznacza to samo dla słowa kluczowego global.
Innym dobrym przykładem jest fundamentalizm „iframe is evil”. Dziesięć lat temu używanie iframe było herezją. W internecie były tysiące ludzi głoszących przeciwko nim. Potem pojawia się facebook, potem social, teraz ramki iframe są wszędzie, od pól „like” po uwierzytelnianie, i voila - wszyscy się zamknij. Są tacy, którzy wciąż się nie zamknęli - słusznie lub niesłusznie. Ale wiesz co, życie toczy się dalej pomimo takich opinii, a nawet ci, którzy dekadę temu opowiadali się przeciwko ramkom iframe, muszą teraz używać ich do integracji różnych aplikacji społecznościowych z aplikacjami własnej organizacji bez słowa.
......
Fundamentalizm kodera jest czymś bardzo, bardzo złym. Niewielki procent z nas może być zaszczycony wygodną pracą w solidnej monolitycznej firmie, która ma wystarczającą siłę, aby znieść ciągłe zmiany w technologii informacyjnej i presję, jaką niesie ze sobą w zakresie konkurencji, czasu, budżetu i innych względów, a zatem może ćwiczyć fundamentalizm i ścisłe trzymanie się postrzeganego „zła” lub „dobra”. Są to wygodne pozycje przypominające dawne czasy, nawet jeśli lokatorzy są młodzi.
Jednak dla większości świat IT to ciągle zmieniający się świat, w którym muszą być otwarci i praktyczni. Nie ma miejsca na fundamentalizm, odłóż na bok oburzające słowa kluczowe, takie jak „zło” na pierwszej linii frontu technologii informacyjnej.
Po prostu użyj tego, co najlepiej pasuje do problemu POD RĘKĄ, biorąc pod uwagę bliską, średnio i długoterminową przyszłość. Nie unikaj używania żadnej funkcji lub podejścia, ponieważ ma do niego szalejącą wrogość ideologiczną wśród dowolnego podzbioru programistów.
Nie wykonają twojej pracy. Będziesz. Postępuj zgodnie ze swoimi okolicznościami.
źródło
Myślę, że każdy dość dużo objaśnił negatywne aspekty globalności. Więc dodam pozytywy, a także instrukcje prawidłowego używania globali:
Głównym celem globals była wymiana informacji między funkcjami. Kiedyś nie istniało nic takiego jak klasa, kod PHP składał się z wielu funkcji. Czasami trzeba będzie udostępniać informacje między funkcjami. Zwykle do tego celu używano globalnego, co wiązało się z ryzykiem uszkodzenia danych przez uczynienie ich globalnymi.
Teraz, zanim jakiś szczęśliwy prostak zacznie komentować wstrzykiwanie zależności, chciałbym cię zapytać, w jaki sposób użytkownik funkcji takiej jak przykład
get_post(1)
znałby wszystkie zależności funkcji. Weź również pod uwagę, że zależności mogą się różnić w zależności odwersji i serwera. Głównym problemem związanym z wstrzykiwaniem zależności jest to, że zależności muszą być wcześniej znane. W sytuacji, gdy nie jest to możliwe lub niechciane zmienne globalne były jedynym sposobem na osiągnięcie tego celu.
Dzięki utworzeniu klasy, obecnie wspólne funkcje można łatwo grupować w klasę i udostępniać dane. Dzięki implementacjom takim jak mediatory nawet niepowiązane ze sobą obiekty mogą udostępniać informacje. Nie jest to już konieczne.
Innym zastosowaniem dla globali jest konfiguracja. Głównie na początku skryptu, przed załadowaniem jakichkolwiek autoloaderów, nawiązaniem połączeń z bazą danych itp.
Podczas ładowania zasobów, globale mogą być używane do konfigurowania danych (tj. Której bazy danych użyć, gdzie znajdują się pliki biblioteczne, adresu URL serwera itp.). Najlepszym sposobem na to jest użycie
define()
funkcji, ponieważ te wartości nie zmieniają się często i można je łatwo umieścić w pliku konfiguracyjnym.Ostatnim zastosowaniem dla globals jest przechowywanie wspólnych danych (tj. CRLF, IMAGE_DIR, IMAGE_DIR_URL), flag statusu czytelnych dla człowieka (tj. ITERATOR_IS_RECURSIVE). Tutaj wartości globalne są używane do przechowywania informacji, które mają być używane w całej aplikacji, co pozwala na ich zmianę i wyświetlanie tych zmian w całej aplikacji.
Wzorzec singleton stał się popularny w php podczas php4, kiedy każda instancja obiektu zajmowała pamięć. Singleton pomógł uratować pamięć RAM, umożliwiając utworzenie tylko jednej instancji obiektu. Przed odniesieniami nawet zastrzyk zależności byłby złym pomysłem.
Nowa implementacja obiektów PHP 5.4+ rozwiązuje większość z tych problemów, dzięki czemu można bezpiecznie przesyłać obiekty bez żadnych kar. Nie jest to już konieczne.
Innym zastosowaniem dla singletonów jest specjalna instancja, w której tylko jedna instancja obiektu musi istnieć w danym momencie, ta instancja może istnieć przed / po wykonaniu skryptu i ten obiekt jest współdzielony między różnymi skryptami / serwerami / językami itp. Tutaj wzorzec singletona rozwiązuje rozwiązanie całkiem nieźle.
Podsumowując, jeśli jesteś na pozycji 1, 2 lub 3, użycie globalnego byłoby rozsądne. Jednak w innych sytuacjach należy zastosować metodę 1.
Nie wahaj się zaktualizować innych przypadków, w których powinny być używane globalne.
źródło
Nie ma sensu tworzenie funkcji konkatacji przy użyciu słowa kluczowego global.
Służy do uzyskiwania dostępu do zmiennych globalnych, takich jak obiekt bazy danych.
Przykład:
Może być używany jako wariacja na temat wzorca Singleton
źródło