【问题标题】:Storing, Updating, Retrieving settings for a PHP Application without a Database在没有数据库的情况下存储、更新、检索 PHP 应用程序的设置
【发布时间】:2009-07-26 23:13:57
【问题描述】:

我需要能够将 php 应用程序的数据存储在一个文件中。我需要能够在没有 PHP 本身以外的任何外部依赖项的情况下做到这一点。

这是我的要求:

  • 设置不会经常更新/添加/删除。因此,设置的更新不必非常有效。但是,我确实希望能够通过 PHP 脚本来完成这一切,而不是通过编辑文件。
  • 设置会不断被读取,因此读取设置必须非常高效。
  • 设置采用独特的格式,如果我将它们放在一个数组中,它可能类似于 $Settings["Database"]["AccessSettings"]["Username"]["myDBUsername"];
    $Settings["Database"]["AccessSettings"]["Password"]["myDBPassword"];

我不希望像上面提到的那样将设置存储在数组中。相反,我更喜欢一些访问方法:getConfig("Database","Accesssettings","Username") 将返回 'myDBUsername'。这样做的原因是我想限制我存储在全局范围内的变量。

获取/检索这些的最佳方式是什么?

执行我认为可能是 xml 文件的层次结构,但我不确定 PHP 在访问 xml 文件时是什么样的(尤其是我需要能够添加、编辑和删除的事实)。如果它应该是 XML,我应该研究什么样的 xml 访问。

如果它是另一种格式,我想要一些正确的方向,以了解如何使用该格式。

【问题讨论】:

  • 这个会很有趣。
  • 请在下面查看我的更新答案。

标签: php xml configuration-files


【解决方案1】:

布赖恩,parse_ini_file 是你所需要的。

啊,我错过了您将通过 PHP 进行编辑的要求。

在这种情况下,没有任何原生 PHP 可用于此目的。你必须自己动手。

不过,您只需使用 Zend_Config_Ini 就可以为自己节省 时间。我知道您声明您不想使用其他任何东西,但是 Zend 框架的结构允许您使用您需要的任何部分。 Zend_Config 可以单独使用。您当然可以将这几个类添加到您的项目中,让它们处理您的 INI 文件解析。

以下是使用上述示例的示例:

[config]
Database.AccessSettings.Username = myDBUsername
Database.AccessSettings.Password = myDBPassword

您可以像这样简单地加载和访问它:

$config = new Zend_Config_Ini('/path/to/ini', 'config');
echo $config->Datbase->AccessSettings->Username; // prints "myDBUsername"
echo $config->Datbase->AccessSettings->Password; // prints "myDBPassword"

要编辑和保存您的配置,您可以使用以下内容:

$config->Database->AccessSettings->Password = "foobar";
$writer = new Zend_Config_Writer_Ini(array('config'   => $config,
                                           'filename' => 'config.ini'));
$writer->write();

编辑

不太清楚为什么人们会根据 vog 被误导的 cmets 投反对票。使用独占锁可以很简单地让多人可以写。 Zend_Config_Writer 使用file_put_contents 进行写入,它始终 支持 LOCK_EX 标志,它专门锁定文件以进行写入。使用此标志时,您不能让多个写入者同时尝试更新文件。

要将此标志与 Zend_Config_Writer 一起使用,如下所示:

$writer = new Zend_Config_Writer_Ini(array('config'   => $config,
                                           'filename' => 'config.ini'));
$writer->setExclusiveLock(true);
$writer->write();

另一种语法:

$writer = new Zend_Config_Writer_Ini();
$writer->write('config.ini', $config, true); // 3rd parameter is $exclusiveLock

【讨论】:

  • 这将在多个 Web 客户端并行访问时严重失败。
  • @vog:这就是缓存的用途。
  • 此外,假设 ANY 生产 PHP 站点正在使用某种类型的字节码缓存,该缓存提供用户缓存,例如 APC。
  • “设置不会经常更新/添加/删除。”为此投票反对我是愚蠢的。我们甚至不知道这个一个网络应用程序,也不知道它会支持多个客户端。
  • @vog:你的 cmets 被误导了,而且是错误的。 @Brian:我在上面更新了我的答案,是的,这是可能的。
【解决方案2】:

如果您不是手工编辑,请使用序列化数据。

使用serialize 编写配置:

file_put_contents('myConfig.txt', serialize($Settings));

使用unserialize读取配置:

$Settings = unserialize(file_get_contents('myConfig.txt'));

您可以使用 PHP 魔术函数 __get() 和 __set() 编写一个用于修改和获取此数据值的类。

【讨论】:

  • 这将在多个客户端并行访问时严重失败。
  • 请澄清,您当然会与多个设置器发生冲突,但多个读取器不会有问题。问题的作者说“设置不会经常更新/添加/删除。所​​以设置的更新不一定非常有效。但是,我确实希望能够通过 PHP 脚本完成这一切,而不是通过编辑文件。”
  • 当然我的意思是并行写访问。 “并行写入干净地相互覆盖”和“并行写入留下无法再读取的混乱”之间存在差异。尽管第一个变体可能是可以接受的,但第二个绝对不是。但是,第二种情况是可能的,因为 file_put_contents() 不是原子的。
  • @hobodave:请不要亲自投票。我不知道你是否注意到了,但是在你向我解释了为什么它被误导后,删除了我的答案。
【解决方案3】:

如果您愿意加入库,可以使用 Spyc 并将您的配置放在 YAML 文件中。

您也可以使用PHP's support for SQLite,这意味着您的数据库只是一个文件,因此不需要数据库服务器。

【讨论】:

    【解决方案4】:

    DBM 文件可能不是一个坏主意。 PHP 内置了对各种 DBM 文件种类的支持:

    http://www.php.net/manual/en/book.dba.php

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-31
      • 2011-06-13
      • 1970-01-01
      • 1970-01-01
      • 2015-01-25
      • 2018-11-18
      • 2011-11-08
      • 2013-04-15
      相关资源
      最近更新 更多