it-swarm.com.de

Was ist der beste Weg, Konfigurationsvariablen in a zu speichern? PHP Web-App?

Ich wechsle oft zwischen .NET- und PHP -Entwicklung. Mit ASP.NET-Sites speichere ich Konfigurationsinformationen (z. B. Verbindungszeichenfolgen, Verzeichnisse, Anwendungseinstellungen) in der web.config -Datei, die entsprechend geschützt ist und leicht auf die Werte zugreifen kann usw.

InPHPlöse ich dies mit einer Klasse, die statische Methoden hat für jede Variable:

class webconfig {
    public static function defaultPageIdCode() {
        return 'welcome';
    }
}

Die Datei ist enthalten , indem auf die App-Variablen mit einer Zeile zugegriffen wird:

$dp = webconfig::defaultPageIdCode();

Und da PHP nicht kompiliert wird, ist es einfach, telnet einen Wert für eine Website zu ändern und einen Wert zu ändern, also funktioniert diese Lösung ziemlich gut und gibt mir diese zwei Vorteile :

  • Ich kann log zu einer config-Variablen hinzufügen, ohne die Schnittstelle mit der Anwendung zu unterbrechen
  • diese Konfigurationsvariablen erscheinen als intellisense in meinem z. Eclipse, NetBeans usw.

Ich kann mir jedoch vorstellen, dass es andere Möglichkeiten gibt, wie man die Einstellungen für das Speichern von Web-Konfigurationen in PHP löst, was andere Vorteile haben kann.

Insbesondere diejenigen, die Erfahrung mit einer Reihe von PHP -Frameworks haben, wie können Konfigurationsvariablen auf andere Weise gespeichert werden und welche Vor- und Nachteile sie haben?

41
Edward Tanguay

Ich habe beschlossen, alle bekannten Methoden mit ihren Vor- und Nachteilen aufzulisten.

Ich habe diese Antwort als Community-Wiki markiert, um die Zusammenarbeit zu vereinfachen.


Globale Konstanten

Zuweisung:

  • define('CONFIG_DIRECTIVE', 'value');

Zugriff auf:

  • $object = new MyObject(CONFIG_DIRECTIVE);

Vorteile:

  • Hat globalen Geltungsbereich.
  • Von den meisten IDEs automatisch vervollständigt.
  • Hat eine vereinbarte Namenskonvention (UPPERCASE_UNDERSCORE_SEPARATED).

Nachteile:

  • Direktiven dürfen keine Arrays enthalten (vor v7.0.0).

Besondere Hinweise:

  • Kann nicht neu zugewiesen werden.

Alternative Syntaxdateien

Zum Beispiel: XML, INI, YAML usw.

Zuweisung:

  • Bearbeiten Sie die Datei einfach in der jeweiligen Sprache. (Zum Beispiel für INI Dateien: config_directive = value.)

Zugriff auf:

  • Die Konfigurationsdatei muss analysiert werden. (Zum Beispiel für INIs: parse_ini_file().)

Vorteile:

  • Hat höchstwahrscheinlich eine Syntax, die besser für eine Konfigurationsdatei geeignet ist.

Nachteile:

  • Möglicher Aufwand für den Zugriff und das Parsen der Datei.

Array

Zuweisung:

  • $config['directive'] = 'value';

Zugriff auf:

  • Die sauberste Methode für den Zugriff auf Konfigurationswerte mit dieser Methode besteht darin, die erforderlichen Werte an das Objekt zu übergeben, das sie bei der Erstellung benötigt, oder sie an Ihr Containerobjekt zu übergeben und sie intern weiterzugeben.
    • $object = new MyObject($config['directive']);
    • $container = new MyContainer($config);

Vorteile:

  • Direktiven können Arrays sein.

Nachteile:

  • Keine automatische Vervollständigung.

Besondere Hinweise:

  • Variable Kollisionen können auftreten. Wenn dies ein Problem ist, benennen Sie Ihr Array entsprechend, um sie zu vermeiden.

Klasse

Zuweisung:

  • Es gibt viele verschiedene klassenbasierte Implementierungen.
    • Statische Klasse.
      • myCfgObj::setDirective('DIRECTIVE', 'value');
    • Instanzklasse.
      • myCfgObj->setDirective('DIRECTIVE', 'value');

Zugriff auf:

  • Auch hier gibt es verschiedene klassenbasierte Implementierungen.
    • Statische Klasse.
      • $object = new MyObject(myCfgObj::getDirective('DIRECTIVE'));
    • Instanzklasse.
      • $object = new MyObject(myCfgObj->getDirective('DIRECTIVE'));

Vorteile:

  • Kann automatisch geladen werden.

Nachteile:

  • Neigt dazu, ein bisschen wortreich zu sein.
  • Kann schwierig zu warten sein, wenn eine Containerklasse nicht verwendet wird.
35
raveren

Ich neige dazu, eine statische Klasse für Einstellungen in PHP zu verwenden

  • Es hat eine globale Reichweite.
  • Sie können Änderungen an geschützten Konfigurationen aktivieren/deaktivieren.
  • Sie können während der Laufzeit beliebige Einstellungen hinzufügen.
  • Sie können die Klasse automatisieren, um öffentliche Konfigurationsdateien aus einer Datei/Datenbank abzurufen.

Beispiel:

abstract class Settings
{
    static private $protected = array(); // For DB / passwords etc
    static private $public = array(); // For all public strings such as meta stuff for site

    public static function getProtected($key)
    {
        return isset(self::$protected[$key]) ? self::$protected[$key] : false;
    }

    public static function getPublic($key)
    {
        return isset(self::$public[$key]) ? self::$public[$key] : false;
    }

    public static function setProtected($key,$value)
    {
        self::$protected[$key] = $value;
    }

    public static function setPublic($key,$value)
    {
        self::$public[$key] = $value;
    }

    public function __get($key)
    {//$this->key // returns public->key
        return isset(self::$public[$key]) ? self::$public[$key] : false;
    }

    public function __isset($key)
    {
        return isset(self::$public[$key]);
    }
}

Wenn Sie während dieser Laufzeit zuerst diese Datei und anschließend Ihre Datenbankkonfigurationsdatei geladen haben, würde Ihre Datenbankkonfigurationsdatei folgendermaßen aussehen:

<?php
Settings::setProtected('db_hostname', 'localhost');
Settings::setProtected('db_username', 'root');
Settings::setProtected('db_password', '');
Settings::setProtected('db_database', 'root');
Settings::setProtected('db_charset', 'UTF-8');
//...
echo Settings::getProtected('db_hostname'); // localhost
//...
Settings::setPublic('config_site_title', 'MySiteTitle');
Settings::setPublic('config_site_charset', 'UTF-8');
Settings::setPublic('config_site_root', 'http://localhost/dev/');

Wie Sie sehen, haben wir eine Methode __get, die nur öffentliche Variablen verwenden darf. Ein Beispiel dafür, warum wir dies haben:

$template = new Template();
$template->assign('settings', new Settings());

Ungeachtet der Tatsache, dass wir dieses Objekt als statisches Objekt verwendet haben, sollten die Werte immer noch in der Vorlage stehen, die Sie jetzt tun können.

<html>
    <head>
        <?php echo isset($settings->config_site_title) ? $settings->config_site_title : 'Fallback Title'; ?>
    </head>
</html>

Dadurch haben Sie nur während des Initialisierungszeitraums Zugriff auf die öffentlichen Daten.

Dies kann viel komplexer, aber systemfreundlicher werden, einige Beispiele:

  • Eine loadConfig-Methode zum automatischen Parsen einer Konfigurationsdatei (xml, php, yaml).
  • Wenn Sie einen shutdown_function registrieren, können Sie die Datenbank automatisch mit neuen Einstellungen aktualisieren.
  • Sie können die Klasse automatisch mit config aus dieser Datenbank füllen.
  • Sie können Iteratoren implementieren, um sie mit Schleifen kompatibel zu machen.
  • Viel mehr.

Auch dies ist bei weitem die beste Methode, um diese Aufgabe zu erfüllen.

23
RobertPitt

So wie ich das mache, speichern Sie sie direkt in einer array und speichern die Datei als config.php

<?php

$config['dbname'] = "mydatabase";
$config['WebsiteName'] = "Fundoo Site";
$config['credits'] = true;
$config['version'] = "4.0.4";

?>

Dies ist die Art, wie die meisten PHP -Frameworks wie Wordpress usw. dies tun.

5
shamittomar

Hinweis: "Best way" existiert nie. Jede Anwendung und jedes Framework hat seinen eigenen Stil. Während Ihr Beispiel den Trick macht, denke ich, ist es für eine einfache Konfigurationsdatei etwas ressourcenlastig.

  • Sie können dies mit einzelnen Variablen wie Amber hervorgehoben tun.
  • Sie können dies mit Arrays tun. Dies ist der gängigste Ansatz, und Sie können Ihre Konfigurationsdatei jederzeit problemlos bearbeiten.
  • Sie können es mit INI-Dateien machen, die PHP leicht zu analysieren

Bearbeiten:

Edward, bitte schau dir die Beispiele von parse_ini_file an. Sie können die INI-Datei mit einem einfachen Befehl laden. Anschließend können Sie die Variablen in einer Klasse wie in Ihrem Beispiel verwenden. 

2
fabrik

Ich denke, es gibt ziemlich viele Möglichkeiten, aber die gebräuchlichsten Methoden sind das Speichern von Text in Dateien wie .csv, .ini, .xml. Mit kleinen Tricks können Sie diese Dateien schützen, sodass niemand die Dateien direkt laden kann.

ein INI-File Beispiel:

;<?php die(); ?>
[config1]
var1 = 'value1';
var2 = 'value2';
...
[config2]
...

Der ; wird in ini-Dateien als Kommentar betrachtet. Wenn Sie also die Datei mit einem Ini-Parser einlesen, wird diese Zeile ignoriert. Wenn jemand direkt über die URL auf die Datei zugreift, wird die Funktion die() ausgeführt. Dies funktioniert nur, wenn die INI-Datei eine Dateierweiterung wie .php trägt, damit der Server weiß, dass dies ausgeführt und nicht als Klartext angezeigt werden soll.

Mögliche Nachteile der meisten Datei-Basis-Konfigurationsspeicher sind Probleme mit einigen utf8-Zeichen.

Zend_Config ist eine Komponente des Zend-Frameworks, die mehrere Speicheradapter mit einer einfach zu bedienenden API bietet.

2
Alex Sawallich

In PHP verwende ich immer ein ".htaccess", um meine Konfigurationsdatei zu schützen (Doppelter Schutz)

1
Oyeme

Da PHP OO verwenden kann, gehe ich gerne mit einer "Config-Klasse":

class Config
{
    /**
     * ---------------------------------
     * Database - Access
     * --------------------------------- 
     */

    /**
     * @var String
     */
    const DB_DRIVER = 'pgsql';

    const DB_USER = 'postgres';

    const DB_PASSWORD = 'postgres';

    const DB_NAME = 'postgres';
}

Es ist leicht zugänglich mit Config :: DB_DRIVER. Die Datei muss nicht hinzugefügt werden, da der Autoloader der Anwendung dies für Sie erledigt. Natürlich muss die Datei noch geschützt werden.

1
DrColossos

Die übliche Route ist die Verwendung von define:

define('MYSQL_USER', 'ROOT');

und auf sie in der gesamten Anwendung über MYSQL_USER zugreifen:

$user = MYSQL_USER;

Arrays werden auf diese Weise jedoch nicht unterstützt.

0
raveren

Es gibt wenige Möglichkeiten:

  1. Sie können die Konfigurationsdatei (ini, json, xml oder yaml) verwenden. Für ini gibt es parse_ini_file, für JSON gibt es json_decode (+ file_get_contents), für YAML muss eine externe Bibliothek verwendet werden (Suche nach sfYaml)

  2. Sie können eine Konfigurationsdatei mit Variablen oder Konstanten haben (besser für unveränderliche Konfigurationen und in allen Bereichen zugänglich), die Sie in Ihr Skript aufnehmen:

    define ('ROOT_DIR', '\ home\www');

    $ sRootDir = '\ home\www';

Wenn Sie OO-orientiert sind, können Sie es als Eigenschaften in die Klasse einschließen. Sie haben nicht für jede Eigenschaft eine Getter-Methode.

class Config
{
    public $var1 = 'xxx';
    public $var2 = 'yyy';
}

($ c = new Config (); drucke $ c-> var1)

oder 

static class Config
{
    public static $var1 = 'xxx';
    public static $var2 = 'yyy';
}

(print c :: $ var1)

Am besten verwenden Sie eine Klasse vom Typ Registrierung, die das Singleton-Muster implementiert und in der Lage ist, config aus der angegebenen Datei zu lesen.

0
ts.

Telnet? OMG Ich bin in eine Zeitgeschichte geraten und 1992 angekommen!

Aber im Ernst, bei IIRC gibt es Tools, mit denen asp.net (und andere Sprachen) Sitzungsdaten analysieren können - was nur ein serialisiertes PHP-Array ist. Ich würde versuchen, die globalen Einstellungen als eine Art Schattensitzung in PHP zu implementieren. Selbst wenn Sie Ihre Konfigurationseinstellungen nicht als serialisiertes PHP - Array speichern, können Sie sie mit einem eigenen Session-Handler zur Laufzeit zur Laufzeit abbilden.

In Bezug auf den Speicherort der Daten ist dies schwieriger, wenn Sie vermutlich auf einer Microsoft-Plattform laufen. Offensichtlich möchten Sie nicht die Kosten für den Festplattenzugriff für jede Anfrage. Obwohl NT einige Datenträger zwischenspeichert, ist es (IME) nicht so effektiv wie andere Betriebssysteme. Memcached scheint eine Lösung dafür zu sein. Es scheint scheint nutzbar zu sein von asp.net.

HTH

0
symcbean

Um testbar zu sein, verwende ich eine Config-Klasse, die die eigentlichen Konfigurationsdaten enthält, und eine AppConfig-statische Klasse, die einen Verweis auf ein Config-Objekt enthält, das beim Bootstrap aus anwendungsweiten Konfigurationsdateien geladen wird (bei Bootstrap injizierte Abhängigkeit). In der Testumgebung ändere ich nur das Config-Objekt. Siehe https://github.com/xprt64/Config

0