优秀的PHP类,用于操作.ini文件

7

我需要能够编辑.ini文件(我正在使用parse_ini_file读取),但要保留注释和格式(换行、缩进)。

您知道有哪些好的类可以为这种操作提供优化的函数吗?


1
您有一些输入和输出的示例吗? - Explosion Pills
看起来像是标准的ini文件,比如php.ini,有4-5个部分,每个部分里面都有一些键值对。 - Alex
此类似的东西是否存在尚不确定(对于PHP而言)。我有一个editconfigini.php,但它忽略了配置文件中的节(sections),只关心特定的键=值(key=value)格式。 - mario
@mario - 存在一些可以做到这一点的东西。例如,Symfony使用ini文件。 - Flukey
@Flukey - 你有没有想到要使用哪个版本的Symfony?1.x版本主要使用ini文件来配置Propel(数据库配置在propel.ini中),但这只是一个配置读取器,好像没有写入器。我猜可能会使用Phing来实现写入器! - halfer
使用Phing创建基于模板的.ini文件,这个链接可能会很有用。话虽如此,我认为Phing对于这个相对琐碎的任务来说是一个庞大而令人生畏的库。 - halfer
4个回答

5

您可以从这里开始,它会读取ini文件,并在写入时保留设置,您需要扩展它以支持添加新条目:

class ini {
    protected $lines;

    public function read($file) {
        $this->lines = array();

        $section = '';

        foreach(file($file) as $line) {
            // comment or whitespace
            if(preg_match('/^\s*(;.*)?$/', $line)) {
                $this->lines[] = array('type' => 'comment', 'data' => $line);
            // section
            } elseif(preg_match('/\[(.*)\]/', $line, $match)) {
                $section = $match[1];
                $this->lines[] = array('type' => 'section', 'data' => $line, 'section' => $section);
            // entry
            } elseif(preg_match('/^\s*(.*?)\s*=\s*(.*?)\s*$/', $line, $match)) {
                $this->lines[] = array('type' => 'entry', 'data' => $line, 'section' => $section, 'key' => $match[1], 'value' => $match[2]);
            }
        }
    }

    public function get($section, $key) {
        foreach($this->lines as $line) {
            if($line['type'] != 'entry') continue;
            if($line['section'] != $section) continue;
            if($line['key'] != $key) continue;
            return $line['value'];
        }

        throw new Exception('Missing Section or Key');
    }

    public function set($section, $key, $value) {
        foreach($this->lines as &$line) {
            if($line['type'] != 'entry') continue;
            if($line['section'] != $section) continue;
            if($line['key'] != $key) continue;
            $line['value'] = $value;
            $line['data'] = $key . " = " . $value . "\r\n";
            return;
        }

        throw new Exception('Missing Section or Key');
    }

    public function write($file) {
        $fp = fopen($file, 'w');

        foreach($this->lines as $line) {
            fwrite($fp, $line['data']);
        }

        fclose($fp);
    }
}

$ini = new ini();
$ini->read("C:\\php.ini");
$ini->set('PHP', 'engine', 'Off');
echo $ini->get('PHP', 'engine');
$ini->write("C:\\php.ini");

谢谢。您知道怎样将注释/空格正则表达式也包括新行(例如空的新行)吗? - Alex
我正在使用你的正则表达式来“记录”额外的数据,比如注释,然后将其添加到由Zend Config类生成的配置之前,这太酷了 :) - Alex
@Alex:我在我的注释正则表达式中忘记了一个问号,这应该使“冒号后跟任何内容”变成可选项。那是如何工作的? - Martin

5

我没有在Zend组件框架中使用过配置写入器,但我使用过配置读取器,它非常可靠。值得一试。


我试过了,真的很酷,但是这个编写者不会保留注释,它只会生成一个新的ini结构 :( - Alex
如果这是唯一的问题,你或许可以尝试在其中加入该功能?当然,如果这样的更改能够回到开源版本中,那将是非常好的——这样你就可以利用它们的升级了。但我猜这取决于Zend关于功能/API稳定性的政策。 - halfer
或者,您可以使用自己的类对Zend编写器类进行子类化,其中包含注释更改。 - halfer


2

PEAR::Config 包支持注释,因此我认为它会保留它们。很可能适合您的需求。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接