Filesystem 函数
在线手册:中文  英文

parse_ini_file

(PHP 4, PHP 5)

parse_ini_file解析一个配置文件

说明

array parse_ini_file ( string $filename [, bool $process_sections = false [, int $scanner_mode = INI_SCANNER_NORMAL ]] )

parse_ini_file() 载入一个由 filename 指定的 ini 文件,并将其中的设置作为一个联合数组返回。

ini 文件的结构和 php.ini 的相似。

参数

filename

要解析的 ini 文件的文件名。

process_sections

如果将最后的 process_sections 参数设为 TRUE,将得到一个多维数组,包括了配置文件中每一节的名称和设置。process_sections 的默认值是 FALSE

scanner_mode

Can either be INI_SCANNER_NORMAL (default) or INI_SCANNER_RAW. If INI_SCANNER_RAW is supplied, then option values will not be parsed.

返回值

成功时以关联数组 array 返回设置,失败时返回 FALSE

更新日志

版本 说明
5.3.0 Added optional scanner_mode parameter. Single quotes may now be used around variable assignments. Hash marks (#) may no longer be used as comments and will throw a deprecation warning if used.
5.2.7 On syntax error this function will return FALSE rather than an empty array.
5.2.4 由数字组成的键名和小节名会被 PHP 当作整数来处理,因此以 0 开头的数字会被当作八进制而以 0x 开头的会被当作十六进制。
5.0.0 该函数也开始处理选项值内的新行。
4.2.1 本函数也开始受到安全模式open_basedir 的影响。

范例

Example #1 sample.ini 的内容

; This is a sample configuration file
; Comments start with ';', as in php.ini

[first_section]
one = 1
five = 5
animal = BIRD

[second_section]
path = "/usr/local/bin"
URL = "http://www.example.com/~username"

[third_section]
phpversion[] = "5.0"
phpversion[] = "5.1"
phpversion[] = "5.2"
phpversion[] = "5.3"

Example #2 parse_ini_file() 例子

常量也可以在 ini 文件中被解析,因此如果在运行 parse_ini_file() 之前定义了常量作为 ini 的值,将会被集成到结果中去。只有 ini 的值会被求值。例如:

<?php

define
('BIRD''Dodo bird');

// Parse without sections
$ini_array parse_ini_file("sample.ini");
print_r($ini_array);

// Parse with sections
$ini_array parse_ini_file("sample.ini"true);
print_r($ini_array);

?>

以上例程的输出类似于:

Array
(
    [one] => 1
    [five] => 5
    [animal] => Dodo bird
    [path] => /usr/local/bin
    [URL] => http://www.example.com/~username
    [phpversion] => Array
        (
            [0] => 5.0
            [1] => 5.1
            [2] => 5.2
            [3] => 5.3
        )

)
Array
(
    [first_section] => Array
        (
            [one] => 1
            [five] => 5
            [animal] => Dodo bird
        )

    [second_section] => Array
        (
            [path] => /usr/local/bin
            [URL] => http://www.example.com/~username
        )

    [third_section] => Array
        (
            [phpversion] => Array
                (
                    [0] => 5.0
                    [1] => 5.1
                    [2] => 5.2
                    [3] => 5.3
                )

        )

)

Example #3 parse_ini_file() parsing a php.ini file

<?php
// A simple function used for comparing the results below
function yesno($expression)
{
    return(
$expression 'Yes' 'No');
}

// Get the path to php.ini using the php_ini_loaded_file() 
// function available as of PHP 5.2.4
$ini_path php_ini_loaded_file();

// Parse php.ini
$ini parse_ini_file($ini_path);

// Print and compare the values, note that using get_cfg_var()
// will give the same results for parsed and loaded here
echo '(parsed) magic_quotes_gpc = ' yesno($ini['magic_quotes_gpc']) . PHP_EOL;
echo 
'(loaded) magic_quotes_gpc = ' yesno(get_cfg_var('magic_quotes_gpc')) . PHP_EOL;
?>

以上例程的输出类似于:

(parsed) magic_quotes_gpc = Yes
(loaded) magic_quotes_gpc = Yes

注释

Note:

本函数和 php.ini 文件没有关系,该文件在运行脚本时就已经处理过了。本函数可以用来读取你自己的应用程序的配置文件。

Note:

如果 ini 文件中的值包含任何非字母数字的字符,需要将其括在双引号中(")。

Note: 有些保留字不能作为 ini 文件中的键名,包括:null,yes,no,true 和 false。值为 null,no 和 false 等效于 "",值为 yes 和 true 等效于 "1"。字符 {}|&~![()" 也不能用在键名的任何地方,而且这些字符在选项值中有着特殊的意义。

参见


Filesystem 函数
在线手册:中文  英文

用户评论:

josephbiesek at msn dot com (2013-06-27 16:33:35)

Set an simple ini file to defined constants
$config = parse_ini_file('main.ini');
foreach($config as $key => $value) {
define($key, $value);
}

michel (2013-06-24 23:41:57)

note configuration files should be stored outside you www-root/htdocs folder

grant at rootcentral dot org (2013-06-18 19:46:07)

Somewhere between versions 5.2.5 and 5.3.24, the parsing of unquoted multiword values (e.g. values with embedded spaces) changed.
In 5.3.24, a multiword value where one of the words is a reserved word (null, yes, no, true, false, on, off, none) will cause the function to return an error.
Adding double quotation marks around the value string will solve the problem.

simon dot riget at gmail dot com (2013-02-21 19:23:36)

.ini files or JSON file format as it is also known as, are very useful format to store stuff in. Especially large arrays. 

Strangely enough there is this nice function to read the file, but no function to write it.

So here is one.

Use it as:  put_ini_file(string $file, array $array)

<?php 
function put_ini_file($file$array$i 0){
  
$str="";
  foreach (
$array as $k => $v){
    if (
is_array($v)){
      
$str.=str_repeat(" ",$i*2)."[$k]".PHP_EOL
      
$str.=put_ini_file("",$v$i+1);
    }else
      
$str.=str_repeat(" ",$i*2)."$k = $v".PHP_EOL
  }
 if(
$file)
    return 
file_put_contents($file,$str);
  else
    return 
$str;
}
?>

julien dot moquet at interieur dot gouv dot fr (2012-05-15 10:08:55)

In order to set a " in ini files, you may follow that trick :

The yourfilename.ini file :

[yoursectionhere]
somevalue = "This "QUOTE"string"QUOTE" has quotes"

The PHP code :

<?php
define
('QUOTE''"');

$aInifile parse_ini_file('yourfilename.ini''yoursectionhere');
echo 
'test : ' $aInifile['yoursectionhere']['somevalue'];
?>

miguelgilmartinez at gmail dot com (2012-05-04 07:55:15)

This function won't work if you try to parse a file with an extension which is not ".ini". It won't work if your filename is config.cfg, for instance. In this case, it will return array(0)

Johannes Schmidt (2012-04-21 19:11:42)

#If you want to replace a Setting in the ini, use this code:
/// bool SetCMSSettings(string $Setting, string $replace, string $INI_PATH)
/// $Setting = The Setting, which you want to replace
/// $replace = the new value
public function SetCMSSettings($Setting, $replace, $INI_PATH)
{
$ini = fopen($INI_PATH,"w+");


$i = 0;
while($Content = fgets($ini))
{
if(preg_match("/".$Setting."/", $Content)) {
fwrite($ini, $Setting."=".$replace);
$i = 1;
} else {
fwrite($ini, $Content);
}
}
// If, the setting wasnt replaced.
if($i == 0) {
fwrite($ini, $Setting."=".$replace);
}
fclose($ini);
}

jwka at gmx dot net (2011-11-17 02:52:15)

Just to give novices a heads up since that can be really time consuming:
BE AWARE of CONSTANTS you defined!
ANY INI value NOT IN QUOTES that matches ANY constant will be replaced by the constant's value while any other unquoted value will be regarded as being a text "as is".
If you want to AVOID REPLACEMENTS, be sure you stringently enclose your strings in quotes!
Remark:
The German examples are (have been?) wrong here. It shows(ed?) that [animal]=BIRD but it will be [animal]=Dodo bird.
Example Extension:
In the example, if the INI file's line would have been:
animal = "BIRD" (notice the quotes)
then [animal] would ALLWAYS equal "BIRD", no matter if a constant BIRD would be defined or not.

jerikojerk (2011-08-16 14:51:32)

Please note that despite the changelog telling nothing about it, the parse_ini_file() changed
-> the way it interprets the simple quote (not accepted on my 5.1 php)
-> array index. PHP 5.3 accepts the following but not php 5.1
[section]
param["index"]='value'
param["other index"]='other value'

Alex - webitoria.com (2011-02-04 15:56:24)

Constants in ini files are not expanded if they are concatenated with strings quoted with single quotes, they must be in double quotes only to make constants expanded.
Example:
define ('APP_PATH', '/some/path');
mypath = APP_PATH '/config'
// Constant won't be expanded: [mypath] => APP_PATH '/config'
mypath = APP_PATH "/config"
// Constant will be expanded: [mypath] => /some/path/config
Note "." between constant and following string is not used.
Since Zend_Config_Ini is built on parse_ini_file, it inherits this behaviour.

daevid at daevid dot com (2010-11-10 19:04:22)

Be warned that this function will not only NOT parse 'null', 'true', 'false', etc. but worse, it converts EVERYTHING to strings and sets 'true' values to "1" and null/'false' values to "".

Here is my test.ini file:

[examples]                                  ; this is a section
                                            ; this is a comment line
log_level = E_ALL & ~E_NOTICE 
1 = intkey                                  ; this is a int key
nullvalue = null                            ; this is NULL
truebool = true                             ; this is boolean (TRUE)
falsebool = false                           ; this is boolean (FALSE)
intvalue = -1                               ; this is a integer (-1)
floatvalue = +1.4E-3                        ; this is a float (0.0014)
stringvalue = Hello World                   ; this is a unquoted string
quoted = "Hello World"                      ; this is a quoted string
apostrophed = 'Hello World'                 ; this is a apostrophed string
quoted escaped = "it work's \"fine\"!"      ; this is a quoted string with escaped quotes
apostrophed escaped = 'it work\'s "fine"!'  ; this is a apostrophed string with escaped apostrophes

Here is my test.php page:

<?php
    var_dump
(parse_ini_file('./test.ini'true));
?>

Here is the output:

array
  'examples' => 
    array
      'log_level' => string '6135' (length=4)
      1 => string 'intkey' (length=6)
      'nullvalue' => string '' (length=0)
      'truebool' => string '1' (length=1)
      'falsebool' => string '' (length=0)
      'intvalue' => string '-1' (length=2)
      'floatvalue' => string '+1.4E-3' (length=7)
      'stringvalue' => string 'Hello World' (length=11)
      'quoted' => string 'Hello World' (length=11)
      'apostrophed' => string ''Hello World'' (length=13)
      'quoted escaped' => string 'it work's \fine\!' (length=17)
      'apostrophed escaped' => string ''it work\'sfine' (length=15)

verified with PHP 5.2.4 to 5.3.3

Rolf (2010-09-21 14:27:25)

As of PHP 5.3, you can escape a double quote like this:
description = "an \" example"
But strangely, this fails when you try to escape two consecutive double quotes:
description = "no \"\" good"
Unless there is something between them (in this example, there is a space character):
description = "this is \" \" ok"

uramihsayibok, gmail, com (2010-09-16 01:10:39)

Undocumented feature!

Using ${...} as a value will look to
1) an INI setting, or
2) an environment variable

For example,

<?php

print_r
(parse_ini_string('
php_ext_dir = ${extension_dir}
operating_system = ${OS}
'
));

?>

Array
(
    [php_ext_dir] => ./ext/
    [operating_system] => Windows_NT
)

Present in PHP 5.3.2, likely in 5.x, maybe even earlier too.

Anonymous (2010-09-11 09:42:31)

a ini lexer with regexp:

<?php

@header('Content-Type: text/plain');

$myini = <<<EOT
[examples]                                  ; this is a section
                                            ; this is a comment line
1 = intkey                                  ; this is a int key
nullvalue = null                            ; this is NULL
truebool = true                             ; this is boolean (TRUE)
falsebool = false                           ; this is boolean (FALSE)
intvalue = -1                               ; this is a integer (-1)
floatvalue = +1.4E-3                        ; this is a float (0.0014)
stringvalue = Hello World                   ; this is a unquoted string
quoted = "Hello World"                      ; this is a quoted string
apostrophed = 'Hello World'                 ; this is a apostrophed string
quoted escaped = "it work's \"fine\"!"      ; this is a quoted string with escaped quotes
apostrophed escaped = 'it work\'s "fine"!'  ; this is a apostrophed string with escaped apostrophes

    [[valid special cases]]                 ; this is a section with square brackets and whitespaces at the beginning
quoted multiline = "line1
line2
line3"                                      ; this is a quoted multiline string
apostrophed multiline = "line1
line2
line3"                                      ; this is a apostrophed multiline string
     spaces before key = is ok               ; this line has whitespaces at the beginning
no val =                                    ; this setting has no key
= no key                                    ; this setting has no value
=                                           ; this setting has no key and no value

[bad cases]                                 ; you should never do that but it works
notgood = unquoted"string                   ; this value has a single quote
notgood2 = unapostrophed'string             ; this value has a single apostrophe
bad = "unclosed quotes                      ; this value has unclosed quotes
bad2 = 'unclosed apostrophes                ; this value has unclosed apostrophes

[invalid
section]
invalid setting
EOT;

function 
get_tokens_from_ini_lexer($data$verbose FALSE)
{
    
$regexp '/
    (?<=^|\r\n|\r|\n)
    (?P<line>
        (?:
            (?(?![\t\x20]*;)
                (?P<left_space>[\t\x20]*)
                (?:
                    \[(?P<section>[^;\r\n]+)\]
                    |
                    (?P<setting>
                        (?P<key>
                            [^=;\r\n]+?
                        )?
                        (?P<left_equal_space>[\t\x20]*)
                        (?P<equal_sign>=)
                        (?P<right_equal_space>[\t\x20]*)
                        (?P<val>
                            \x22(?P<quoted>.*?)(?<!\x5C)\x22
                            |
                            \x27(?P<apostrophed>.*?)(?<!\x5C)\x27
                            |
                            (?P<null>null)
                            |
                            (?P<bool>true|false)
                            |
                            (?P<int>[+-]?(?:[1-9]\d{0,18}|0))
                            |
                            (?P<float>(?:[+-]?(?:[1-9]\d*|0))\.\d+(?:E[+-]\d+)?)
                            |
                            (?P<string>[^;\r\n]+?)
                        )?
                    )
                )
            )
            (?P<right_space>[\t\x20]*)
            (?:
                (?P<comment_seperator>;)
                (?P<comment_space>[\t\x20]*)
                (?P<comment>[^\r\n]+?)?
            )?
        )
        |
        (?P<error>
            [^\r\n]+?
        )
    )
    (?=\r\n|\r|\n|$)(?P<crlf>\r\n|\r|\n)?
    |
    (?<=\r\n|\r|\n)(?P<emptyline>\r\n|\r|\n)
    /xsi'
;

    if(!@
is_int(preg_match_all($regexp$data$tokensPREG_SET_ORDER)))
    {
        
// parse error
    
}
    else
    {
        foreach(
$tokens as $i => $token)
        {
            if(!
$verbose)
            {
                unset(
$tokens[$i]['line']);
                unset(
$tokens[$i]['crlf']);
                unset(
$tokens[$i]['setting']);
                unset(
$tokens[$i]['equal_sign']);
                unset(
$tokens[$i]['val']);
                unset(
$tokens[$i]['left_space']);
                unset(
$tokens[$i]['left_equal_space']);
                unset(
$tokens[$i]['right_equal_space']);
                unset(
$tokens[$i]['right_space']);
                unset(
$tokens[$i]['comment_seperator']);
                unset(
$tokens[$i]['comment_space']);
            };

            foreach(
$token as $key => $val)
            {
                if(!@
is_string($key) || !@strlen($val))
                {
                    unset(
$tokens[$i][$key]);
                };
            };
        };

        return(
$tokens);
    };
};

$verbose FALSE;

print_r(get_tokens_from_ini_lexer($myini$verbose));

?>

pd at frozen-bits dot de (2010-08-19 02:21:54)

I use the following syntax to secure my config.ini.php file:

;<?php
;die(); // For further security
;/*

[category]
name="value"

;*/

;?>

Works like a charm and is both: A valid PHP File and a valid ini-File ;)

geggert at web dot de (2010-07-23 06:44:43)

As quick an dirty way to gain the security of that *.ini.php-files you may alternatively use this as first line:

<?php exit(); __halt_compiler();
// the closing tag is just to end up the syntax highlighting ...
// leave these comments and the closing tag away in your ini.php-file!
?>

You can use parse_ini_file() in the normal way and any criminal stranger will only see a ";" then ...

forcestudios.square7.de (2010-06-15 12:46:05)

Tip: you cannot parse an ini-file with this safer structure:

<?php exit();
$data="

[section_one]
test = abc

[section_two]
and_so=on

"
;
?>

(strangers are not able to see this file because php closed the file previously by executing exit();)

But here is a very simple code to prevent this:
<?php

    
class iniParser{
        
        private 
$IniFile;
        private 
$SafeFile;
        private 
$ParseClasses;
        
        public 
$KeysWithoutSections;
        public 
$KeysWithSections;
        
        
        public function 
__construct($FileName$SafeFile false){
            
            
$this->IniFile $FileName;
            
$this->SafeFile $SafeFile;
            
        }
        
        public function 
parseIni($SaveInClass true){
            
            
$FileHandle file($this->IniFile);
            
            
$CountLines count($FileHandle);
            
$Counter 0;
            
            
$NKeys "";
            
            if ( 
$this->SafeFile ){
                
                
$Counter += 2;
                
$CountLines -= 2;
            }
            
            while ( 
$Counter $CountLines ){
                
                
$CurLine $FileHandle[$Counter];
                
                
$CurLineSplit explode("="$CurLine);
                
                
$CurKey $CurLineSplit[0];
                
$CurValue $CurLineSplit[1];
                if( 
$SaveInClass )
                    
$this->Keys[trim($CurKey)] = trim($CurValue);
                    
                else
                    
$NKeys[trim($CurKey)] = trim($CurValue);
                
                
$Counter++;
            }
            
            if( 
$SaveInClass )
                return 
$this->KeysWithoutSections;
            
            else
                return 
$NKeys;
            
        }
        
        public function 
parseIniWithSections($SaveInClass true){
        
            
$FileHandle file($this->IniFile);
            
            
$CountLines count($FileHandle);
            
$Counter 0;
            
            
$LastSection "";
            
            
$NKeys "";
            
            if ( 
$this->SafeFile ){
            
                
$CountLines -= 2;
                
$Counter += 2;
            
            }
            
            while ( 
$Counter $CountLines ){
            
                
$CurLine $FileHandle[$Counter];
                
                if ( 
strpos($CurLine"[") == ){
                
                    
$LastSection $CurLine;
                    continue;
                
                }
                
                
$Explosion explode("="$CurLine);
                
                
$CurKey trim($Explosion[0]);
                
$CurValue trim($Explosion[1]);
                
                if ( 
$SaveInClass 
                    
$this->KeysWithSections[$LastSection][$CurKey] = $CurValue;
                    
                else
                    
$NKeys[$LastSection][$CurKey] = $CurValue;
                
                
            }
            
            if ( 
$SaveInClass )
                return 
$this->KeysWithSections;
                
            else
                return 
$NKeys;
        
        }
        
    };

?>

To use this class just try this script here:

<?php

include "iniparser.php" // class above

$SafeIniParser = new iniParser("test.php"true); // file: test.php, safefile.

$Keys $SafeIniParser->parseIniWithSections(false);

echo 
$Keys["section_one"]["test"];

?>

i used this file:
<?php exit();
$data="

[section_one]
test = abc

[section_two]
and_so=on

"
;
?>

Mauro Gabriel Titimoli (2010-01-19 15:14:52)

I have recently finished an implementacion of a multiple configuration type class.

<?php
class Configuration {
    const 
AUTO 0;
    const 
JSON 2;
    const 
PHP_INI 4;
    const 
XML 16;

    static private 
$CONF_EXT_RELATION = array(
        
'json' => 2// JSON
        
'ini' => 4,  // PHP_INI
        
'xml' => 16  // XML
    
);

    static private 
$instances;

    private 
$data;

    static public function 
objectToArray($obj) {
        
$arr = (is_object($obj))?
            
get_object_vars($obj) :
            
$obj;

        foreach (
$arr as $key => $val) {
            
$arr[$key] = ((is_array($val)) || (is_object($val)))?
                
self::objectToArray($val) :
                
$val;
        }

        return 
$arr;
    }

    private function 
__construct($file$type Configuration::AUTO) {
        if (
$type == self::AUTO) {
            
$type self::$CONF_EXT_RELATION[pathinfo($filePATHINFO_EXTENSION)];
        }

        switch(
$type) {
            case 
self::JSON:
                
$this->data json_decode(file_get_contents($file), true);
                break;

            case 
self::PHP_INI:
                
$this->data parse_ini_file($filetrue);
                break;

            case 
self::XML:
                
$this->data self::objectToArray(simplexml_load_file($file));
                break;
        }
    }

    static public function & 
getInstance($file$type Configuration::AUTO) {
        if(! isset(
self::$instances[$file])) {
            
self::$instances[$file] = new Configuration($file$type);
        }

        return 
self::$instances[$file];
    }

    public function 
__get($section) {
        if ((
is_array($this->data)) &&
                (
array_key_exists($section$this->data))) {
            return 
$this->data[$section];
        }
    }

    public function 
getAvailableSections() {
        return 
array_keys($this->data);
    }
}

$configuration Configuration::getInstance(/*configuration filename*/);
foreach(
$configuration->getAvailableSections() as $pos => $sectionName) {
    
var_dump($sectionName);
    
var_dump($configuration->{$sectionName});
}
?>

freamer89 at gmail dot com (2009-11-03 08:38:37)

Didn`t find the one,which suits my needs,so Here`s a small and easy write ini from array function... Maybe you`ll find it handy.
<?php
function write_php_ini($array$file)
{
    
$res = array();
    foreach(
$array as $key => $val)
    {
        if(
is_array($val))
        {
            
$res[] = "[$key]";
            foreach(
$val as $skey => $sval$res[] = "$skey = ".(is_numeric($sval) ? $sval '"'.$sval.'"');
        }
        else 
$res[] = "$key = ".(is_numeric($val) ? $val '"'.$val.'"');
    }
    
safefilerewrite($fileimplode("\r\n"$res));
}
//////
function safefilerewrite($fileName$dataToSave)
{    if (
$fp fopen($fileName'w'))
    {
        
$startTime microtime();
        do
        {            
$canWrite flock($fpLOCK_EX);
           
// If lock not obtained sleep for 0 - 100 milliseconds, to avoid collision and CPU load
           
if(!$canWriteusleep(round(rand(0100)*1000));
        } while ((!
$canWrite)and((microtime()-$startTime) < 1000));

        
//file was locked so now we can store information
        
if ($canWrite)
        {            
fwrite($fp$dataToSave);
            
flock($fpLOCK_UN);
        }
        
fclose($fp);
    }

}
?>

prometheus (2009-09-30 09:32:03)

I made a small test to check differencies between parse_ini_file and json_decode and I surprised a little bit.

Here are my test files...
parseini-test.ini:
[global]
a = 1
b = 2
c = "Lorem Ipsum"
d = "Dolor Sit Amet"
e = 3.14

jsondecode-test.json:
{
    "a": 1,
    "b": 2,
    "c": "Lorem Ipsum",
    "d": "Dolor Sit Amet",
    "e": 3.14
}

And source codes are...
parseini.php:
<?php

$s 
microtime(TRUE);
for (
$i=0$i<100000$i++)
{
$a parse_ini_file('./parseini-test.ini');
unset(
$a);
}
$e microtime(TRUE);
echo 
$e-$s;

?>

jsondecode.php:
<?php

$s 
microtime(TRUE);
for (
$i=0$i<100000$i++)
{
$a json_decode(file_get_contents('./jsondecode-test.json'), TRUE);
unset(
$a);
}
$e microtime(TRUE);
echo 
$e-$s;

?>

These tests ran for three times (the third result is near to average in my experiences):
- parseini.php: 3.24759721756
- jsondecode.php: 3.289290905

My conclusion:
I`m going to use the json_decode() for reading config files because no significant difference in running time between parse_ini_file() and json_decode() + file_get_contents() but JSON is a more powerful format for storing well typed (parse_ini_file parses 3.14 as string, json_decode as float) and well structured configuration settings. As a note: json_decode is sensitive for associative keys` quotation, use quotes at all time in keys` names.

Test ran on PHP 5.2.

flacroix897 at hotmail dot com (2009-08-25 10:23:46)

Make sure you use double-quotes when using spaces in a value as of 5.3.
Consider the following INI file:
key = tested on php5
with the following code:
$res = parse_ini_file('myini.ini');
var_dump($res);
In 5.2, this will give you:
array(1) {
["key"]=>
string(14) "tested on php5"
}
In 5.3, this will give you:
Warning: syntax error, unexpected BOOL_TRUE in Unknown on line 1 in test.php on line 3
bool(false)
This is because the 'on' word is a reserved keyword for boolean TRUE. The documentation now states that a string that contains any non-alphanumeric character should be enclosed in double-quotes (a space is not alphanumeric).

rmcleod79 [at] talktalk ~dot~ net (2009-07-08 01:40:43)

Here's a simple settings class that parses an ini file for settings. It has a private constructor so that it can only be instantiated through the getInstance method, this means that there can only ever be one settings object at a time.

<?php

class Settings {
    private static 
$instance;
    private 
$settings;
    
    private function 
__construct($ini_file) {
        
$this->settings parse_ini_file($ini_filetrue);
    }
    
    public static function 
getInstance($ini_file) {
        if(! isset(
self::$instance)) {
            
self::$instance = new Settings($ini_file);            
        }
        return 
self::$instance;
    }
    
    public function 
__get($setting) {
        if(
array_key_exists($setting$this->settings)) {
            return 
$this->settings[$setting];
        } else {
            foreach(
$this->settings as $section) {
                if(
array_key_exists($setting$section)) {
                    return 
$section[$setting];
                }
            }
        }
    }
}

?>

settings.ini

[General]

url = "http://www.example.com"

[Database]

host = localhost
username = user
password = password
db = cms
adapter = mysqli

Using the class

<?php

$settings 
Settings::getInstance(/*path to settings.ini*/);

echo 
$settings->url;

print_r($settings->Database);

echo 
$settings->db;

?>

Output would be:

http://www.example.com

Array
(
    [host] => localhost
    [username] => user
    [password] => password
    [db] => cms
    [adapter] => mysqli
)

cms

joe at u13 dot net (2009-06-20 00:46:43)

I'm not sure why, but for some reason php's ini functions always leave out entries for me. 

To solve this problem, I wrote my own ini parsing function, intended to be a replacement for parse_ini_file('file.ini', true);

<?php

function new_parse_ini($f)
{

    
// if cannot open file, return false
    
if (!is_file($f))
        return 
false;

    
$ini file($f);

    
// to hold the categories, and within them the entries
    
$cats = array();

    foreach (
$ini as $i) {
        if (@
preg_match('/\[(.+)\]/'$i$matches)) {
            
$last $matches[1];
        } elseif (@
preg_match('/(.+)=(.+)/'$i$matches)) {
            
$cats[$last][$matches[1]] = $matches[2];
        }
    }

    return 
$cats;

}

?>

The usage follows the Example #2 on http://us3.php.net/manual/en/function.parse-ini-file.php , except without the second parameter being 'true'.

jeremygiberson at gmail dot com (2009-04-30 16:01:16)

Here is a quick parse_ini_file wrapper to add extend support to save typing and redundancy.
<?php
    
/**
     * Parses INI file adding extends functionality via ":base" postfix on namespace.
     *
     * @param string $filename
     * @return array
     */
    
function parse_ini_file_extended($filename) {
        
$p_ini parse_ini_file($filenametrue);
        
$config = array();
        foreach(
$p_ini as $namespace => $properties){
            list(
$name$extends) = explode(':'$namespace);
            
$name trim($name);
            
$extends trim($extends);
            
// create namespace if necessary
            
if(!isset($config[$name])) $config[$name] = array();
            
// inherit base namespace
            
if(isset($p_ini[$extends])){
                foreach(
$p_ini[$extends] as $prop => $val)
                    
$config[$name][$prop] = $val;
            }
            
// overwrite / set current namespace values
            
foreach($properties as $prop => $val)
            
$config[$name][$prop] = $val;
        }
        return 
$config;
    }
?>

Treats this ini:
<?php 
/*
[base]
host=localhost
user=testuser
pass=testpass
database=default

[users:base]
database=users

[archive : base]
database=archive
*/
?>
As if it were like this:
<?php
/*
[base]
host=localhost
user=testuser
pass=testpass
database=default

[users:base]
host=localhost
user=testuser
pass=testpass
database=users

[archive : base]
host=localhost
user=testuser
pass=testpass
database=archive
*/
?>

prikkeldraad at gmail dot com (2009-03-26 06:15:44)

When PHP dies without any warning or message when parsing the ini-file, check the values of the file. All non alphanumeric values need to be quoted.

pBakhuis at googles mail dot com (gmail) (2008-12-12 08:42:59)

To those who were like me looking if this could be used to create an array out of commandline output I offer you the function below (I used it to parse mplayer output).

If you want it behave exactly the same as parse_ini_file you'll obviously have to add some code to feed the different sections to this one. Hope it's of help to someone!

<?php
/**
 * The return is very similar to that of parse_ini_file, but this works off files
 * 
 * Below is an example of what it does, where the first
 * value is what you'd normally want to do, and the second and third things that might
 * happen and in case it does it's good to know what is going on.
 * 
 * $anArray = array( 'default=theValue', 'setting=', 'something=value=value' );
 * explodeExplode( '=', $anArray );
 * 
 * the return will be 
 * array( 'default' => 'theValue', 'setting' => '', 'something' => 'value=value' );
 * 
 * So the oddities here are, text after the second $string occurence dissapearing
 * and empty values resulting in an empty string.
 * 
 * @return $returnArray array array( 'setting' => 'value' )
 * @param $string Object
 * @param $array Object
 */
function explodeExplode$string$array )
{
    
$returnArray = array();
    
    foreach( 
$array as $arrayValue )
    {
        
$tmpArray explode$string$arrayValue );
        
        if( 
count$tmpArray ) == )
        {
            
$returnArray[$tmpArray[0]] = '';
        }
        else if( 
count$tmpArray ) == )
        {
            
$returnArray[$tmpArray[0]] = $tmpArray[1];
        }
        else if( 
count$tmpArray ) > )
        {
            
$implodeBack = array();
            
$firstLoop      true;
            foreach( 
$tmpArray as $tmpValue )
            {
                if( 
$firstLoop )
                {
                    
$firstLoop false;
                }
                else
                {
                    
$implodeBack[] = $tmpValue;
                }
            }
            
print_r$implodeBack );
            
$returnArray[$tmpArray[0]] = implode'='$implodeBack );
        }
    }
    
    return 
$returnArray;
}
?>

Bill Brown - macnimble.com (2008-10-16 19:47:41)

Working on a project for a client recently, I needed a way to set a default configuration INI file, but also wanted to allow the client to override the settings through the use of a custom INI file.

I thought array_merge or array_merge_recursive would do the trick for me, but it fails to override settings in the way that I wanted. I wrote my own function to do what I wanted. It's nothing spectacular, but thought I'd post it here in case it saved someone else some time.

<?php
function ini_merge ($config_ini$custom_ini) {
  foreach (
$custom_ini AS $k => $v):
    if (
is_array($v)):
      
$config_ini[$k] = ini_merge($config_ini[$k], $custom_ini[$k]);
    else:
      
$config_ini[$k] = $v;
    endif;
  endforeach;
  return 
$config_ini;
};
$CONFIG_INI parse_ini_file('../config.ini'TRUE);
$CUSTOM_INI parse_ini_file('ini/custom.ini'TRUE);
$INI ini_merge($CONFIG_INI$CUSTOM_INI);
?>

This allowed me to put the default INI file above the web root with information that requires extra security (database connection info, etc.) and a writable INI file within the structure of the site without affecting the default settings of the default config.ini file.

Anyway, hope it helps.

david dot dyess at gmail dot com (2008-08-04 00:12:13)

Here is another way to group values in the ini:

my.ini:

[singles]
test = a test
test2 = another test
test3 = this is a test too

[multiples]
tests[] = a test
tests[] = another test
tests[] = this is a test too

my.php:

<?php $init parse_ini_file('my.ini'); ?>

The same as:

<?php
$init
['test'] = 'a test';
$init['test2'] = 'another test';
$init['test3'] = 'this is a test too';
$init['tests'][0] = 'a test';
$init['tests'][1] = 'another test';
$init['tests'][2] = 'this is a test too';
?>

This works with the bool set to true also, can be useful with loops. Works with the bool set to true as well.

juampii_4 at hotmail dot com (2008-07-09 20:24:13)

class.parseini.php
<?php
##By juan pablo tosso
class Parser
{

    public function 
printini($file$sector$var)
    {
        
$file=$file.".ini";
        
$is=array();
        
$isparse_ini_file($filetrue);
        
trim($is);
        if(
is_array($is) && file_exists($file))
        {
            return 
$is[$sector][$var];
        }else{
            return 
"error";
        }
        
    }
    
    
}

?>

Ini.ini:
[test]
foo=bar

[test2]
foo1=bar1
foo2=bar2
foo bar=something else

just in another file write:

include("class.parseini.php");
$new= new Parser();
echo $new->printini("ini", "test2", "foo1");

goulven.ch AT gmail DOT com (2007-10-29 06:33:50)

Warning: parse_ini_files cannot cope with values containing the equal sign (=).

The following function supports sections, comments, arrays, and key-value pairs outside of any section.
Beware that similar keys will overwrite one another (unless in different sections).

<?php
function parse_ini $filepath ) {
    
$ini file$filepath );
    if ( 
count$ini ) == ) { return array(); }
    
$sections = array();
    
$values = array();
    
$globals = array();
    
$i 0;
    foreach( 
$ini as $line ){
        
$line trim$line );
        
// Comments
        
if ( $line == '' || $line{0} == ';' ) { continue; }
        
// Sections
        
if ( $line{0} == '[' ) {
            
$sections[] = substr$line1, -);
            
$i++;
            continue;
        }
        
// Key-value pair
        
list( $key$value ) = explode'='$line);
        
$key trim$key );
        
$value trim$value );
        if ( 
$i == ) {
            
// Array values
            
if ( substr$line, -1) == '[]' ) {
                
$globals$key ][] = $value;
            } else {
                
$globals$key ] = $value;
            }
        } else {
            
// Array values
            
if ( substr$line, -1) == '[]' ) {
                
$values$i ][ $key ][] = $value;
            } else {
                
$values$i ][ $key ] = $value;
            }
        }
    }
    for( 
$j=0$j<$i$j++ ) {
        
$result$sections$j ] ] = $values$j ];
    }
    return 
$result $globals;
}
?>

Example usage:
<?php
$stores 
parse_ini('stores.ini');
print_r$stores );
?>

An example ini file:
<?php
/*
;Commented line start with ';'
global_value1 = a string value
global_value1 = another string value

; empty lines are discarded
[Section1]
key = value
; whitespace around keys and values is discarded too
otherkey=other value
otherkey=yet another value
; this key-value pair will overwrite the former.
*/
?>

www.onphp5.com (2007-10-24 13:26:49)

Looks like in PHP 5.3.0 special characters like \n are extrapolated into real newlines. Gotta use \\n.

arnapou (2007-10-03 06:51:17)

I didn't find a simple ini class so I wrote that class to read and write ini files.
I hope it could help you.

Read file : $ini = INI::read('myfile.ini');
Write file : INI::write('myfile.ini', $ini);

Features : 
- support [] syntax for arrays
- support . in keys like bar.foo.something = value
- true and false string are automatically converted in booleans
- integers strings are automatically converted in integers
- keys are sorted when writing
- constants are replaced but they should be written in the ini file between braces : {MYCONSTANT}

<?php

class INI {
    
/**
     *  WRITE
     */
    
static function write($filename$ini) {
        
$string '';
        foreach(
array_keys($ini) as $key) {
            
$string .= '['.$key."]\n";
            
$string .= INI::write_get_string($ini[$key], '')."\n";
        }
        
file_put_contents($filename$string);
    }
    
/**
     *  write get string
     */
    
static function write_get_string(& $ini$prefix) {
        
$string '';
        
ksort($ini);
        foreach(
$ini as $key => $val) {
            if (
is_array($val)) {
                
$string .= INI::write_get_string($ini[$key], $prefix.$key.'.');
            } else {
                
$string .= $prefix.$key.' = '.str_replace("\n""\\\n"INI::set_value($val))."\n";
            }
        }
        return 
$string;
    }
    
/**
     *  manage keys
     */
    
static function set_value($val) {
        if (
$val === true) { return 'true'; }
        else if (
$val === false) { return 'false'; }
        return 
$val;
    }
    
/**
     *  READ
     */
    
static function read($filename) {
        
$ini = array();
        
$lines file($filename);
        
$section 'default';
        
$multi '';
        foreach(
$lines as $line) {
            if (
substr($line01) !== ';') {
                
$line str_replace("\r"""str_replace("\n"""$line));
                if (
preg_match('/^\[(.*)\]/'$line$m)) {
                    
$section $m[1];
                } else if (
$multi === '' && preg_match('/^([a-z0-9_.\[\]-]+)\s*=\s*(.*)$/i'$line$m)) {
                    
$key $m[1];
                    
$val $m[2];
                    if (
substr($val, -1) !== "\\") {
                        
$val trim($val);
                        
INI::manage_keys($ini[$section], $key$val);
                        
$multi '';
                    } else {
                        
$multi substr($val0, -1)."\n";
                    }
                } else if (
$multi !== '') {
                    if (
substr($line, -1) === "\\") {
                        
$multi .= substr($line0, -1)."\n";
                    } else {
                        
INI::manage_keys($ini[$section], $key$multi.$line);
                        
$multi '';
                    }
                }
            }
        }
        
        
$buf get_defined_constants(true);
        
$consts = array();
        foreach(
$buf['user'] as $key => $val) {
            
$consts['{'.$key.'}'] = $val;
        }
        
array_walk_recursive($ini, array('INI''replace_consts'), $consts);
        return 
$ini;
    }
    
/**
     *  manage keys
     */
    
static function get_value($val) {
        if (
preg_match('/^-?[0-9]$/i'$val)) { return intval($val); } 
        else if (
strtolower($val) === 'true') { return true; }
        else if (
strtolower($val) === 'false') { return false; }
        else if (
preg_match('/^"(.*)"$/i'$val$m)) { return $m[1]; }
        else if (
preg_match('/^\'(.*)\'$/i'$val$m)) { return $m[1]; }
        return 
$val;
    }
    
/**
     *  manage keys
     */
    
static function get_key($val) {
        if (
preg_match('/^[0-9]$/i'$val)) { return intval($val); }
        return 
$val;
    }
    
/**
     *  manage keys
     */
    
static function manage_keys(& $ini$key$val) {
        if (
preg_match('/^([a-z0-9_-]+)\.(.*)$/i'$key$m)) {
            
INI::manage_keys($ini[$m[1]], $m[2], $val);
        } else if (
preg_match('/^([a-z0-9_-]+)\[(.*)\]$/i'$key$m)) {
            if (
$m[2] !== '') {
                
$ini[$m[1]][INI::get_key($m[2])] = INI::get_value($val);
            } else {
                
$ini[$m[1]][] = INI::get_value($val);
            }
        } else {
            
$ini[INI::get_key($key)] = INI::get_value($val);
        }
    }
    
/**
     *  replace utility
     */
    
static function replace_consts(& $item$key$consts) {
        if (
is_string($item)) {
            
$item strtr($item$consts);
        }
    }
}

?>

thuylnt (2007-09-26 02:09:55)

I need to read a ini file, modify some values in some sections, and save it. But the important thing is, i want to keep all the comments, the new lines in the right order. So i modified function parse_ini_file_quotes_safe and write_ini_file.
I think they work fine.

<?php
    
function read_ini_file($f, &$r)
    {
        
$null "";
        
$r=$null;
        
$first_char "";
        
$sec=$null;
        
$comment_chars=";#";
        
$num_comments "0";
        
$num_newline "0";

        
//Read to end of file with the newlines still attached into $f
        
$f = @file($f);
        if (
$f === false) {
            return -
2;
        }
        
// Process all lines from 0 to count($f)
        
for ($i=0$i<@count($f); $i++)
        {
            
$w=@trim($f[$i]);
            
$first_char = @substr($w,0,1);
            if (
$w)
            {
                if ((@
substr($w,0,1)=="[") and (@substr($w,-1,1))=="]") {
                    
$sec=@substr($w,1,@strlen($w)-2);
                    
$num_comments 0;
                    
$num_newline 0;
                }
                else if ((
stristr($comment_chars$first_char) == true)) {
                    
$r[$sec]["Comment_".$num_comments]=$w;
                    
$num_comments $num_comments +1;
                }                
                else {
                    
// Look for the = char to allow us to split the section into key and value
                    
$w=@explode("=",$w);
                    
$k=@trim($w[0]);
                    unset(
$w[0]);
                    
$v=@trim(@implode("=",$w));
                    
// look for the new lines
                    
if ((@substr($v,0,1)=="\"") and (@substr($v,-1,1)=="\"")) {
                        
$v=@substr($v,1,@strlen($v)-2);
                    }
                    
                    
$r[$sec][$k]=$v;
                    
                }
            }
            else {
                
$r[$sec]["Newline_".$num_newline]=$w;
                
$num_newline $num_newline +1;
            }
        }
        return 
1;
    }

    function 
write_ini_file($path$assoc_arr) {
        
$content "";

        foreach (
$assoc_arr as $key=>$elem) {
            if (
is_array($elem)) {
                if (
$key != '') {
                    
$content .= "[".$key."]\r\n";                    
                }
                
                foreach (
$elem as $key2=>$elem2) {
                    if (
$this->beginsWith($key2,'Comment_') == && $this->beginsWith($elem2,';')) {
                        
$content .= $elem2."\r\n";
                    }
                    else if (
$this->beginsWith($key2,'Newline_') == && ($elem2 == '')) {
                        
$content .= $elem2."\r\n";
                    }
                    else {
                        
$content .= $key2." = ".$elem2."\r\n";
                    }
                }
            }
            else {
                
$content .= $key." = ".$elem."\r\n";
            }
        }

        if (!
$handle fopen($path'w')) {
            return -
2;
        }
        if (!
fwrite($handle$content)) {
            return -
2;
        }
        
fclose($handle);
        return 
1;
    }

    function 
beginsWith$str$sub ) {
        return ( 
substr$str0strlen$sub ) ) === $sub );
    }
?>

yarco dot w at gmail dot com (2007-06-29 01:46:46)

parse_ini_file can't deal with const which cancate a string. For example, if test.ini file is

classPath = ROOT/lib

If you:
<?php
define
('ROOT'dirname(__FILE__));

$buf parse_ini_file('test.ini');
?>

const ROOT would't be parsed.

But my version could work find.

<?php
// array parse_ini_file ( string $filename [, bool $process_sections] )
function parse_ini($filename$process_sections false)
{
  function 
replace_process(& $item$key$consts)
  {
    
$item str_replace(array_keys($consts), array_values($consts), $item);
  }

  
$buf get_defined_constants(true); // PHP version > 5.0
  
$consts $buf['user'];
  
$ini parse_ini_file($filename$process_sections);

  
array_walk_recursive($ini'replace_process'$consts);
  return 
$ini;
}

define('ROOT''/test');
print_r(parse_ini(dirname(__FILE__).'/test.ini'));

?>

Adam (2007-06-25 10:45:15)

Arrays can be defined in the ini file by adding '[]' at the end of a key name. For example:
value1 = 17
value2 = 13
value3[] = a
value3[] = b
value3[] = c
Will return:
Array
(
[value1] => 17
[value2] => 13
[value3] => Array
(
[0] => a
[1] => b
[2] => c
)
)

Mildred (2007-05-25 00:42:35)

I wrote few functions to work with ini files.

The function make_ini_file($array, &$errors)
The function read_ini($file)
The function prepare_ini($array, $maxdepth=NULL)

The function prepare_ini($array, $maxdepth=NULL)
This function will take an array as returned by the function read_ini() and will return an array as needed by the function make_ini_file() so that you can write extanded ini files easily.
If maxdepth is not given (or if maxdepth is NULL), this function will try to create sections so the keys in the sections do not have dots. if maxdepth is given, it will create sections with $maxdepth members in them (or less if it is not possible). It won't use the special key name "."

<?php

function prepare_ini($arr$maxdepth=NULL){
    
$res = array();
    
prepare_ini__1($res$arr$maxdepth);
    return 
$res;
}

function 
prepare_ini__1(
    &
$res$arr$maxdepth,
    
$prefix1=""$prefix2=""$depth=0,
    
$self='prepare_ini__1')
{
    foreach(
$arr as $key=>$val){
        if(
is_array($val)){
            if(
is_null($maxdepth) or $depth $maxdepth){
                
$newprefix $prefix1 "$prefix1.$key$key;
                
$self($res$val$maxdepth$newprefix$prefix2$depth+1);
            }else{
                
$newprefix $prefix2 "$prefix1.$key$key;
                
$self($res$val$maxdepth$prefix1$newprefix$depth+1);
            }
        }else{
            
$newprefix $prefix2 "$prefix2.$key$key;
            if(!isset(
$res[$prefix1])) $res[$prefix1] = array();
            
$res[$prefix1][$newprefix] = $val;
        }
    }
}

// kate: indent-width 4; tab-width 8; space-indent on;
// kate: replace-tabs off; remove-trailing-space on;
?>

mark at hostcobalt dot com (2007-03-27 12:39:01)

or to prevent the file being viewed you can just use a .htaccess file and add this line
<files *.ini>
order deny,allow
deny from all
</files>
i use a similar thing to prevent my config files being accessed

ant at loadtrax dot com (2006-11-15 09:09:10)

A number of posts mention using pear::Config as a replacement for this function. Note however that internally it uses parse_ini_file to read the ini file, so it suffers from the same limitations.

Justin Hall (2006-10-31 11:46:55)

This is a simple (but slightly hackish) way of avoiding the character limitations (in values):

<?php
define
('QUOTE''"');
$test parse_ini_file('test.ini');

echo 
"<pre>";
print_r($test);
?>

contents of test.ini:

park yesterday = "I (walked) | {to} " QUOTE"the"QUOTE " park yesterday & saw ~three~ dogs!"

output:

<?php
Array
(
    [
park yesterday] => (walked) | {to"the" park yesterday saw ~threedogs!
)
?>

(2006-10-23 02:16:55)

this function won't parse a remote INI file, even with allow_url_fopen turned on.

judas dot iscariote at gmail dot com (2006-10-01 00:26:58)

If you are looking for an OOP way to parse ini files, take a look at Marcus Boerger's IniGroups class available here :
http://www.php.net/~helly/php/ext/spl/classIniGroups.html

tertillian at yahoo dot com (2006-02-21 17:12:12)

I ran into a snag where I wanted to have an INI file for a library. All attempts to parse the file from the library, apart from hardcoded path qualification, failed because it couldn't find the INI file. Some of the php functions will optionally use the include path. Adding this to the parse_ini_file() function would permit its use in this way and would encourage not putting INI files in document root.

nbraczek at bsds dot de (2006-02-15 16:29:41)

Beside the mentioned reserved words 'null', 'yes', 'no', 'true', and 'false', also 'none' seems to be a reserved word. Parsing an ini file stops at a key named 'none'.

mauder[remove] at [remove]gmail[remove] dot com (2006-02-14 04:31:26)

Be careful if you put any .ini file in your readable directories, if somebody would know the name (e.g. if your application is widely used), the webserver might return it as plain text.

For example : your database username and password could be exposed, if it is stored in that file !

To prevent this from happening :
- give the file .php extension :  "my.ini.php"
- put ';<?php' (without quotes and without X between X and php) on first line 
- put ';?>' on last line

The server would run the ini file as being PHP-code, but will do nothing due to bad syntax, preventing the content from being exosed.
On the other hand, it is still a valid .ini file...

HTH !

(2005-09-22 13:53:26)

I wrote a replacement function with following changes:
-It allows quotes and double quotes.
-It detects wether your .ini file has sections or not.
-It will read until eof in any case, even if a line contains errors.

I know it can be improved a lot, so feel free to work on it and, please, notify me if you do.

<?php
function parse_ini_file_quotes_safe($f)
{
 
$r=$null;
 
$sec=$null;
 
$f=@file($f);
 for (
$i=0;$i<@count($f);$i++)
 {
  
$newsec=0;
  
$w=@trim($f[$i]);
  if (
$w)
  {
   if ((!
$r) or ($sec))
   {
    if ((@
substr($w,0,1)=="[") and (@substr($w,-1,1))=="]") {$sec=@substr($w,1,@strlen($w)-2);$newsec=1;}
   }
   if (!
$newsec)
   {
    
$w=@explode("=",$w);$k=@trim($w[0]);unset($w[0]); $v=@trim(@implode("=",$w));
    if ((@
substr($v,0,1)=="\"") and (@substr($v,-1,1)=="\"")) {$v=@substr($v,1,@strlen($v)-2);}
    if (
$sec) {$r[$sec][$k]=$v;} else {$r[$k]=$v;}
   }
  }
 }
 return 
$r;
}
?>

dimk at pisem dot net (2005-07-13 21:33:30)

Class to access ini values at format "section_name.property", for example $myconf->get("system.name") returns a property "name" in section "system":

<?php
class Settings {

var 
$properties = array();

    function 
Settings() {
        
$this->properties parse_ini_file(_SETTINGS_FILEtrue);
    }

    function 
get($name) {
        if(
strpos($name".")) {
            list(
$section_name$property) = explode("."$name);
            
$section =& $this->properties[$section_name];
            
$name $property;
        } else {
            
$section =& $properties;
        }

        if(
is_array($section) && isset($section[$name])) {
            return 
$section[$name];
        }
        return 
false;
    }

}
?>

dreamscape (2005-06-24 09:10:13)

I handy function to allow values with new lines if you are PHP4, is the following:

<?php
function prepareIniNl($string) {
    return 
preg_replace("/(\r\n|\n|\r)/""\\n"$string);
}
?>

Now, when writing your INI file, parse the value through the function and it will turn for example:

Value line 1
Value line 2

Into literally:

Value line 1\nValue line 2

Which is stored as a single line in the INI file.  And when you read the INI file back into PHP, the \n will be parsed and you're value will be back to:

Value line 1
Value line 2

dawalama at gmail dot com (2005-05-20 08:09:10)

<?php
/*
* Search_ini_file refined. 
*/
function search_ini_file $filename$search_param$return_section false )
{
        
$search_key =   (isset($search_param['key'])?$search_param['key']:false);
        
$search_value = (isset($search_param['value'])?$search_param['value']:false);
        if ( !(
$search_key !==false || $search_value !==false) ){
                return 
false;
        }
        
$retvalue false;
        
$handle fopen($filename'r');
        if ( (
$search_key !== false) && ($search_value !== false) ){
                
$key_found false;
                
$retvalue['key'] = false;
                
$retvalue['value'] = false;
                while( !
feof($handle) ) {
                        
$line trim(fgets($handle4096));
                        if (
preg_match("/^\[$search_key\].*?$/s",$line)){
                                
$key_found true;
                                
$retvalue['key'] = true;
                                continue;
                        }
                        if (
$key_found){
                                if (
preg_match("/^\[.*?$/"trim($line))){
                                        break;
                                }else{
                                        if (
$return_section){
                                                if (
$line != '') {
                                                        list(
$k$v) = split("="$line);
                                                        
$retvalue[$search_key][$k] = preg_replace("/;.*$/"""$v);
                                                }   }   }

                                if (
preg_match("/^$search_value\s*?=.*$/"$line)){
                                        
$retvalue['value'] = true;
                                        break;
                                }   }  }
        }elseif (
$search_key !== false){
                
$keyfound false;
                while ( !
feof($handle) ){
                        
$line trim(fgets($handle4096));
                        if (
preg_match("/^\[$search_key\].*?$/s",$line)){
                                
$retvalue  true;
                                if (!
$return_section){
                                        break;
                                }else{
                                        
$retvalue = Array();
                                        
$keyfound true;
                                        continue;
                                }  }

                        if ( 
$keyfound ){
                                if (
preg_match("/^\[.*?$/"trim($line))){
                                        break;
                                }else{
                                        if (
$return_section){
                                                if (
$line != ''){
                                                        list(
$k$v) = split("="$line);
                                                        
$retvalue[$search_key][$k] = preg_replace("/;.*$/"""$v);
                                                }   }  }  }  }
        }elseif (
$search_value !== false){
                while ( !
feof($handle) ){
                        
$line trim(fgets($handle4096));

                        if (
preg_match("/^$search_value\s*?=.*$/"$line)){
                                
$retvalue true;
                                if (
$return_section){
                                        
$retvalue = array();
                                        if (
$line != ''){
                                                list(
$k$v) = split("="$line);
                                                
$retvalue[$k] = preg_replace("/;.*$/"""$v);
                                        }  }
                                break;
                        }   }  }
        
fclose($handle);
        return 
$retvalue;
}
?>

sly at noiretblanc dot org (2005-03-08 08:57:50)

Be careful with the string "none", for example if you want to save a CSS border-style in your config.ini file :
[style]
borderstyle=none
will return:
'style' => array ( 'borderstyle' => '' )
and not
'style' => array ( 'borderstyle' => 'none' )
The solution is to quote the string none :
[style]
borderstyle="none"

hfuecks at phppatterns dot com (2004-07-15 08:20:09)

parse_ini_file seems to have changed it's signature between PHP 4.3.x and PHP 5.0.0 (can't find any relevant changelog / cvs entries referring to this).
In PHP 4.3.x and below return value was a boolean FALSE if the ini file could not be found. With PHP 5.0.0 the return value is an empty array if the file is not found.

php at isaacschlueter dot com (2004-06-21 23:47:55)

Even better than putting the <?php at the head of the file is to do something like this:

--
config.ini.php--
; <?
php die( 'Please do not access this page directly.' ); ?>
; This is the settings page, do not modify the above line.
setting = value
...

waikeatNOSPAM at archerlogic dot com (2003-11-09 06:37:44)

I found that this function will not work on remote files.
I tried
$someArray = parse_ini_file("http://www.example.com/setting.ini");
and it reports
Cannot Open 'http://www.example.com/setting.ini' for reading ...

rus dot grafx at usa dot net (2003-10-10 18:15:13)

Instead of using parse_ini_file() function I would recommend to use PEAR's Config package which is MUCH more flexible (assuming that you don't mind using PEAR and OOP). Have a closer look at http://pear.php.net/package/Config

dshearin at excite dot com (2003-06-19 20:47:33)

I found another pitfall to watch out for. The key (to the left of the equal sign) can't be the same as one of the predefined values, like yes, no, on, off, etc. I was working on a script that read in an ini file that matched the country codes of top level domains to the full name of the country. I kept getting a parse error everytime it got to the entry for Norway ("no"). I fixed the problem by sticking a dot in front of each of the country codes.

(2003-05-10 04:05:13)

If your configuration file holds any sensitive information (such as database login details), remember NOT to place it within your document root folder! A common mistake is to replace config.inc.php files, which are formatted in PHP:
<?php
$database
['host'] = 'localhost';
// etc...
?>

With config.ini files which are written in plain text:
[database]
host = localhost

The file config.ini can be read by anyone who knows where it's located, if it's under your document root folder. Remember to place it above!

kieran dot huggins at rogers dot com (2003-01-07 10:24:15)

Just a quick note for all those running into trouble escaping double quotes:
I got around this by "base64_encode()"-ing my content on the way in to the ini file, and "base64_decode()"-ing on the way out.
Because base64 uses the "=" sign, you will have to encapsulate the entire value in double quotes so the line looks like this:
varname = "TmlhZ2FyYSBGYWxscywgT04="
When base64'd, your strings will retain all \n, \t...etc... URL's retain everything perfectly :-)
I hope some of you find this useful!
Cheers, Kieran

fbeyer at clickhand dot de (2002-11-29 09:37:23)

Besides the features mentioned above (eg. core constants, booleans), you can also access user-defined constants in ini files! This is handy if you want to create a bit-field, for example:

<?php
// Define pizza toppings
define('PIZZA_HAM',           1);
define('PIZZA_PINEAPPLE',     2);
define('PIZZA_ONION',         4);
define('PIZZA_MOZARELLA',     8);
define('PIZZA_GARLIC',        16);

// Read predefined pizzas
$pizzas parse_ini_file('pizzas.ini');

if (
$pizzas[$user_pizza] & PIZZA_ONION) {
    
// Add onions to the pizza
}
?>

[pizzas]

; Define pizzas
hawaii = PIZZA_HAM | PIZZA_PINEAPPLE
stinky = PIZZA_ONION | PIZZA_GARLIC

bob at kludgebox dot com (2002-03-26 10:27:31)

And for the extra-paranoid like myself, add a rule into your httpd.conf file so that *.ini (or *.inc) in my case can't be sent to a browser:
<Files *.inc>
Order deny,allow
Deny from all
</Files>

JoshuaStarr at aelana dot com (2002-01-14 19:41:14)

It should be noted that in all of our attempts you cannot escape a double quote in the value when read with the parse_ini_file() function.
;============================
; Example Configuration File
;============================
[category]
title = "Best Scripting Language"
desc = "See <a href=\"http://www.php.net/\">PHP</a>!"
If this file is read by parse_ini_file() the link value will not be set because of the escaped double quotes.

易百教程