PHP global in Funktionen

100

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 globalThema hin und wieder auftaucht, könnten wir eine gute "kanonische" Antwort verwenden, um darauf zu verlinken.

Pascal Qyy
quelle
2
Schauen Sie sich diesen Link an: stackoverflow.com/questions/1557787 Unten rechts auf dieser Seite finden
Sie
Es ist keine direkte Antwort auf Ihre Frage, aber bitte lesen Sie diese ältere SO-Frage .
Ólafur Waage
1
Daher kann ich kein pro-globales Schlüsselwort lesen. 1) Warum ist es hier? 2) Warum benutzen die Leute es?
Pascal Qyy
@ G.Qyy Warum gibt es goto? Warum benutzen die Leute es? Sie benutzen es nicht (ich hoffe zumindest): P
PeeHaa
Ende letzten Jahres (14. Dezember) hat jemand diese Frage abgelehnt. Ich bin sehr interessiert zu wissen warum, weil alle Sichtweisen, einschließlich der negativen, interessant sind. In diesem Fall mehr denn je! Ich bin sehr dankbar für jeden Hinweis darauf.
Pascal Qyy

Antworten:

158

Globals sind böse

Dies gilt sowohl für das globalSchlü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, z

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
}

All 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 $_GEToder $_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

function fn()

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:

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

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

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

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 $onein 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

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

Und dann tust du es

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

Es gibt keine Möglichkeit zu sehen, dass $foosich 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:

Gordon
quelle
10
Warum implementiert PHP solche Dinge? Gibt es ein Dienstprogramm? Ich war immer überrascht von gefährlichen Implementierungen in PHP, die viele Leute jedes Mal verwenden ... Es fällt mir schwer zu glauben, dass es keine logischen Gründe gibt!
Pascal Qyy
5
Ich wünschte, Sie könnten Globals größer machen.
Kermit
3
Wow, endlich hat jemand gut erklärt, warum Globale böse sind ... Ich habe immer gehört, dass sie böse sind, und ich habe einige sehr spezifische Beispiele dafür gesehen, warum, aber dies ist wirklich eine gute und umfassende Erklärung für den allgemeinen Grund warum. +1
Wingblade
Ich bin sehr spät dran und verstehe irgendwie, was Sie sagen, aber wie wäre es mit MySQL-Verbindungen? Sollten diese jedes Mal als Parameter übergeben werden oder handelt es sich um einen globalen $ link; in deinen Augen erlaubt?
Mave
2
Sie haben Recht, bis auf die Konstanten. Sie stellen keinen "Status" der Anwendung dar und es ist in Ordnung, innerhalb einer Funktion auf sie zu verweisen. Die Funktion "lügt" nicht, wenn sie eine Konstante von innen verwendet. Ich stimme zu, dass dies impliziert, dass der Programmierer zu einem bestimmten Zeitpunkt Kenntnisse von außen hatte, aber das ist ein sehr akzeptabler Kompromiss für das, was eine Konstante ist. Im Ernst, es ist keine allzu große Sache.
Sebas
35

Der einzige große Grund dagegen globalist, dass die Funktion von einem anderen Bereich abhängig ist. Dies wird sehr schnell chaotisch.

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

vs.

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

Das Erfordernis $str1und $str2das 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.

globalist ein schlechtes Muster, selbst wenn globale Dinge wie $dbRessourcen einbezogen werden. Es wird der Tag kommen, an dem Sie umbenennen möchten, dies $dbaber 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.

täuschen
quelle
1
Es tut mir leid, aber warum sollte ich definitiv umbenennen wollen $db? Es ist die gU, die überall herumgereicht wird. Warum sollte es geändert werden, wenn ich die Verbindungsinformationen separat aktualisieren kann?
Casey Dwayne
3
@kcd Weil Sie eines Tages erkennen, wie großartig die Abhängigkeitsinjektion ist, und Ihre App umstrukturieren möchten? Weil Sie eines Tages Ihre Inhalte in andere Inhalte integrieren müssen, die ebenfalls eine globale $dbVariable verwenden? Weil Sie eines Tages Unit-Tests entdecken und dafür mehr als eine Datenbankverbindung gleichzeitig verwalten müssen? Viele, viele Gründe.
Täuschung
35

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:

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',
   );

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:

/**
 * @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();

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:

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

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

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.

Loek Bergman
quelle
Das Drupal-Codebeispiel verwendet keine Globalen, sondern Konstanten. Ein sehr wichtiger Unterschied besteht darin, dass eine Konstante nach ihrer Definition nicht mehr neu definiert werden kann. Auch kann man nicht einfach die Funktionen xyzund vergleichen setZ. Der erste ändert den globalen Status, der zweite ist eine Klassenmethode und ändert nur den Status der Instanz, für die er aufgerufen wurde.
Arjan
@Arjen: Wenn Sie in Drupal 7.14 nach dem Schlüsselwort global suchen, erhalten Sie Hunderte von Treffern. Es ist ein altes Problem bei öffentlichen Setzern: Sie kontrollieren nicht den Ort, an dem sie geändert werden, sobald Sie sie öffentlich gemacht haben. Es wurde empfohlen, sie überhaupt nicht zu verwenden oder als privat zu deklarieren, damit sie später nicht hinzugefügt werden können.
Loek Bergman
@Arjan: Aufgrund meines Fehlers bei der Schreibweise Ihres Namens haben Sie keine Benachrichtigung über meine Antwort erhalten. Jetzt wirst du. :-)
Loek Bergman
@LoekBergman: globalIn 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 hoffe globalwirklich , dass sie s in Drupal 8 nicht verwenden werden .
Arjan
@LoekBergman Bitte verwenden Sie Setter und Getter. Das Einrichten nimmt nicht viel Zeit in Anspruch und ermöglicht anderen, die Ihren Code verwenden und möglicherweise Ihre Klassen erweitern, mehr Kontrolle. Sobald Sie einen Parameter veröffentlicht haben, ist es das. Sie haben nicht die Möglichkeit, es später auszublenden.
mAsT3RpEE
15

Einfach ausgedrückt gibt es globalim 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 globalcan und sollten durch Dependency Injection ersetzt werden oder einfach das globale Objekt als Parameter übergeben.

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

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.

unit100
quelle
3
+1 für Anti-Fundamentalismus und so, aber nur zu sagen "viele Leute benutzen es / es funktioniert / etc" ist nur ein "argumentum ad populum", ein grundlegender Sophismus. Die Tatsache, dass die Mehrheit der Menschen eine Sache denkt oder tut, beweist nicht, dass sie Recht haben! Wenn in einer Menschenmenge eine Gefahr auftritt, wird die Mehrheit der Menschen dumme Dinge tun, und einige Menschen werden von anderen gestampft sterben. Haben sie Recht, diesem fünfjährigen kleinen Mädchen einen Fuß ins Gesicht zu setzen, nur weil sie denken, sie müssen unbedingt eine Tür schieben, die sich nur öffnet, wenn sie gezogen wird, um dem Feuer zu entkommen? Ich glaube nicht ...
Pascal Qyy
1
Die Mehrheit, die etwas tut, bestätigt natürlich nichts für sich. Der Fall ist jedoch Software. und wenn die Mehrheit dies tut und ein Großteil der von diesen Personen erstellten Apps und Dienste gut funktioniert (WordPress für viele andere), bedeutet dies, dass sie verwendet werden können.
Unity100
7

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:

  1. 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 von
    Version 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.

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

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

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

mAsT3RpEE
quelle
6

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:

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

Es kann als Variation des Singleton-Musters verwendet werden

Bob Fanger
quelle
"es macht keinen Sinn" - eigentlich schon: Ein Beispiel ist die Implementierung einer Nachschlagetabelle ohne Verwendung von OOP.
Nir Alfasi