Was ist der Nutzen des globalen Schlüsselworts ?
Gibt es Gründe, eine Methode einer anderen vorzuziehen?
- Sicherheit?
- Performance?
- Noch etwas?
Methode 1:
function exempleConcat($str1, $str2)
{
return $str1.$str2;
}
Methode 2:
function exempleConcat()
{
global $str1, $str2;
return $str1.$str2;
}
Wann ist die Verwendung sinnvoll global
?
Für mich scheint es gefährlich zu sein ... aber es kann nur ein Mangel an Wissen sein. Ich interessiere mich für dokumentierte (zB mit Codebeispiel, Link zur Dokumentation ...) technische Gründe.
Danke im Voraus!
Kopfgeld
Dies ist eine nette allgemeine Frage zum Thema. Ich (@Gordon) biete ein Kopfgeld an, um zusätzliche Antworten zu erhalten. Ob Ihre Antwort mit meiner übereinstimmt oder einen anderen Standpunkt vertritt, spielt keine Rolle. Da das global
Thema hin und wieder auftaucht, könnten wir eine gute "kanonische" Antwort verwenden, um darauf zu verlinken.
php
language-design
Pascal Qyy
quelle
quelle
goto
? Warum benutzen die Leute es? Sie benutzen es nicht (ich hoffe zumindest): PAntworten:
Globals sind böse
Dies gilt sowohl für das
global
Schlüsselwort als auch für alles andere, was von einem lokalen bis zu einem globalen Bereich reicht (Statik, Singletons, Register, Konstanten). Sie möchten sie nicht verwenden. Ein Funktionsaufruf sollte sich nicht auf etwas außerhalb verlassen müssen, zAll dies macht Ihren Code von außen abhängig. Das heißt, Sie müssen den vollständigen globalen Status Ihrer Anwendung kennen, bevor Sie diese zuverlässig aufrufen können. Die Funktion kann ohne diese Umgebung nicht existieren.
Die superglobals verwenden , kann es nicht offensichtlich , dass die Fehler, aber wenn Sie Ihren Code über eine Befehlszeile aufrufen, die Sie nicht haben
$_GET
oder$_POST
. Wenn Ihr Code auf Eingaben von diesen beruht, beschränken Sie sich auf eine Webumgebung. Abstrakt einfach die Anfrage in ein Objekt und benutze das stattdessen.Wenn Sie fest codierte Klassennamen (statisch, Konstanten) koppeln, kann Ihre Funktion auch nicht existieren, ohne dass diese Klasse verfügbar ist. Dies ist weniger problematisch, wenn es sich um Klassen aus demselben Namespace handelt. Wenn Sie jedoch mit dem Mischen aus verschiedenen Namespaces beginnen, entsteht ein Wirrwarr.
Die Wiederverwendung wird durch all das stark behindert. Dies gilt auch für Unit-Tests .
Außerdem lügen Ihre Funktionssignaturen, wenn Sie an den globalen Bereich koppeln
ist ein Lügner, weil er behauptet, ich könne diese Funktion aufrufen, ohne etwas an sie weiterzugeben. Erst wenn ich mir den Funktionskörper anschaue, lerne ich, dass ich die Umgebung in einen bestimmten Zustand versetzen muss.
Wenn für Ihre Funktion Argumente erforderlich sind, machen Sie sie explizit und übergeben Sie sie:
vermittelt aus der Unterschrift deutlich, was es heißt, genannt zu werden. Es ist nicht abhängig von der Umgebung, sich in einem bestimmten Zustand zu befinden. Das musst du nicht tun
Es geht darum, (globales Schlüsselwort) einzuziehen oder einzudringen (Argumente). Wenn Sie Abhängigkeiten einschieben / injizieren, ist die Funktion nicht mehr von außen abhängig. Wenn Sie dies tun
fn(1)
, müssen Sie keine Variable haben, die irgendwo außerhalb 1 hält. Wenn Sie jedoch global$one
in die Funktion einbinden, koppeln Sie sie an den globalen Bereich und erwarten, dass dort eine Variable definiert ist. Die Funktion ist dann nicht mehr unabhängig.Schlimmer noch, wenn Sie die globalen Werte in Ihrer Funktion ändern, ist Ihr Code schnell völlig unverständlich, da Ihre Funktionen überall Nebenwirkungen haben.
In Ermangelung eines besseren Beispiels betrachten
Und dann tust du es
Es gibt keine Möglichkeit zu sehen, dass
$foo
sich diese drei Zeilen geändert haben. Warum sollte das Aufrufen derselben Funktion mit denselben Argumenten plötzlich die Ausgabe oder einen Wert im globalen Status ändern? Eine Funktion sollte X für einen definierten Eingang Y ausführen. Immer.Dies wird bei der Verwendung von OOP noch schwerwiegender, da es bei OOP um die Kapselung geht. Wenn Sie sich an den globalen Bereich wenden, brechen Sie die Kapselung. Alle diese Singletons und Registries, die Sie in Frameworks sehen, sind Code-Gerüche, die zugunsten von Dependency Injection entfernt werden sollten. Entkoppeln Sie Ihren Code.
Mehr Ressourcen:
static
als schädlich angesehenquelle
Der einzige große Grund dagegen
global
ist, dass die Funktion von einem anderen Bereich abhängig ist. Dies wird sehr schnell chaotisch.vs.
Das Erfordernis
$str1
und$str2
das Einrichten im aufrufenden Bereich, damit die Funktion funktioniert, bedeutet, dass Sie unnötige Abhängigkeiten einführen. Sie können diese Variablen in diesem Bereich nicht mehr umbenennen, ohne sie auch in der Funktion und damit auch in allen anderen Bereichen, in denen Sie diese Funktion verwenden, umzubenennen. Dies führt bald zu Chaos, wenn Sie versuchen, Ihre Variablennamen im Auge zu behalten.global
ist ein schlechtes Muster, selbst wenn globale Dinge wie$db
Ressourcen einbezogen werden. Es wird der Tag kommen, an dem Sie umbenennen möchten, dies$db
aber nicht können, da Ihre gesamte Anwendung vom Namen abhängt.Begrenzung und den Umfang der Variablen trennt , ist wesentlich für jede halbwegs komplexe Anwendung zu schreiben.
quelle
$db
? Es ist die gU, die überall herumgereicht wird. Warum sollte es geändert werden, wenn ich die Verbindungsinformationen separat aktualisieren kann?$db
Variable verwenden? Weil Sie eines Tages Unit-Tests entdecken und dafür mehr als eine Datenbankverbindung gleichzeitig verwalten müssen? Viele, viele Gründe.Globals sind unvermeidlich.
Es ist eine alte Diskussion, aber ich möchte noch einige Gedanken hinzufügen, weil ich sie in den oben genannten Antworten vermisse. Diese Antworten vereinfachen, was eine globale zu viel ist, und präsentieren Lösungen, die überhaupt keine Lösungen für das Problem sind. Das Problem ist: Was ist der richtige Umgang mit einer globalen Variablen und die Verwendung des Schlüsselworts global? Dazu müssen wir zunächst untersuchen und beschreiben, was ein Global ist.
Schauen Sie sich diesen Code von Zend an - und verstehen Sie bitte, dass ich nicht behaupte, dass Zend schlecht geschrieben ist:
Hier gibt es viele unsichtbare Abhängigkeiten. Diese Konstanten sind eigentlich Klassen. Sie können require_once auch auf einigen Seiten dieses Frameworks sehen. Require_once ist eine globale Abhängigkeit, wodurch externe Abhängigkeiten erstellt werden. Das ist für einen Rahmen unvermeidlich. Wie können Sie eine Klasse wie DecoratorPluginManager ohne viel externen Code erstellen, von dem sie abhängt? Es kann nicht ohne viele Extras funktionieren. Haben Sie mit dem Zend-Framework jemals die Implementierung einer Schnittstelle geändert? Eine Schnittstelle ist in der Tat eine globale.
Eine weitere weltweit verwendete Anwendung ist Drupal. Sie sind sehr besorgt über das richtige Design, aber genau wie jedes große Framework haben sie viele externe Abhängigkeiten. Schauen Sie sich die Globals auf dieser Seite an:
Haben Sie jemals eine Weiterleitung zur Anmeldeseite geschrieben? Das verändert einen globalen Wert. (Und dann sagen Sie nicht 'WTF', was ich als gute Reaktion auf eine schlechte Dokumentation Ihrer Anwendung betrachte.) Das Problem bei Globals ist nicht, dass es sich um Globals handelt, Sie benötigen sie, um eine aussagekräftige Anwendung zu haben. Das Problem ist die Komplexität der gesamten Anwendung, die es zu einem Albtraum machen kann. Sitzungen sind global, $ _POST ist global, DRUPAL_ROOT ist global, include / install.core.inc 'ist nicht modifizierbar global. Es gibt eine große Welt außerhalb jeder Funktion, die erforderlich ist, damit diese Funktion ihre Arbeit erledigt.
Die Antwort von Gordon ist falsch, weil er die Unabhängigkeit einer Funktion überschätzt und eine Funktion als Lügner bezeichnet, was die Situation zu stark vereinfacht. Funktionen lügen nicht und wenn Sie sich sein Beispiel ansehen, ist die Funktion nicht richtig gestaltet - sein Beispiel ist ein Fehler. (Übrigens stimme ich dieser Schlussfolgerung zu, dass man Code entkoppeln sollte.) Die Antwort der Täuschung ist nicht wirklich eine richtige Definition der Situation. Funktionen funktionieren immer in einem größeren Rahmen und sein Beispiel ist viel zu einfach. Wir werden ihm alle zustimmen, dass diese Funktion völlig nutzlos ist, weil sie eine Konstante zurückgibt. Diese Funktion ist sowieso schlechtes Design. Wenn Sie zeigen möchten, dass die Praxis schlecht ist, geben Sie bitte ein relevantes Beispiel. Das Umbenennen von Variablen in einer Anwendung ist mit einer guten IDE (oder einem Tool) keine große Sache. Die Frage bezieht sich auf den Umfang der Variablen, nicht auf den Unterschied im Umfang mit der Funktion. Es gibt einen geeigneten Zeitpunkt für eine Funktion, um ihre Rolle im Prozess zu erfüllen (deshalb wird sie in erster Linie erstellt), und zu diesem richtigen Zeitpunkt kann sie die Funktionsweise der gesamten Anwendung beeinflussen und somit auch an globalen Variablen arbeiten . Die Antwort von xzyfer ist eine Aussage ohne Argumentation. Globals sind in einer Anwendung genauso vorhanden, wenn Sie über prozedurale Funktionen oder ein OOP-Design verfügen. Die nächsten beiden Möglichkeiten, den Wert eines globalen Werts zu ändern, sind im Wesentlichen dieselben: daher auch an globalen Variablen arbeiten. Die Antwort von xzyfer ist eine Aussage ohne Argumentation. Globals sind in einer Anwendung genauso vorhanden, wenn Sie über prozedurale Funktionen oder ein OOP-Design verfügen. Die nächsten beiden Möglichkeiten, den Wert eines globalen Werts zu ändern, sind im Wesentlichen dieselben: daher auch an globalen Variablen arbeiten. Die Antwort von xzyfer ist eine Aussage ohne Argumentation. Globals sind in einer Anwendung genauso vorhanden, wenn Sie über prozedurale Funktionen oder ein OOP-Design verfügen. Die nächsten beiden Möglichkeiten, den Wert eines globalen Werts zu ändern, sind im Wesentlichen dieselben:
In beiden Fällen wird der Wert von $ z innerhalb einer bestimmten Funktion geändert. Auf beide Arten der Programmierung können Sie diese Änderungen an einer Reihe anderer Stellen im Code vornehmen. Man könnte sagen, dass man mit global überall $ z aufrufen und dort ändern kann. Ja, du kannst. Aber wirst du? Und wenn es an ungeeigneten Orten gemacht wird, sollte es dann nicht als Fehler bezeichnet werden?
Bob Fanger kommentiert xzyfer.
Sollte jemand dann einfach irgendetwas verwenden und vor allem das Schlüsselwort 'global'? Nein, aber versuchen Sie wie bei jeder Art von Design zu analysieren, worauf es ankommt und was davon abhängt. Versuchen Sie herauszufinden, wann es sich ändert und wie es sich ändert. Das Ändern globaler Werte sollte nur bei Variablen erfolgen, die sich bei jeder Anforderung / Antwort ändern können. Das heißt, nur zu den Variablen, die zum Funktionsablauf eines Prozesses gehören, nicht zu seiner technischen Implementierung. Die Umleitung einer URL zur Anmeldeseite gehört zum Funktionsablauf eines Prozesses, der Implementierungsklasse, die für eine Schnittstelle zur technischen Implementierung verwendet wird. Sie können Letzteres während der verschiedenen Versionen der Anwendung ändern, sollten diese jedoch nicht bei jeder Anforderung / Antwort ändern.
Um besser zu verstehen, wann es ein Problem ist, mit Globals und dem Schlüsselwort global zu arbeiten, und wann nicht, werde ich den nächsten Satz einführen, der von Wim de Bie beim Schreiben über Blogs stammt: "Persönliches Ja, privates Nein". Wenn eine Funktion den Wert einer globalen Variablen aufgrund ihrer eigenen Funktionsweise ändert, werde ich diese private Verwendung einer globalen Variablen und eines Fehlers nennen. Aber wenn die Änderung der globalen Variablen für die ordnungsgemäße Verarbeitung der gesamten Anwendung vorgenommen wird, wie die Weiterleitung des Benutzers auf die Anmeldeseite, dann ist das meiner Meinung nach möglicherweise gutes Design, nicht per Definition schlecht und schon gar nicht schlecht Anti-Muster.
Rückblickend auf die Antworten von Gordon, Deceze und Xzyfer: Alle haben als Beispiele 'privates Ja' (und Bugs). Deshalb sind sie gegen die Verwendung von Globalen. Ich würde es auch tun. Sie enthalten jedoch keine "persönlichen Ja, privaten Nein" -Beispiele, wie ich sie in dieser Antwort mehrmals gemacht habe.
quelle
xyz
und vergleichensetZ
. Der erste ändert den globalen Status, der zweite ist eine Klassenmethode und ändert nur den Status der Instanz, für die er aufgerufen wurde.global
In Drupal 7.26 (der neuesten Version) gibt es ungefähr 400 Treffer für das Wort. Einige dieser Treffer befinden sich in Kommentaren, andere in Code, der seit Jahren nicht mehr berührt wurde. Ich hoffeglobal
wirklich , dass sie s in Drupal 8 nicht verwenden werden .Einfach ausgedrückt gibt es
global
im modernen PHP-Code meiner Meinung nach selten einen Grund und niemals einen guten. Besonders wenn Sie PHP 5 verwenden. Und besonders speziell, wenn Sie objektorientierten Code entwickeln.Globale Werte wirken sich negativ auf die Wartbarkeit, Lesbarkeit und Testbarkeit von Code aus. Viele Verwendungen von
global
can und sollten durch Dependency Injection ersetzt werden oder einfach das globale Objekt als Parameter übergeben.quelle
Zögern Sie nicht, globale Schlüsselwörter in Funktionen in PHP zu verwenden. Nehmen Sie besonders nicht Leute mit, die fremdartig predigen / schreien, wie "global" "global" sind und so weiter.
Erstens, weil das, was Sie verwenden, völlig von der Situation und dem Problem abhängt und es KEINE Lösung / Möglichkeit gibt, etwas beim Codieren zu tun. Den Irrtum undefinierbarer, subjektiver, religiöser Adjektive wie „böse“ in der Gleichung völlig außer Acht lassen.
Ein typisches Beispiel:
Wordpress und sein Ökosystem verwenden in ihren Funktionen globale Schlüsselwörter. Sei der Code OOP oder nicht OOP.
Und ab sofort macht Wordpress im Grunde genommen 18,9% des Internets aus und betreibt die riesigen Megasites / Apps unzähliger Giganten, von Reuters über Sony, NYT bis CNN.
Und es macht es gut.
Die Verwendung globaler Schlüsselwörter in Funktionen befreit Wordpress von MASSIVEM Aufblähen, das aufgrund seines riesigen Ökosystems auftreten würde. Stellen Sie sich vor, jede Funktion fragt / übergibt eine Variable, die von einem anderen Plugin, Core und Return benötigt wird. Hinzugefügt mit Plugin-Interdependenzen, die in einem Albtraum von Variablen oder einem Albtraum von Arrays enden würden, die als Variablen übergeben werden. Eine HÖLLE zum Verfolgen, eine Hölle zum Debuggen, eine Hölle zum Entwickeln. Unglaublich großer Speicherbedarf aufgrund von Code-Bloat und variablem Bloat. Schwieriger auch zu schreiben.
Es kann Leute geben, die Wordpress, sein Ökosystem, ihre Praktiken und das, was in diesen Teilen vor sich geht, kritisieren.
Sinnlos, da dieses Ökosystem fast 20% des gesamten Internets ausmacht. Anscheinend funktioniert es, es macht seinen Job und mehr. Dies bedeutet, dass dies auch für das globale Schlüsselwort gilt.
Ein weiteres gutes Beispiel ist der Fundamentalismus "Iframes sind böse". Vor einem Jahrzehnt war es eine Häresie, Iframes zu verwenden. Und im Internet predigten Tausende von Menschen gegen sie. Dann kommt Facebook, dann kommt Social, jetzt gibt es überall Iframes, von "Like" -Boxen bis zur Authentifizierung, und voila - alle halten den Mund. Es gibt diejenigen, die immer noch nicht die Klappe gehalten haben - zu Recht oder zu Unrecht. Aber weißt du was? Trotz solcher Meinungen geht das Leben weiter, und selbst diejenigen, die vor einem Jahrzehnt gegen Iframes predigten, müssen sie jetzt verwenden, um verschiedene soziale Apps wortlos in die eigenen Anwendungen ihres Unternehmens zu integrieren.
......
Coder Fundamentalism ist etwas sehr, sehr Schlechtes. Ein kleiner Prozentsatz unter uns mag mit der komfortablen Arbeit in einem soliden monolithischen Unternehmen zufrieden sein, das über genügend Einfluss verfügt, um den ständigen Wandel in der Informationstechnologie und den damit verbundenen Druck in Bezug auf Wettbewerb, Zeit, Budget und andere Überlegungen zu ertragen, und daher praktizieren kann Fundamentalismus und strikte Einhaltung der wahrgenommenen "Übel" oder "Güter". Bequeme Positionen, die an das Alter erinnern, auch wenn die Besatzer jung sind.
Für die Mehrheit ist die it-Welt jedoch eine sich ständig verändernde Welt, in der sie offen und praktisch sein muss. Es gibt keinen Platz für Fundamentalismus, lassen Sie unverschämte Schlüsselwörter wie "böse" in den Frontgräben der Informationstechnologie außer Acht.
Verwenden Sie einfach das, was für das Problem AT HAND am sinnvollsten ist, mit geeigneten Überlegungen für die nahe, mittel- und langfristige Zukunft. Scheuen Sie sich nicht, ein Merkmal oder einen Ansatz zu verwenden, da es eine weit verbreitete ideologische Feindseligkeit unter einer bestimmten Codierer-Untergruppe aufweist.
Sie werden Ihren Job nicht machen. Du wirst. Handle entsprechend deinen Umständen.
quelle
Ich denke, jeder hat die negativen Aspekte von Globals ziemlich genau dargelegt. Also werde ich die Positiven sowie Anweisungen für die ordnungsgemäße Verwendung von Globals hinzufügen:
Der Hauptzweck von Globals war der Austausch von Informationen zwischen Funktionen. Damals, als es nichts Vergleichbares gab, bestand der PHP-Code aus einer Reihe von Funktionen. Manchmal müssen Sie Informationen zwischen Funktionen austauschen. In der Regel wurde dazu das Global verwendet, mit dem Risiko, dass Daten durch Globalisierung beschädigt werden.
Bevor ein Happy Go Lucky Simpleton einen Kommentar zur Abhängigkeitsinjektion startet, möchte ich Sie fragen, wie der Benutzer einer Funktion wie Beispiel
get_post(1)
alle Abhängigkeiten der Funktion kennen würde. Beachten Sie auch, dass die Abhängigkeiten vonVersion zu Version und von Server zu Server unterschiedlich sein können. Das Hauptproblem bei der Abhängigkeitsinjektion besteht darin, dass Abhängigkeiten im Voraus bekannt sein müssen. In einer Situation, in der dies nicht möglich ist oder unerwünschte globale Variablen der einzige Weg waren, um dieses Ziel zu erreichen.
Aufgrund der Erstellung der Klasse können jetzt allgemeine Funktionen einfach in einer Klasse gruppiert und Daten gemeinsam genutzt werden. Durch Implementierungen wie Mediatoren können auch nicht verwandte Objekte Informationen austauschen. Dies ist nicht mehr erforderlich.
Eine andere Verwendung für Globals ist für Konfigurationszwecke. Meistens zu Beginn eines Skripts, bevor Autoloader geladen, Datenbankverbindungen hergestellt usw. wurden.
Während des Ladens von Ressourcen können globale Daten verwendet werden, um Daten zu konfigurieren (dh welche Datenbank verwendet werden soll, in der sich Bibliotheksdateien befinden, die URL des Servers usw.). Der beste Weg, dies zu tun, ist die Verwendung der
define()
Funktion, da sich diese Werte nicht oft ändern und einfach in eine Konfigurationsdatei eingefügt werden können.Die endgültige Verwendung für Globals besteht darin, allgemeine Daten (z. B. CRLF, IMAGE_DIR, IMAGE_DIR_URL) und lesbare Statusflags (dh ITERATOR_IS_RECURSIVE) zu speichern. Hier werden Globals verwendet, um Informationen zu speichern, die anwendungsweit verwendet werden sollen, damit sie geändert werden können und diese Änderungen anwendungsweit angezeigt werden.
Das Singleton-Muster wurde in PHP während PHP4 populär, als jede Instanz eines Objekts Speicher beanspruchte. Der Singleton half beim Speichern von RAM, indem nur eine Instanz eines Objekts erstellt werden konnte. Vor Referenzen wäre sogar eine Abhängigkeitsinjektion eine schlechte Idee gewesen.
Die neue PHP-Implementierung von Objekten aus PHP 5.4+ behebt die meisten dieser Probleme. Sie können Objekte sicher und ohne weitere Nachteile weitergeben. Dies ist nicht mehr erforderlich.
Eine andere Verwendung für Singletons ist die spezielle Instanz, bei der jeweils nur eine Instanz eines Objekts vorhanden sein muss, diese Instanz möglicherweise vor / nach der Skriptausführung vorhanden ist und dieses Objekt von verschiedenen Skripten / Servern / Sprachen usw. gemeinsam genutzt wird. Hier löst ein Singleton-Muster das Problem Lösung ganz gut.
Wenn Sie sich also in Position 1, 2 oder 3 befinden, ist die Verwendung eines Global sinnvoll. In anderen Situationen sollte jedoch Methode 1 verwendet werden.
Sie können auch andere Fälle aktualisieren, in denen Globals verwendet werden sollten.
quelle
Es macht keinen Sinn, eine Concat-Funktion mit dem globalen Schlüsselwort zu erstellen.
Es wird verwendet, um auf globale Variablen wie ein Datenbankobjekt zuzugreifen.
Beispiel:
Es kann als Variation des Singleton-Musters verwendet werden
quelle