PHP globalnie w funkcjach

101

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ż globaltemat pojawia się od czasu do czasu, możemy użyć dobrej „kanonicznej” odpowiedzi, aby utworzyć link.

Pascal Qyy
źródło
2
spójrz na ten link: stackoverflow.com/questions/1557787 Istnieje wiele powiązanych artykułów w prawym dolnym rogu tej strony
JohnP
To nie jest bezpośrednia odpowiedź na twoje pytanie, ale przeczytaj to starsze pytanie SO .
Ólafur Waage
1
Nie mogę więc odczytać żadnego pro-globalnego słowa kluczowego. 1) Dlaczego tu jest. 2) Dlaczego ludzie go używają?
Pascal Qyy
@ G.Qyy Dlaczego tam jest goto? Dlaczego ludzie go używają? Nie używają go (przynajmniej mam nadzieję): P
PeeHaa
Pod koniec ubiegłego roku (14 grudnia) ktoś przegłosował to pytanie. Bardzo mnie interesuje, dlaczego, bo wszystkie punkty widzenia, w tym negatywne, są interesujące. W tym przypadku bardziej niż kiedykolwiek! Będę bardzo wdzięczny za jakąkolwiek wskazówkę na ten temat.
Pascal Qyy,

Odpowiedzi:

159

Globale są źli

Dotyczy to globalsł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, np

function fn()
{
    global $foo;              // never ever use that
    $a = SOME_CONSTANT        // do not use that
    $b = Foo::SOME_CONSTANT;  // do not use that unless self::
    $c = $GLOBALS['foo'];     // incl. any other superglobal ($_GET, …)
    $d = Foo::bar();          // any static call, incl. Singletons and Registries
}

Wszystko 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 $_GETlub $_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

function fn()

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:

function fn($arg1, $arg2)
{
    // do sth with $arguments
}

jasno przekazuje z podpisu, czego wymaga nazwa. Znajdowanie się w określonym stanie nie jest zależne od środowiska. Nie musisz tego robić

$arg1 = 'foo';
$arg2 = 'bar';
fn();

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 $onewewną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ę

function fn()
{
    global $foo;
    echo $foo;     // side effect: echo'ing
    $foo = 'bar';  // side effect: changing
}

A potem robisz

$foo = 'foo';
fn(); // prints foo
fn(); // prints bar <-- WTF!!

Nie ma sposobu, aby zobaczyć, że $foozmienił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:

Gordon
źródło
10
Dlaczego PHP implementuje takie rzeczy? Czy jest narzędzie? Zawsze zaskakują mnie niebezpieczne implementacje w PHP, z których korzysta wiele osób za każdym razem ... Trudno mi uwierzyć, że nie ma żadnych logicznych powodów!
Pascal Qyy
6
Chciałbym, żebyś mógł sprawić, że Globals są większe.
Kermit
3
Wow, w końcu ktoś dobrze wyjaśnił, dlaczego globale są źli ... Zawsze słyszałem, że tak jest i widziałem kilka bardzo konkretnych przykładów, dlaczego, ale to naprawdę dobre i wyczerpujące wyjaśnienie ogólnego powodu. +1
Wingblade
Jestem naprawdę spóźniony i trochę rozumiem, o czym mówisz, ale co z połączeniami mysqli? Czy powinny one być przekazywane za każdym razem jako parametr, czy jest to globalne łącze $; dozwolone w twoich oczach?
Mave
2
Masz rację, z wyjątkiem stałych. Nie reprezentują „stanu” aplikacji i można do nich odwoływać się z poziomu funkcji. Funkcja nie „kłamie”, jeśli używa stałej od wewnątrz. Zgadzam się, że sugeruje to, że programista w pewnym momencie miał wiedzę z zewnątrz, ale to bardzo akceptowalny kompromis za to, czym jest stała. Poważnie, to nie jest zbyt wielka sprawa.
Sebas
35

Jedynym ważnym powodem globaljest to, że oznacza to, że funkcja jest zależna od innego zakresu. To bardzo szybko się zabrudzi.

$str1 = 'foo';
$str2 = 'bar';
$str3 = exampleConcat();

vs.

$str = exampleConcat('foo', 'bar');

Wymaganie $str1i $str2ustawienie 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.

globalto zły wzorzec, nawet jeśli chodzi o uwzględnianie globalnych rzeczy, takich jak $dbzasoby. 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.

zamrozić
źródło
1
Przepraszam, ale dlaczego na pewno miałbym chcieć zmienić nazwę $db? To PDO, rozpowszechniane wszędzie. Dlaczego miałoby się to zmieniać, skoro mogę oddzielnie aktualizować informacje o połączeniu?
Casey Dwayne,
3
@kcd Ponieważ pewnego dnia zdajesz sobie sprawę, jak wielki jest zastrzyk zależności i chcesz zrestrukturyzować swoją aplikację? Ponieważ pewnego dnia będziesz musiał zintegrować swoje rzeczy z innymi rzeczami, które również używają $dbzmiennej 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.
deceze
35

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:

class DecoratorPluginManager extends AbstractPluginManager
{
/**
 * Default set of decorators
 *
 * @var array
 */
protected $invokableClasses = array(
    'htmlcloud' => 'Zend\Tag\Cloud\Decorator\HtmlCloud',
    'htmltag'   => 'Zend\Tag\Cloud\Decorator\HtmlTag',
    'tag'       => 'Zend\Tag\Cloud\Decorator\HtmlTag',
   );

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:

/**
 * @file
 * Initiates a browser-based installation of Drupal.
 */

/**
 * Root directory of Drupal installation.
 */
define('DRUPAL_ROOT', getcwd());

/**
 * Global flag to indicate that site is in installation mode.
 */
define('MAINTENANCE_MODE', 'install');

// Exit early if running an incompatible PHP version to avoid fatal errors.
if (version_compare(PHP_VERSION, '5.2.4') < 0) {
  print 'Your PHP installation is too old. Drupal requires at least PHP 5.2.4. See the     <a     href="http://drupal.org/requirements">system requirements</a> page for more     information.';
  exit;
}

// Start the installer.
require_once DRUPAL_ROOT . '/includes/install.core.inc';
install_drupal();

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:

function xzy($var){
 global $z;
 $z = $var;
}

function setZ($var){
 $this->z = $var;
}

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.

Loek Bergman
źródło
Przykładowy kod Drupala nie używa globalnych, używa stałych. Bardzo ważną różnicą jest to, że stałej nie można przedefiniować po jej zdefiniowaniu. Nie możesz też po prostu porównać funkcji xyzi setZ. Pierwsza zmienia stan globalny, druga jest metodą klasową i zmienia tylko stan instancji, do której została wywołana.
Arjan
@Arjen: jeśli szukasz słowa kluczowego global w Drupalu 7.14, otrzymasz setki trafień. To stary problem z ustawiaczami publicznymi: nie kontrolujesz miejsca, w którym są zmieniane, gdy już je upubliczniłeś. Zalecono, aby w ogóle ich nie używać lub zadeklarować je jako prywatne, aby nie można było ich później dodać.
Loek Bergman
@Arjan: z powodu mojego błędu w pisowni Twojego imienia nie otrzymałeś żadnego powiadomienia o mojej odpowiedzi. Teraz będziesz. :-)
Loek Bergman
@LoekBergman: Jest około 400 trafień na to słowo globalw 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ą globals w drupal 8.
Arjan
@LoekBergman Użyj seterów i pobierających. Konfiguracja nie zajmuje dużo czasu i pozwala innym, którzy używają Twojego kodu i być może rozszerzają Twoje klasy, na większą kontrolę. Kiedy już upublicznisz parametr, to wszystko. nie możesz go później ukryć.
mAsT3RpEE
15

Mówiąc najprościej, rzadko istnieje powód globali 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ń globalmożna i należy zastąpić iniekcją zależności lub po prostu przekazaniem obiektu globalnego jako parametru.

function getCustomer($db, $id) {
    $row = $db->fetchRow('SELECT * FROM customer WHERE id = '.$db->quote($id));
    return $row;
}
xzyfer
źródło
10

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.

jedność100
źródło
3
+1 dla anty-fundamentalizmu i tak dalej, ale powiedzenie po prostu „wielu ludzi to używa / to działa / itp.” Jest po prostu „argumentum ad populum”, podstawowym sofizmatem. fakt, że większość ludzi myśli lub robi jedną rzecz, nie dowodzi, że mają rację! w tłumie, jeśli pojawi się niebezpieczeństwo, większość ludzi zrobi głupie rzeczy, a niektórzy umrą zdeptani przez innych. Czy mają rację, stawiając stopę na twarzy tej pięcioletniej dziewczynki, tylko dlatego, że myślą, że muszą bezwzględnie pchać drzwi, które otwierają się tylko wtedy, gdy są pociągane, aby uciec przed ogniem? Nie sądzę…
Pascal Qyy
1
większość, która coś robi, oczywiście, sama z siebie niczego nie potwierdza. jednak sprawa jest oprogramowanie. a jeśli większość to robi, a większość aplikacji i usług stworzonych przez te osoby dobrze się trzyma (wordpress dla wielu innych), oznacza to, że można z nich korzystać.
jedność100
7

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:

  1. 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 od
    wersji 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.

  2. 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.

  3. 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.

  4. 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.

mAsT3RpEE
źródło
6

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:

function getCustomer($id) {
  global $db;
  $row = $db->fetchRow('SELECT * FROM customer WHERE id = '.$db->quote($id));
  return $row;
}

Może być używany jako wariacja na temat wzorca Singleton

Bob Fanger
źródło
„to nie ma sensu” - faktycznie tak: przykładem będzie implementacja tabeli przeglądowej bez użycia OOP.
Nir Alfasi