Variblen Global verfügbar machen

S

spex

Hi,

Ich suche eine Möglichkeit wie ich Variablen Global verfügbar machen kann.
Ich möchte die Varibalen aus meiner config.php auch in Funktionen verwenden können, ohne das ich jedesmal die datei neu inludieren oder per $GLOBALS darauf zugreifen muss.

Ich würd es gerne so machen wie in vBulletin, das arbeitet ja scheinbar irgendwie mit Classen oder Objekten, aber da blick ich nicht ganz durch. Weil die Classen müssten ja dann in den Funktionen wieder neu gesetzt werden ($config = new classname;) und genau das soll ja nicht passieren.

In vBulletin kann man (wenn die global.php includiert wurde) auf die Configeinträge bequem über $vbulletin->userinfo['username'], zugreifen ohne jedesmal eine classe neu laden zu müssen oder eine config.php Datei neu zu includieren.

Gruß
 
Mal reinarbeiten in das PHP Beispiel.
Immoment kann ich mir darunter noch nicht viel vorstellen.
 
vBulletin ist nun wirklich keine Glanzleistung in Sachen effizienter und eleganter Code...
Wenn ich es richtig in Erinnerung habe, wird in Version 3.5+ überwiegend im Global Scope (main) und mit Referenzen gearbeitet, jedoch ohne PHP5 Features. So sieht das dann zB so aus:

PHP:
class vBulletin {
    var $user = null;

    function vBulletin( &$user ) {
        $this->user = &$user;
    }

    function doSth() {
        return $this->user->userinfo['username'];
    }
}
// ...
$user = new User();
// ...
$vbulletin = new vBulletin( $user );
// ...
var_dump( $vbulletin->doSth() );

Eleganter geht das via PHP5 und dem von Gumbo bereits genannten Entwurfsmuster, welches nur eine einmalige Instanzierung der Klasse zulässt. Dazu gibt es noch ein paar nette Abwandlungen, aber das liest du dir am besten selbst an.
Alternativ kannst du $GLOBALS verwenden, was jedoch eher unschön, unsauber und nicht empfehlenswert ist, so lange man nicht wirklich weiß, was man tut.
 
Das wird wol daran liegen das vBulletin auf Kompatibilität setzen muss. Nicht jeder besitzt einen eigenen Server und kann von PHP4 auf PHP5 aufrüsten. Außerdem ist vBulletin 3 dann doch schon etwas älter und die jetzt kommende Version 3.7.0 ist soweit ich weiß die Letzte und danach wird nurnoch an Version 4 gearbeitet (abgesehen von Bugfixes ...).

Und ja $GLOBALS wollte ich nicht verwenden das ist mir zu heikel.

Vondaher: Danke für eure Antworten ich werd mir mal beide Lösungen durch den Kopf gehen lassen.
 
Wäre nett wenn mir mal jemand ein Beispiel aus dem Code hier (von Wikipedia) schreiben könnte, vielleicht versteh ich dann mehr.

Was ich brauche ist wie gesagt, eine Klasse die es mir ermöglicht auf eine Variable zuzugreifen, die in der Klasse einmal aus einer Configdatei eingelesen wird, sodass ich dann immerwieder darauf zugreifen kann und das GLOBAL, also auch in Funktionen (Ohne die Configdatei erneut einlesen zu müssen.).

PHP:
<?php
class Singleton {
  /**
   * die Instanz wird hier abgelegt
   */
  private static $instance = NULL;
  
  /**
   * Konstruktor private, damit die Klasse nur aus sich selbst heraus instanziiert werden kann.
   */
  private function __construct() {}

  /**
   * mit dieser statischen Methode bekommt man das Singleton
   */
  public static function getInstance()
  {
      if (self::$instance === NULL)
      {
          self::$instance = new Singleton;
      }
      return self::$instance;
  }

  /**
   * Klonen per 'clone' von außen verbieten
   */
  private function __clone() {}
}

$single = Singleton::getInstance();
?>

Gruß
 
PHP:
<?php
class Singleton {
  /**
   * die Instanz wird hier abgelegt
   */
  private static $instance = NULL;
  private static $config_file = './test2.txt';
  private static $array;

  /**
   * Konstruktor private, damit die Klasse nur aus sich selbst heraus instanziiert werden kann.
   */
  private function __construct() {}

  /**
   * mit dieser statischen Methode bekommt man das Singleton
   */
  public static function getInstance()
  {
	  if (self::$instance === NULL)
	  {
		  include(self::$config_file);
		  self::$array = $config;
		  self::$instance = new Singleton;
	  }
	  return self::$instance;
  }
  /**
   * mit dieser Methode bekommt man die Inhalte des Config Arrays
   */
  public static function __get($var)
  {
  	return self::$array[$var];
  }
  /**
   * Klonen per 'clone' von außen verbieten
   */
  private function __clone() {}
}

$single = Singleton::getInstance();
print $single->test;
?>

Dieses Beispiel geht von einer Configdatei aus, die ungefähr so aussieht:
PHP:
<?php

$config['test'] = "abc";
$config['new_config'] = "123";

?>
 
Kleine Korrektur: "Keine Überladungsmethode darf statisch definiert sein.", meint die PHP-Doku, demzufolge wäre das hier "besser":

PHP:
<?php
class Singleton {
  /**
   * die Instanz wird hier abgelegt
   */
  private static $instance = null;

  private $array;

  /**
   * Konstruktor private, damit die Klasse nur aus sich selbst heraus instanziiert werden kann.
   */
  private function __construct( array $config ) {
     $this->array = $config;
  }

  /**
   * mit dieser statischen Methode bekommt man das Singleton
   */
  public static function getInstance( array $config )
  {
      if (self::$instance === NULL)
      {
          self::$instance = new Singleton( $config );
      }
      return self::$instance;
  }
  /**
   * mit dieser Methode bekommt man die Inhalte des Config Arrays
   */
  public function __get($var)
  {
      return $this->array[$var];
  }
  /**
   * Klonen per 'clone' von außen verbieten
   */
  private function __clone() {}
}

$single = Singleton::getInstance( array( 'test' => "foobar" ) );
print $single->test;
?>
 
Ooops, da hast du natürlich recht... Wobei es trotzdem funktioniert... Weißt du auch den Grund dafür? Der würde mich interessieren...
Ich meine, gut, es steht da... Aber ohne Gründe finde ich es komisch.
 
Ui, habe mich einfach mal auf die Dokumentation gestützt, wie so oft ist die Antwort bei PHP-Eigenheiten, dass es PHP ist. Effektive Überladungen gibt es ja leider nicht, die ganze Chose der "Objektorientierung" ist in PHP generell sehr lose implementiert. Könnte mir vorstellen, dass selbst die statischen Eigenschaften und Methoden doch auch nur in eine Instanz eines Objekts in C++ gepackt werden und die Zugriffe an sich dann im entsprechenden Scope ausgewertet werden. Wird also statisch aufgerufen, wird die einmalig initialisierte, statische Instanz benutzt, wird dynamisch aufgerufen, wird die entsprechend referenzierte Instanz verwendet.

Durch die Unfunktionalität folgenden Konstrukts aber, macht es dann doch wenig Sinn es auf das Statische anzuwenden, da die dynamische Pseudoüberladung nicht mehr stattfinden kann:
PHP:
<?php
class Test {
    private static $test1 = array();
    private $test2 = array();
    
    public function __construct() {}
    
    public function __set($name, $value) {
        $this->test2[$name] = $value;
    }
    
    public static function __set($name, $value) {
        self::$test1[$name] = $value;
    }
}

Wirft: Cannot redeclare Test::__set() in <file> on line 12

Wahrscheinlich ist die Aussage in der PHP-Doku deshalb auch eher eine Empfehlung ;) Ist halt ein wenig öde, wenn man nur statisch arbeitet, da man genau ein Objekt verwenden kann, wohingegen mit mehreren Instanzen der Klasse entsprechend mehrere Objekte verwaltet werden können ohne sich in die Query zu kommen. Schwer zu beschreiben, aber ich denke, du weißt, worauf es hinausläuft.
 
Zurück