web-dev-qa-db-fra.com

Quelle est la meilleure façon de sauvegarder les variables de configuration dans un PHP application web?

Je bascule souvent entre les développements .NET et PHP. Avec Sites ASP.NET J’enregistre les informations de configuration (chaînes de connexion, répertoires, paramètres d’application, par exemple) dans le fichier web.config qui est correctement protégé et permet d’accéder facilement aux valeurs, etc.

DansPHP, je résous ceci avec une classe qui a des méthodes statiques pour chaque variable:

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

Le fichier est inclus par l'application, les variables sont accessibles en une ligne:

$dp = webconfig::defaultPageIdCode();

Et comme PHP n’est pas compilé, il est facile de telnet in et de modifier une valeur pour un site Web de toute façon, cette solution fonctionne assez bien et me donne ces deux avantages :

  • Je peux ajouter de la logique à une variable de configuration sans casser son interface avec l'application
  • ces variables de configuration apparaissent sous la forme intellisense dans mon exemple. Eclipse, NetBeans, etc.

Mais je peux imaginer qu'il existe d'autres moyens par lesquels les gens résolvent de sauvegarder les paramètres de configuration Web dans PHP, ce qui peut présenter d'autres avantages.

Surtout ceux qui ont de l'expérience avec un certain nombre de cadres PHP, quels sont les autres moyens de sauvegarder les variables de configuration et leurs avantages et inconvénients?

41
Edward Tanguay

J'ai tendance à utiliser une classe statique Settings en PHP, c'est parce que

  • Il a une portée globale.
  • Vous pouvez activer/désactiver les modifications apportées aux configurations protégées.
  • Vous pouvez ajouter des paramètres n'importe où dans l'exécution.
  • Vous pouvez automatiser la classe pour extraire les configurations publiques à partir d'un fichier/d'une base de données.

Exemple:

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]);
    }
}

Ensuite, dans votre environnement d'exécution, si vous avez d'abord chargé ce fichier, suivi de votre fichier de configuration de base de données, votre fichier de configuration de base de données ressemblerait à ceci:

<?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/');

Comme vous pouvez le voir, nous avons une méthode __get qui devrait seulement être autorisée à récupérer des variables publiques. Voici un exemple de pourquoi nous avons ceci:

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

Indépendamment du fait que nous ayons utilisé cet objet en tant qu’objet statique, les valeurs doivent rester telles qu’elles soient maintenant dans le modèle, disons.

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

Et cela ne vous permettra d'avoir accès aux données publiques que pendant la période initialisée.

Cela peut devenir beaucoup plus complexe mais plus convivial, quelques exemples:

  • Une méthode loadConfig pour analyser automatiquement un fichier de configuration, xml, php, yaml.
  • Si vous enregistrez un shutdown_function, vous pouvez mettre à jour automatiquement la base de données avec les nouveaux paramètres.
  • Vous pouvez automatiquement renseigner la classe avec config à partir de cette base de données.
  • Vous pouvez implémenter des itérateurs pour le rendre compatible avec le bouclage.
  • Beaucoup plus.

Cela aussi est de loin la meilleure méthode pour mener à bien ce travail.

23
RobertPitt

Pour ce faire, stockez-les directement dans une array et enregistrez le fichier sous le nom config.php.

<?php

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

?>

C'est la façon dont la plupart des PHP frameworks tels que Wordpress, etc. le font.

5
shamittomar

Remarque: le "meilleur moyen" n'existe jamais. Chaque application et chaque structure font leur propre style. Bien que votre exemple soit efficace, je pense que c'est un peu lourd en ressources pour un simple fichier de configuration.

  • Vous pouvez le faire avec des variables simples comme Amber a souligné
  • Vous pouvez le faire avec des tableaux c'est l'approche la plus courante et vous pouvez toujours facilement modifier votre fichier de configuration.
  • Vous pouvez le faire avec des fichiers .ini que PHP analyser facilement

Modifier:

Edward, regarde les exemples de parse_ini_file. Vous pouvez charger le fichier .ini avec une simple commande, puis vous pouvez utiliser les variables d'une classe comme dans votre exemple. 

2
fabrik

Je pense qu'il y a beaucoup de possibilités, mais les méthodes les plus courantes consistent à stocker le texte brut dans des fichiers tels que .csv, .ini, .xml. Avec de petites astuces, vous pouvez protéger ces fichiers, afin que personne ne puisse les charger directement.

un exemple de fichier INI:

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

Le ; est considéré comme un commentaire dans les fichiers ini. Ainsi, lorsque vous lirez le fichier avec un analyseur ini, cette ligne sera ignorée. Si quelqu'un accède au fichier directement via url, la fonction die()- sera exécutée. Cela ne fonctionne que si le fichier INI porte une extension de fichier telle que .php, de sorte que le serveur sache que cela doit être exécuté et non affiché sous forme de texte brut.

Le désavantage possible de la plupart des fichiers-base-config-storages sont des problèmes avec certains caractères utf8.

Zend_Config est un composant de Zend-Framework, qui offre des possibilités pour plusieurs adaptateurs de stockage avec une API facile à utiliser.

2
Alex Sawallich

Dans PHP, j'utilise toujours un ".htaccess" pour protéger mon fichier de configuration (Double protection)

1
Oyeme

Puisque PHP peut utiliser OO, j'aime bien aller avec une "classe de configuration":

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

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

    const DB_USER = 'postgres';

    const DB_PASSWORD = 'postgres';

    const DB_NAME = 'postgres';
}

Il est facile d’accéder à Config :: DB_DRIVER. Pas besoin d'inclure le fichier car l'autoloader de l'application le fera pour vous. Bien sûr, la protection du fichier reste à faire.

1
DrColossos

La voie habituelle est d'utiliser define:

define('MYSQL_USER', 'ROOT');

et accédez-y partout dans l'application via MYSQL_USER:

$user = MYSQL_USER;

Cependant, les tableaux ne sont pas pris en charge de cette manière.

0
raveren

Il y a peu de possibilités:

  1. Vous pouvez utiliser un fichier de configuration (ini, json, xml ou yaml). Pour ini vous avez parse_ini_file, pour JSON il y a json_decode (+ file_get_contents), pour YAML vous devez utiliser une bibliothèque externe (recherchez sfYaml)

  2. Vous pouvez avoir un fichier de configuration avec des variables ou des constantes (mieux pour une configuration immuable et accessible dans toutes les portées), que vous incluez dans votre script:

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

    $ sRootDir = '\ home\www';

Si vous êtes orienté objet orienté objet, vous pouvez l'envelopper en classe sous la forme de propriétés. Vous n'avez pas de méthode getter pour chaque propriété. Vous pouvez simplement avoir:

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

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

ou 

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

(print c :: $ var1)

Le mieux est d'avoir une classe de type registre, implémentant un motif singleton et capable de lire la configuration à partir d'un fichier donné.

0
ts.

Telnet? OMG Je suis tombé dans une guerre du temps et je suis arrivé en 1992!

Mais sérieusement, IIRC existe des outils qui permettent à asp.net (et à d’autres langages) d’analyser les données de session - ce qui n’est qu’un tableau php sérialisé. J'essaierais d'implémenter les paramètres globaux comme une sorte de session shadow dans PHP. Même si vous ne stockez pas vos paramètres de configuration sous forme de tableau PHP sérialisé, vous pouvez les mapper dans la session au moment de l'exécution à l'aide de votre propre gestionnaire de session.

Pour ce qui est du lieu où vous stockez les données, c’est plus compliqué lorsque vous utilisez probablement une plate-forme Microsoft. Évidemment, vous ne voulez pas que l’accès au disque soit coûteux pour chaque demande. Bien que NT fasse une mise en cache de disque, ce n'est pas (IME) tout aussi efficace que les autres OS. Memcached semble être une solution à cela. Il semble semble être utilisable de asp.net.

HTH

0
symcbean

Pour pouvoir être testé, j'utilise une classe Config qui contient les données de configuration réelles et une classe AppConfig statique qui contient une référence à un objet Config chargé au démarrage à partir de fichiers de configuration à l'échelle de l'application (dépendance injectée au démarrage). Dans l'environnement de test, je ne change que l'objet Config. Voir https://github.com/xprt64/Config

0
Constantin Galbenu