Creating a config file in PHP

我想为我的 PHP 项目创建一个配置文件,但是我不确定最好的方法是什么。

到目前为止我有三个想法。

1-使用变数

$config['hostname'] = "localhost";
$config['dbuser'] = "dbuser";
$config['dbpassword'] = "dbpassword";
$config['dbname'] = "dbname";
$config['sitetitle'] = "sitetitle";

2-Use Const

define('DB_NAME', 'test');
define('DB_USER', 'root');
define('DB_PASSWORD', '');
define('DB_HOST', 'localhost');
define('TITLE', 'sitetitle');

3-使用资料库

我将在类中使用该配置,所以我不确定哪种方法是最好的,或者是否有更好的方法。

222946 次浏览

我通常最终创建一个具有数据库连接的 conn.php 文件。 然后我将该文件包含在所有需要数据库查询的文件中。

DEFINE 将使常量在类中的任何地方都可用,而不需要使用 global,而变量需要在类中使用 global,我将使用 DEFINE。但是,如果 db 参数在程序执行过程中发生变化,那么您可能需要保留变量。

好吧——在数据库中存储数据库配置数据有点困难——你不这样认为吗?

但实际上,这是一个非常固执己见的问题,因为任何风格都是有效的,这完全是个人偏好的问题。就个人而言,我会选择配置变量而不是常量——通常是因为我不喜欢全局空间中的东西,除非有必要。我的代码库中没有一个函数能够轻松地访问我的数据库密码(除了我的数据库连接逻辑)-所以我会在那里使用它,然后可能会销毁它。

编辑 : 回答你的评论——没有一个解析机制是最快的(ini、 json 等)——但是它们也不是你的应用程序中真正需要优化的部分,因为在这样小的文件中速度差异可以忽略不计。

如果您认为出于某种原因将使用多于1 db 的数据库,那么使用变量,因为您可以更改一个参数以切换到一个完全不同的 db。例如测试,自动备份等。

一个简单而优雅的方法是创建一个返回数组的 config.php文件(或者不管你怎么称呼它) :

<?php


return array(
'host' => 'localhost',
'username' => 'root',
);

然后:

$configs = include('config.php');

这是我的方法。

    <?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";


?>

任何疑问请评论

使用 INI 文件是一个灵活而强大的解决方案!PHP 有 本地功能来正确处理它。例如,可以像下面这样创建一个 INI 文件:

阑尾切除术

[database]
db_name     = mydatabase
db_user     = myuser
db_password = mypassword


[application]
app_email = mailer@myapp.com
app_url   = myapp.com

所以你只需要打个电话:

$ini = parse_ini_file('app.ini');

然后,您可以使用 $ini数组轻松地访问这些定义。

echo $ini['db_name'];     // mydatabase
echo $ini['db_user'];     // myuser
echo $ini['db_password']; // mypassword
echo $ini['app_email'];   // mailer@myapp.com

重要提示: 出于安全原因,INI 文件必须位于非公用文件夹中

我使用了@hugo _ leonardo 的 解决方案:

<?php


return (object) array(
'host' => 'localhost',
'username' => 'root',
'pass' => 'password',
'database' => 'db'
);


?>

这允许您在包含 php: $configs->host而不是 $configs['host']时使用对象语法。

另外,如果你的应用程序在客户端有你需要的配置(比如一个 Angular 应用程序) ,你可以让这个 config.php文件包含你所有的配置(集中在一个文件中,而不是一个 JavaScript 文件和一个 PHP 文件)。技巧就是让另一个 PHP 文件只显示客户端信息 echo(避免显示不想显示的信息,比如数据库连接字符串)。把它叫做 get_app_info.php:

<?php


$configs = include('config.php');
echo json_encode($configs->app_info);


?>

以上假设您的 config.php包含一个 app_info参数:

<?php


return (object) array(
'host' => 'localhost',
'username' => 'root',
'pass' => 'password',
'database' => 'db',
'app_info' => array(
'appName'=>"App Name",
'appURL'=> "http://yourURL/#/"
)
);


?>

因此,数据库的信息保留在服务器端,但是应用程序的信息可以通过 JavaScript 访问,例如 $http.get('get_app_info.php').then(...);类型的调用。

我看到的相对优缺点有:

基于文件的机制

这些要求您的代码在特定位置查找 ini 文件。这是一个很难解决的问题,在大型 PHP 应用程序中经常会遇到。然而,您可能需要解决这个问题,以便找到在运行时合并/重用的 PHP 代码。

常见的方法是使用相对目录,或者从工作目录向上搜索,找到一个只在应用程序基本目录中命名的文件。

Common file formats used for config files are PHP code, ini formatted files, JSON, XML, YAML and serialized PHP

PHP 代码

这为表示不同的数据结构提供了巨大的灵活性,并且(假设它是通过 include 或 need 处理的)解析后的代码可以从操作码缓存中获得,从而带来性能优势。

Include _ path提供了一种方法,可以在不依赖其他代码的情况下抽象文件的潜在位置。

另一方面,将配置与代码分离的主要原因之一是分离职责。它提供了向运行库注入其他代码的路由。

If the configuration is created from a tool, it may be possible to validate the data in the tool, but there is no standard function to escape data for embedding into PHP code as exists for HTML, URLs, MySQL statements, shell commands....

序列化数据 这对于少量的配置(最多200个项)是相对有效的,并且允许使用任何 PHP 数据结构。创建/解析数据文件只需要很少的代码(因此您可以将精力放在确保只使用适当的授权编写文件上)。

转义写入文件的内容是自动处理的。

由于您可以序列化对象,所以它确实创建了一个机会,通过读取配置文件(_ _ wakeup 神奇方法)来调用代码。

结构化文件

Storing it as a INI file as suggested by Marcel or JSON or XML also provides a simple api to map the file into a PHP data structure (and with the exception of XML, to escape the data and create the file) while eliminating the code invocation vulnerability using serialized PHP data.

它将具有与序列化数据相似的性能特征。

数据库存储

这是最好考虑的地方,您有大量的配置,但是在什么是需要为当前的任务选择-我惊讶地发现,在大约150个数据项,它更快地从本地 MySQL 实例检索数据比反序列化一个数据文件。

OTOH 不是存储用于连接到数据库的凭据的好地方!

执行环境

您可以在运行的 执行环境 PHP 中设置值。

这消除了 PHP 代码在特定位置查找配置的任何要求。OTOH 不能很好地扩展到大量数据,并且难以在运行时进行普遍更改。

在客户身上

有一个存储配置数据的地方我没有提到,那就是客户机。同样,网络开销意味着这无法很好地扩展到大量配置。由于终端用户对数据拥有控制权,因此数据必须以一种可以检测到任何篡改的格式(即加密签名)存储,而且不应该包含任何因披露数据而受到损害的信息(即可逆加密)。

Conversely, this has a lot of benefits for storing sensitive information which is owned by the end user - if you are not storing this on the server, it cannot be stolen from there.

网络目录 存储配置信息的另一个有趣的地方是 DNS/LDAP。这将适用于少量的小信息片段-但是您不需要坚持第一个正常的形式-考虑,例如 防晒霜

该基础设施支持缓存、复制和分发,因此适用于非常大的基础设施。

版本控制系统

配置,像代码应该被管理和版本控制-因此直接从 VC 系统获得配置是一个可行的解决方案。但是这通常伴随着巨大的性能开销,因此缓存可能是明智的。

您可以创建一个配置类,该配置类具有静态属性

class Config
{
static $dbHost = 'localhost';
static $dbUsername = 'user';
static $dbPassword  = 'pass';
}

然后你可以简单地使用它:

Config::$dbHost

有时在我的项目中,我使用设计模式 SINGLETON 来访问配置数据。

Why?

例如,您的项目中有2个数据源,您可以选择启用其中的一个。

  • Mysql
  • json

在配置文件的某个地方选择:

$dataSource = 'mysql' // or 'json'

当你改变源代码整个应用程序应切换到新的数据源,工作良好,不需要改变代码。

例如:

配置:

class Config
{
// ....
static $dataSource = 'mysql';
/ .....
}

单身班:

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

... 以及代码中的某个地方(例如某个服务类) :

$container->getItemsLoader(AppConfig::getInstance()->getDataSource()) // getItemsLoader need Object of specific data source class by dependency injection

我们可以从系统中的任何位置获得 AppConfig 对象,并且总是获得相同的副本(多亏了 static)。类的 init ()方法被调用 在构造函数中,它只保证一次执行 值,并创建特定数据源类的新对象。现在我们的脚本可以获取对象并在不知情的情况下对其进行操作 甚至是实际存在的具体实现。

What about something like this ?

class Configuration
{


private $config;


    

public function __construct($configIniFilePath)
{
$this->config = parse_ini_file($configIniFilePath, true);
}


/**
* Gets the value for the specified setting name.
*
* @param string $name the setting name
* @param string $section optional, the name of the section containing the
*     setting
* @return string|null the value of the setting, or null if it doesn't exist
*/
public function getConfiguration($name, $section = null)
{
$configValue = null;


if ($section === null) {
if (array_key_exists($name, $this->config)) {
$configValue = $this->config[$name];
}
} else {
if (array_key_exists($section, $this->config)) {
$sectionSettings = $this->config[$section];
if (array_key_exists($name, $sectionSettings)) {
$configValue = $sectionSettings[$name];
}
}
}


return $configValue;
}
}

如果我有一个 config 文件,比如 config.conf (它可以是 http:// example.com/config.conf )

user=cacom
version = 2021608
status= true

这是我的职责:

function readFileConfig($UrlOrFilePath){


$lines = file($UrlOrFilePath);
$config = array();
    

foreach ($lines as $l) {
preg_match("/^(?P<key>.*)=(\s+)?(?P<value>.*)/", $l, $matches);
if (isset($matches['key'])) {
$config[trim($matches['key'])] = trim($matches['value']);
}
}


return $config;
}

我们可以使用:

$urlRemote = 'http://example.com/default-config.conf';
$localConfigFile = "/home/domain/public_html/config.conf";
$localConfigFile2 = "config.conf";


print_r(readFileConfig($localConfigFile2));
print_r(readFileConfig($localConfigFile));
print_r(readFileConfig($urlRemote));

你可以用这个简单的例子:

define('someprop', 0);

还有

echo someprop; // output 0

就是这个

<?php
$server = "localhost";
$username = "root";
$password = "";
$db = "your_db_name";




$conn = mysqli_connect($server, $username, $password, $db);


if(!$conn){
die('Error in connecting to server or Database');
}
?>