Je souhaite créer un fichier de configuration pour mon projet PHP, mais je ne sais pas quel est le meilleur moyen de le faire.
J'ai 3 idées jusqu'à présent.
Variable à 1 utilisation
$config['hostname'] = "localhost";
$config['dbuser'] = "dbuser";
$config['dbpassword'] = "dbpassword";
$config['dbname'] = "dbname";
$config['sitetitle'] = "sitetitle";
Const. 2 utilisations
define('DB_NAME', 'test');
define('DB_USER', 'root');
define('DB_PASSWORD', '');
define('DB_Host', 'localhost');
define('TITLE', 'sitetitle');
base de données à 3 utilisations
Je vais utiliser la configuration dans les classes, donc je ne suis pas sûr du meilleur moyen ou du meilleur moyen.
Un moyen simple mais élégant consiste à créer un fichier config.php
(ou le nom de votre choix) qui renvoie simplement un tableau:
<?php
return array(
'Host' => 'localhost',
'username' => 'root',
);
Puis:
$configs = include('config.php');
Utiliser un fichier INI est une solution flexible et puissante! PHP a ne fonction native pour le gérer correctement. Par exemple, il est possible de créer un fichier INI comme ceci:
app.ini
[database]
db_name = mydatabase
db_user = myuser
db_password = mypassword
[application]
app_email = [email protected]
app_url = myapp.com
Donc, la seule chose que vous devez faire est d'appeler:
$ini = parse_ini_file('app.ini');
Ensuite, vous pouvez accéder facilement aux définitions en utilisant le tableau $ini
.
echo $ini['db_name']; // mydatabase
echo $ini['db_user']; // myuser
echo $ini['db_password']; // mypassword
echo $ini['app_email']; // [email protected]
IMPORTANT: Pour des raisons de sécurité, le fichier INI doit se trouver dans un dossier non public.
J'utilise une légère évolution de celle de @hugo_leonardo solution :
<?php
return (object) array(
'Host' => 'localhost',
'username' => 'root',
'pass' => 'password',
'database' => 'db'
);
?>
Cela vous permet d'utiliser la syntaxe de l'objet lorsque vous incluez php: $configs->Host
au lieu de $configs['Host']
.
De plus, si votre application a les configurations dont vous avez besoin côté client (comme pour une application Angular), vous pouvez faire en sorte que ce fichier config.php
contienne toutes vos configurations (centralisées dans un seul fichier au lieu d'un). JavaScript et un pour PHP). Le truc serait alors d’avoir un autre fichier PHP contenant echo
uniquement les informations côté client (pour éviter d’afficher des informations que vous ne voulez pas afficher comme chaîne de connexion à la base de données). Appelez-le dire get_app_info.php
:
<?php
$configs = include('config.php');
echo json_encode($configs->app_info);
?>
En supposant que votre config.php
contient un paramètre app_info
:
<?php
return (object) array(
'Host' => 'localhost',
'username' => 'root',
'pass' => 'password',
'database' => 'db',
'app_info' => array(
'appName'=>"App Name",
'appURL'=> "http://yourURL/#/"
)
);
?>
Les informations de votre base de données restent donc côté serveur, mais les informations de votre application sont accessibles à partir de votre JavaScript, avec par exemple un type d'appel $http.get('get_app_info.php').then(...);
.
Je suis plutôt surpris de la réponse acceptée ici et du nombre de votes positifs qu’elle a recueillis. À l'exception de la réponse de Marcio Mazzucato, il n'y a aucune discussion sur les avantages/inconvénients relatifs de l'une ou de plusieurs des approches.
Les options que je vois sont:
Mécanismes basés sur les fichiers
Cela nécessite que votre code recherche dans des emplacements spécifiques pour trouver le fichier ini. C’est un problème difficile à résoudre et qui survient toujours dans les grandes applications PHP. Cependant, vous aurez probablement besoin de résoudre le problème pour trouver le code PHP incorporé/réutilisé à l'exécution.
Les méthodes les plus courantes consistent à toujours utiliser des répertoires relatifs ou à rechercher dans le répertoire en cours un fichier exclusivement nommé dans le répertoire de base de l'application.
Les formats de fichier couramment utilisés pour les fichiers de configuration sont le code PHP, les fichiers au format INI, JSON, XML, YAML et PHP sérialisé.
code PHP
Cela offre une grande flexibilité pour la représentation de différentes structures de données et (en supposant qu’il soit traité via include ou require), le code analysé sera disponible à partir du cache opcode, offrant ainsi un avantage en termes de performances.
include_path permet d'extraire les emplacements potentiels du fichier sans recourir à du code supplémentaire.
D'autre part, l'une des principales raisons de séparer la configuration du code est la séparation des responsabilités. Il fournit un moyen d'injecter du code supplémentaire dans le moteur d'exécution.
Si la configuration est créée à partir d'un outil, il peut être possible de valider les données dans l'outil, mais il n'existe pas de fonction standard permettant d'échapper aux données à incorporer dans le code PHP existant pour HTML, les URL et les instructions MySQL. , Commandes Shell ....
Données sérialisées Ceci est relativement efficace pour de petites quantités de configuration (jusqu'à environ 200 éléments) et permet d'utiliser toutes les données PHP. structure. Il faut très peu de code pour créer/analyser le fichier de données (vous pouvez donc déployer tous vos efforts pour que le fichier ne soit écrit qu’avec l’autorisation appropriée).
La sortie du contenu écrit dans le fichier est gérée automatiquement.
Comme vous pouvez sérialiser des objets, cela crée une opportunité pour invoquer du code simplement en lisant le fichier de configuration (la méthode magique __wakeup).
Fichier structuré
Le stocker en tant que fichier INI comme suggéré par Marcel ou JSON ou XML fournit également une simple API permettant de mapper le fichier dans une structure de données PHP (et, à l'exception de XML, d'échapper). les données et créer le fichier) tout en éliminant la vulnérabilité d’appel de code utilisant des données sérialisées PHP.
Ses performances seront similaires à celles des données sérialisées.
Stockage de la base de données
C’est ce qui convient le mieux lorsque vous avez une énorme quantité de configuration mais que vous sélectionnez sélectivement ce qui est nécessaire pour la tâche actuelle. J’ai été surpris de constater qu’à environ 150 éléments de données, il était plus rapide de récupérer les données d’une instance MySQL locale que de désérialiser un fichier de données.
OTOH n'est pas un bon endroit pour stocker les informations d'identification que vous utilisez pour vous connecter à votre base de données!
L'environnement d'exécution
Vous pouvez définir des valeurs dans le environnement d'exécution PHP est en cours d'exécution.
Cela supprime la nécessité pour le code PHP de rechercher la configuration dans un emplacement spécifique. OTOH ne s'adapte pas correctement à de grandes quantités de données et est difficile à modifier universellement au moment de l'exécution.
Sur le client
Un endroit que je n'ai pas mentionné pour stocker les données de configuration est chez le client. Là encore, la surcharge du réseau signifie que cela ne s'adapte pas correctement à de grandes quantités de configuration. Et puisque l’utilisateur final a le contrôle des données, celles-ci doivent être stockées dans un format où toute altération est détectable (c’est-à-dire avec une signature cryptographique) et ne doit contenir aucune information compromise par sa divulgation (c’est-à-dire chiffré de manière réversible).
À l'inverse, le stockage d'informations confidentielles appartenant à l'utilisateur final présente de nombreux avantages. Si vous ne les stockez pas sur le serveur, vous ne pourrez pas les dérober.
Répertoires réseau Un autre endroit intéressant pour stocker les informations de configuration est DNS/LDAP. Cela fonctionnera pour un petit nombre de petites informations - mais vous n'avez pas besoin de vous en tenir à la 1ère forme normale - considérons, par exemple, SPF .
L'infrastructure prend en charge la mise en cache, la réplication et la distribution. Par conséquent, cela fonctionne bien pour les très grandes infrastructures.
Systèmes de contrôle de version
La configuration, comme le code, doit être gérée et contrôlée par la version. Obtenir la configuration directement à partir de votre système VC est donc une solution viable. Mais souvent, cela entraîne un surcoût de performances important, d'où la mise en cache.
Eh bien - il serait un peu difficile de stocker vos données de configuration de base de données dans une base de données - vous ne pensez pas?
Mais en réalité, c’est une question qui suscite beaucoup d’opinion, car tout style fonctionne vraiment et c’est une question de préférence. Personnellement, je choisirais une variable de configuration plutôt que des constantes - généralement parce que je n'aime pas les choses dans l'espace global à moins que ce ne soit nécessaire. Aucune des fonctions de ma base de code ne devrait pouvoir accéder facilement à mon mot de passe de base de données (à l’exception de la logique de connexion à ma base de données). Je l’utiliserais donc là et le détruirais probablement.
Edit: pour répondre à votre commentaire - aucun des mécanismes d'analyse ne serait le plus rapide (ini, json, etc.) - mais ce ne sont pas non plus les parties de votre application sur lesquelles vous devriez vraiment vous concentrer. sur l'optimisation puisque la différence de vitesse serait négligeable sur des fichiers aussi petits.
Define rendra la constante disponible partout dans votre classe sans avoir besoin d'utiliser global, alors que la variable nécessite global dans la classe, j'utiliserais DEFINE. mais encore une fois, si les paramètres de la base de données doivent changer pendant l'exécution du programme, vous voudrez peut-être rester avec variable.
Vous pouvez créer une classe de configuration avec des propriétés statiques
class Config
{
static $dbHost = 'localhost';
static $dbUsername = 'user';
static $dbPassword = 'pass';
}
alors vous pouvez simplement l'utiliser:
Config::$dbHost
Parfois, dans mes projets, j'utilise un modèle de conception SINGLETON pour accéder aux données de configuration. C'est très confortable en utilisation.
Pourquoi?
Par exemple, vous avez 2 sources de données dans votre projet. Et vous pouvez choisir celle qui est activée.
Quelque part dans le fichier de configuration que vous choisissez:
$dataSource = 'mysql' // or 'json'
Lorsque vous changez d’application source entière, vous devez basculer vers une nouvelle source de données, travaillez parfaitement et n’avez pas besoin de changer de code.
Exemple:
Config:
class Config
{
// ....
static $dataSource = 'mysql';
/ .....
}
Classe Singleton:
class AppConfig
{
private static $instance;
private $dataSource;
private function __construct()
{
$this->init();
}
private function init()
{
switch (Config::$dataSource)
{
case 'mysql':
$this->dataSource = new StorageMysql();
break;
case 'json':
$this->dataSource = new StorageJson();
break;
default:
$this->dataSource = new StorageMysql();
}
}
public static function getInstance()
{
if (empty(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
public function getDataSource()
{
return $this->dataSource;
}
}
... et quelque part dans votre code (par exemple, dans une classe de service):
$container->getItemsLoader(AppConfig::getInstance()->getDataSource()) // getItemsLoader need Object of specific data source class by dependency injection
Nous pouvons obtenir un objet AppConfig à partir de n’importe quel endroit du système et toujours obtenir la même copie (grâce à static). La méthode init () de la classe est appelée Dans le constructeur, ce qui garantit une seule exécution. Corps (init) vérifie la valeur de config $ dataSource et crée un nouvel objet d'une classe de source de données spécifique. Maintenant, notre script peut obtenir un objet et l'exploiter, sans savoir même quelle implémentation spécifique existe réellement.
Si vous pensez utiliser plus d'une base de données pour une raison quelconque, utilisez la variable, car vous pourrez modifier un paramètre pour passer à une base de données totalement différente. C'est à dire. pour les tests, la sauvegarde automatique, etc.
Je finis normalement par créer un seul fichier conn.php avec mes connexions à la base de données. Ensuite, j'inclus ce fichier dans tous les fichiers qui nécessitent des requêtes de base de données.
Voici mon chemin.
<?php
define('DEBUG',0);
define('PRODUCTION',1);
#development_mode : DEBUG / PRODUCTION
$development_mode = PRODUCTION;
#Website root path for links
$app_path = 'http://192.168.0.234/dealer/';
#User interface files path
$ui_path = 'ui/';
#Image gallery path
$gallery_path = 'ui/gallery/';
$mysqlserver = "localhost";
$mysqluser = "root";
$mysqlpass = "";
$mysqldb = "dealer_plus";
?>
Des doutes s'il vous plaît commenter