创建ini文件,使用PHP写入值

43

我找不到一种简单的方法来创建一个新文件,将其视为 ini 文件 (而不是 php.ini 或类似... 一个单独的 ini 文件用于每个用户),并使用 PHP 创建/删除值。PHP 似乎没有简易的方法来创建 ini 文件和读取/写入/删除值。到目前为止,它仅限于“读取” - 没有关于创建条目或操作键/值的任何内容。


1
当你说“per user”时,你指的是什么?是指每次使用 PHP 应用程序吗? - Peter Bailey
1
为什么每个用户都需要一个 .ini 文件?这种类型的信息不应该存储在数据库中吗? - Omnipresent
1
@netrox,我认为Peter Bailey理解了你所说的用户 - 是指主机上的用户名(apache正在运行的用户名或其他),还是应用程序的最终用户(即在浏览器中访问它的人)? - Dominic Rodger
1
顺便说一句,欢迎来到stackoverflow.com,这是一个很棒的第一个问题! - Dominic Rodger
2
如果必须将其存储在文件或其他单字段字符串中,您可能需要考虑改用JSON:json_encodejson_decode。它更加灵活(布尔值、整数、数组、对象等)并且非常便携(现在许多语言都有JSON编码器/解码器)。 - Timo Tijhof
显示剩余4条评论
6个回答

53

我在PHP文档的评论中找到了以下代码片段:

function write_ini_file($assoc_arr, $path, $has_sections=FALSE) { 
    $content = ""; 
    if ($has_sections) { 
        foreach ($assoc_arr as $key=>$elem) { 
            $content .= "[".$key."]\n"; 
            foreach ($elem as $key2=>$elem2) { 
                if(is_array($elem2)) 
                { 
                    for($i=0;$i<count($elem2);$i++) 
                    { 
                        $content .= $key2."[] = \"".$elem2[$i]."\"\n"; 
                    } 
                } 
                else if($elem2=="") $content .= $key2." = \n"; 
                else $content .= $key2." = \"".$elem2."\"\n"; 
            } 
        } 
    } 
    else { 
        foreach ($assoc_arr as $key=>$elem) { 
            if(is_array($elem)) 
            { 
                for($i=0;$i<count($elem);$i++) 
                { 
                    $content .= $key."[] = \"".$elem[$i]."\"\n"; 
                } 
            } 
            else if($elem=="") $content .= $key." = \n"; 
            else $content .= $key." = \"".$elem."\"\n"; 
        } 
    } 

    if (!$handle = fopen($path, 'w')) { 
        return false; 
    }

    $success = fwrite($handle, $content);
    fclose($handle); 

    return $success; 
}

用法:

$sampleData = array(
                'first' => array(
                    'first-1' => 1,
                    'first-2' => 2,
                    'first-3' => 3,
                    'first-4' => 4,
                    'first-5' => 5,
                ),
                'second' => array(
                    'second-1' => 1,
                    'second-2' => 2,
                    'second-3' => 3,
                    'second-4' => 4,
                    'second-5' => 5,
                ));
write_ini_file($sampleData, './data.ini', true);

祝你好运!


10
if (!fwrite($handle, $content)) { 后,应该关闭文件句柄。 - Dave Jarvis
5
没有使用章节时,代码中存在一个错误,变量 $key2 应该是 $key。 - kjetilh
@MartinKonecny这是否意味着在非官方解决方案中出现错误是可以接受的? - Tomáš Zato
@TomášZato 不,这意味着他不应该说这是官方代码。就我所知,它可能有漏洞。他从评论部分抓取了它。 - Martin Konecny
抱歉,我第一次没有正确理解您评论的上下文。感谢您让我明确了。 - Tomáš Zato
显示剩余4条评论

7
PEAR有两个(单元测试过的)包可以完成您渴望的任务:
  • Config_Lite - 如果您只需要.ini文件,则非常理想
  • Config - 还可以读取.php和.xml文件
我宁愿使用经过充分测试的代码,而不是编写自己的代码。

7
我不能保证其工作效果,但有一些实现parse_ini_file()相反(即write_ini_file,这不是标准的PHP函数)的建议在parse_ini_file的文档页面上。
您可以使用write_ini_file将值发送到文件中,使用parse_ini_file读取它们 - 修改parse_ini_file返回的关联数组,然后使用write_ini_file将修改后的数组写回文件中。
这对你有用吗?

5
在这段代码中:
else { 
    foreach ($assoc_arr as $key=>$elem) { 
        if(is_array($elem)) 
        { 
            for($i=0;$i<count($elem);$i++) 
            { 
                $content .= $key2."[] = \"".$elem[$i]."\"\n"; 
            } 
        } 
        else if($elem=="") $content .= $key2." = \n"; 
        else $content .= $key2." = \"".$elem."\"\n"; 
    } 
} 

$key2必须被$key替换,否则您将在.ini文件中找到空键。


3

基于上面的答案,我写了这个类,可能会有用。适用于PHP 5.3,但可以很容易地适配到之前的版本。

class Utils
    {
        public static function write_ini_file($assoc_arr, $path, $has_sections)
        {
            $content = '';

            if (!$handle = fopen($path, 'w'))
                return FALSE;

            self::_write_ini_file_r($content, $assoc_arr, $has_sections);

            if (!fwrite($handle, $content))
                return FALSE;

            fclose($handle);
            return TRUE;
        }

        private static function _write_ini_file_r(&$content, $assoc_arr, $has_sections)
        {
            foreach ($assoc_arr as $key => $val) {
                if (is_array($val)) {
                    if($has_sections) {
                        $content .= "[$key]\n";
                        self::_write_ini_file_r(&$content, $val, false);
                    } else {
                        foreach($val as $iKey => $iVal) {
                            if (is_int($iKey))
                                $content .= $key ."[] = $iVal\n";
                            else
                                $content .= $key ."[$iKey] = $iVal\n";
                        }
                    }
                } else {
                    $content .= "$key = $val\n";
                }
            }
        }
    }

从PHP7开始,这行代码 self::_write_ini_file_r(&$content, $val, false) 应该改为 self::_write_ini_file_r($content, $val, false) - DDS

2
我使用这个,它似乎有效。
function listINIRecursive($array_name, $indent = 0)
{
    global $str;
    foreach ($array_name as $k => $v)
    {
        if (is_array($v))
        {
            for ($i=0; $i < $indent * 5; $i++){ $str.= " "; }
            $str.= " [$k] \r\n";
            listINIRecursive($v, $indent + 1);
        }
            else
        {
            for ($i=0; $i < $indent * 5; $i++){ $str.= " "; }
            $str.= "$k = $v \r\n";
        }
    }
 }

它返回要写入.ini文件的文本。

2
如果$array_name包含一个多维数组,那么您的代码片段将失败。也就是说,如果父数组的深度为3或更多,则会出现问题。 - Tivie

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