在 PHP 中创建配置文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14752470/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Creating a config file in PHP
提问by Ali Akbar Azizi
I want to create a config file for my PHP project, but I'm not sure what the best way to do this is.
我想为我的 PHP 项目创建一个配置文件,但我不确定这样做的最佳方法是什么。
I have 3 ideas so far.
到目前为止,我有 3 个想法。
1-Use Variable
1-使用变量
$config['hostname'] = "localhost";
$config['dbuser'] = "dbuser";
$config['dbpassword'] = "dbpassword";
$config['dbname'] = "dbname";
$config['sitetitle'] = "sitetitle";
2-Use Const
2-使用常量
define('DB_NAME', 'test');
define('DB_USER', 'root');
define('DB_PASSWORD', '');
define('DB_HOST', 'localhost');
define('TITLE', 'sitetitle');
3-Use Database
三用数据库
I will be using the config in classes so I'm not sure which way would be the best or if there is a better way.
我将在课程中使用配置,所以我不确定哪种方式最好,或者是否有更好的方式。
回答by Hugo Mota
One simple but elegant way is to create a config.phpfile (or whatever you call it) that just returns an array:
一种简单而优雅的方法是创建一个config.php只返回一个数组的文件(或任何你称之为的文件):
<?php
return array(
'host' => 'localhost',
'username' => 'root',
);
And then:
进而:
$configs = include('config.php');
回答by Marcio Mazzucato
Use an INI file is a flexible and powerful solution! PHP has a native functionto handle it properly. For example, it is possible to create an INI file like this:
使用 INI 文件是一个灵活而强大的解决方案!PHP 有一个本地函数来正确处理它。例如,可以像这样创建一个 INI 文件:
app.ini
应用程序文件
[database]
db_name = mydatabase
db_user = myuser
db_password = mypassword
[application]
app_email = [email protected]
app_url = myapp.com
So the only thing you need to do is call:
所以你唯一需要做的就是调用:
$ini = parse_ini_file('app.ini');
Then you can access the definitions easily using the $iniarray.
然后您可以使用$ini数组轻松访问定义。
echo $ini['db_name']; // mydatabase
echo $ini['db_user']; // myuser
echo $ini['db_password']; // mypassword
echo $ini['app_email']; // [email protected]
IMPORTANT:For security reasons the INI file must be in a non public folder
重要提示:出于安全原因,INI 文件必须位于非公用文件夹中
回答by BoDeX
I use a slight evolution of @hugo_leonardo 's solution:
我使用了@hugo_leonardo解决方案的轻微演变:
<?php
return (object) array(
'host' => 'localhost',
'username' => 'root',
'pass' => 'password',
'database' => 'db'
);
?>
This allows you to use the object syntax when you include the php : $configs->hostinstead of $configs['host'].
这允许您在包含 php 时使用对象语法:$configs->host而不是$configs['host'].
Also, if your app has configs you need on the client side (like for an Angular app), you can have this config.phpfile contain all your configs (centralized in one file instead of one for JavaScript and one for PHP). The trick would then be to have another PHP file that would echoonly the client side info (to avoid showing info you don't want to show like database connection string). Call it say get_app_info.php:
此外,如果您的应用程序在客户端具有您需要的配置(例如 Angular 应用程序),您可以让此config.php文件包含您的所有配置(集中在一个文件中,而不是集中在一个文件中,而不是一个用于 JavaScript,一个用于 PHP)。诀窍是拥有另一个echo仅包含客户端信息的PHP 文件(以避免显示您不想显示的信息,例如数据库连接字符串)。调用它说get_app_info.php:
<?php
$configs = include('config.php');
echo json_encode($configs->app_info);
?>
The above assuming your config.phpcontains an app_infoparameter:
以上假设您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/#/"
)
);
?>
So your database's info stays on the server side, but your app info is accessible from your JavaScript, with for example a $http.get('get_app_info.php').then(...);type of call.
因此,您的数据库信息保留在服务器端,但您的应用程序信息可通过 JavaScript 访问,例如$http.get('get_app_info.php').then(...);调用类型。
回答by symcbean
The options I see with relative merits / weaknesses are:
我看到的具有相对优点/缺点的选项是:
File based mechanisms
基于文件的机制
These require that your code look in specific locations to find the ini file. This is a difficult problem to solve and one which always crops up in large PHP applications. However you will likely need to solve the problem in order to find the PHP code which gets incorporated / re-used at runtime.
这些要求您的代码在特定位置查找以找到 ini 文件。这是一个难以解决的问题,并且在大型 PHP 应用程序中总是会出现。但是,您可能需要解决问题才能找到在运行时合并/重用的 PHP 代码。
Common approaches to this are to always use relative directories, or to search from the current directory upwards to find a file exclusively named in the base directory of the application.
对此的常见方法是始终使用相对目录,或者从当前目录向上搜索以查找在应用程序的基本目录中专门命名的文件。
Common file formats used for config files are PHP code, ini formatted files, JSON, XML, YAML and serialized PHP
用于配置文件的常见文件格式有 PHP 代码、ini 格式文件、JSON、XML、YAML 和序列化 PHP
PHP code
PHP代码
This provides a huge amount of flexibility for representing different data structures, and (assuming it is processed via include or require) the parsed code will be available from the opcode cache - giving a performance benefit.
这为表示不同的数据结构提供了巨大的灵活性,并且(假设它是通过 include 或 require 处理的)解析的代码将从操作码缓存中获得 - 从而提高性能。
The include_pathprovides a means for abstracting the potential locations of the file without relying on additional code.
所述的include_path提供用于提取的文件的潜在位置,而不依赖于额外的代码的装置。
On the other hand, one of the main reasons for separating configuration from code is to separate responsibilities. It provides a route for injecting additional code into the runtime.
另一方面,将配置与代码分离的主要原因之一是职责分离。它提供了向运行时注入额外代码的途径。
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....
如果配置是从工具创建的,则可以验证工具中的数据,但没有标准函数来转义数据以嵌入 PHP 代码,如 HTML、URL、MySQL 语句、shell 命令...... .
Serialized dataThis is relatively efficient for small amounts of configuration (up to around 200 items) and allows for use of any PHP data structure. It requires very little code to create/parse the data file (so you can instead expend your efforts on ensuring that the file is only written with appropriate authorization).
序列化数据这对于少量配置(最多约 200 项)来说相对高效,并且允许使用任何 PHP 数据结构。它只需要很少的代码来创建/解析数据文件(因此您可以花精力确保文件只在适当的授权下写入)。
Escaping of content written to the file is handled automatically.
写入文件的内容的转义是自动处理的。
Since you can serialize objects, it does create an opportunity for invoking code simply by reading the configuration file (the __wakeup magic method).
由于您可以序列化对象,因此它确实为通过读取配置文件(__wakeup 魔术方法)来调用代码创造了机会。
Structured file
结构化文件
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.
按照 Marcel 或 JSON 或 XML 的建议将其存储为 INI 文件还提供了一个简单的 api 来将文件映射到 PHP 数据结构(除了 XML,用于转义数据并创建文件),同时消除代码调用使用序列化 PHP 数据的漏洞。
It will have similar performance characteristics to the serialized data.
它将具有与序列化数据相似的性能特征。
Database storage
数据库存储
This is best considered where you have a huge amount of configuration but are selective in what is needed for the current task - I was surprised to find that at around 150 data items, it was quicker to retrieve the data from a local MySQL instance than to unserialize a datafile.
当您有大量配置但对当前任务所需的内容有选择性时,最好考虑这样做 - 我惊讶地发现在大约 150 个数据项中,从本地 MySQL 实例检索数据比从反序列化一个数据文件。
OTOH its not a good place to store the credentials you use to connect to your database!
OTOH 不是存储用于连接到数据库的凭据的好地方!
The execution environment
执行环境
You can set values in the execution environmentPHP is running in.
您可以在PHP 运行的执行环境中设置值。
This removes any requirement for the PHP code to look in a specific place for the config. OTOH it does not scale well to large amounts of data and is difficult to change universally at runtime.
这消除了 PHP 代码在特定位置查找配置的任何要求。OTOH 它不能很好地扩展到大量数据,并且很难在运行时普遍更改。
On the client
在客户端
One place I've not mentioned for storing configuration data is at the client. Again the network overhead means that this does not scale well to large amounts of configuration. And since the end user has control over the data it must be stored in a format where any tampering is detectable (i.e. with a cryptographic signature) and should not contain any information which is compromised by its disclosure (i.e. reversibly encrypted).
我没有提到的一个用于存储配置数据的地方是在客户端。同样,网络开销意味着这不能很好地扩展到大量配置。并且由于最终用户可以控制数据,因此必须以一种可检测到任何篡改(即使用加密签名)的格式存储数据,并且不应包含任何会因披露而受到损害的信息(即可逆加密)。
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.
相反,这对于存储最终用户拥有的敏感信息有很多好处 - 如果您没有将其存储在服务器上,则无法从那里窃取。
Network DirectoriesAnother interesting place to store configuration information is in DNS / LDAP. This will work for a small number of small pieces of information - but you don't need to stick to 1st normal form - consider, for example SPF.
网络目录另一个有趣的存储配置信息的地方是在 DNS/LDAP 中。这将适用于少量小块信息 - 但您不需要坚持第一范式 - 考虑,例如SPF。
The infrastucture supports caching, replication and distribution. Hence it works well for very large infrastructures.
该基础架构支持缓存、复制和分发。因此,它适用于非常大的基础设施。
Version Control systems
版本控制系统
Configuration, like code should be managed and version controlled - hence getting the configuration directly from your VC system is a viable solution. But often this comes with a significant performance overhead hence caching may be advisable.
配置,如代码应该被管理和版本控制——因此直接从您的 VC 系统获取配置是一个可行的解决方案。但通常这会带来显着的性能开销,因此缓存可能是可取的。
回答by Colin M
Well - it would be sort of difficult to store your database configuration data in a database - don't ya think?
好吧 - 将您的数据库配置数据存储在数据库中会有点困难 - 你不觉得吗?
But really, this is a pretty heavily opinionated question because any style works really and it's all a matter of preference. Personally, I'd go for a configuration variable rather than constants - generally because I don't like things in the global space unless necessary. None of the functions in my codebase should be able to easily access my database password (except my database connection logic) - so I'd use it there and then likely destroy it.
但实际上,这是一个非常自以为是的问题,因为任何风格都确实有效,而且这完全是个人喜好问题。就个人而言,我会选择配置变量而不是常量 - 通常是因为除非必要,否则我不喜欢全局空间中的东西。我的代码库中的任何函数都不能轻松访问我的数据库密码(除了我的数据库连接逻辑) - 所以我会在那里使用它,然后可能会销毁它。
Edit: to answer your comment - none of the parsing mechanisms would be the fastest (ini, json, etc) - but they're also not the parts of your application that you'd really need to focus on optimizing since the speed difference would be negligible on such small files.
编辑:回答您的评论 - 没有任何解析机制是最快的(ini、json 等) - 但它们也不是您真正需要专注于优化的应用程序部分,因为速度差异会在这样的小文件上可以忽略不计。
回答by trigun0x2
If you think you'll be using more than 1 db for any reason, go with the variable because you'll be able to change one parameter to switch to an entirely different db. I.e. for testing , autobackup, etc.
如果您认为出于某种原因将使用 1 个以上的 db,请使用该变量,因为您将能够更改一个参数以切换到一个完全不同的 db。即用于测试、自动备份等。
回答by Sebastian Skurnóg
You can create a config class witch static properties
您可以创建一个配置类女巫静态属性
class Config
{
static $dbHost = 'localhost';
static $dbUsername = 'user';
static $dbPassword = 'pass';
}
then you can simple use it:
那么你可以简单地使用它:
Config::$dbHost
Sometimes in my projects I use a design pattern SINGLETON to access configuration data. It's very comfortable in use.
有时在我的项目中,我使用设计模式 SINGLETON 来访问配置数据。使用起来非常舒服。
Why?
为什么?
For example you have 2 data source in your project. And you can choose witch of them is enabled.
例如,您的项目中有 2 个数据源。您可以选择启用其中的女巫。
- mysql
- json
- mysql
- json
Somewhere in config file you choose:
您选择的配置文件中的某处:
$dataSource = 'mysql' // or 'json'
When you change source whole app shoud switch to new data source, work fine and dont need change in code.
当您更改源整个应用程序应该切换到新的数据源时,工作正常并且不需要更改代码。
Example:
例子:
Config:
配置:
class Config
{
// ....
static $dataSource = 'mysql';
/ .....
}
Singleton class:
单例类:
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;
}
}
... and somewhere in your code (eg. in some service class):
...以及您代码中的某处(例如,在某些服务类中):
$container->getItemsLoader(AppConfig::getInstance()->getDataSource()) // getItemsLoader need Object of specific data source class by dependency injection
We can obtain an AppConfig object from any place in the system and always get the same copy (thanks to static). The init () method of the class is called In the constructor, which guarantees only one execution. Init() body checks The value of the config $dataSource, and create new object of specific data source class. Now our script can get object and operate on it, not knowing even which specific implementation actually exists.
我们可以从系统中的任何位置获取 AppConfig 对象,并且始终获取相同的副本(感谢静态)。类的init()方法在构造函数中调用,保证只执行一次。Init() 主体检查config $dataSource 的值,并创建特定数据源类的新对象。现在我们的脚本可以获取对象并对其进行操作,甚至不知道实际存在哪个具体实现。
回答by phpalix
Define will make the constant available everywhere in your class without needing to use global, while the variable requires global in the class, I would use DEFINE. but again, if the db params should change during program execution you might want to stick with variable.
定义将使您的类中的任何地方都可以使用常量,而无需使用全局变量,而变量需要在类中使用全局变量,我将使用 DEFINE。但同样,如果 db 参数在程序执行期间发生变化,您可能想要坚持使用变量。
回答by Mihir Chhatre
I normally end up creating a single conn.php file that has my database connections. Then i include that file in all files that require database queries.
我通常最终创建一个具有我的数据库连接的 conn.php 文件。然后我将该文件包含在需要数据库查询的所有文件中。
回答by Alok Rajasukumaran
Here is my way.
这是我的方式。
<?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";
?>
?>
Any doubts please comment
有任何疑问请评论

