parse_ini_file

(PHP 4, PHP 5, PHP 7, PHP 8)

parse_ini_fileParst eine Konfigurationsdatei

Beschreibung

parse_ini_file(string $filename, bool $process_sections = false, int $scanner_mode = INI_SCANNER_NORMAL): array|false

parse_ini_file() lädt die in filename angegebene Datei, und gibt die darin enthaltenen Einstellungen in einem assoziativen Array zurück.

Die Struktur der Ini-Datei ist identisch zur php.ini.

Parameter-Liste

filename

Der Dateiname der zu parsenden ini-Datei. Wenn ein relativer Pfad verwendet wird, wird er relativ zum aktuellen Arbeitsverzeichnis ausgewertet und dann entsprechend dem include_path.

process_sections

Setzt man den Parameter process_sections auf true, erhält man ein mehrdimensionales Array mit den Gruppennamen und Einstellungen. Der Standardwert für process_sections ist false

scanner_mode

Kann entweder INI_SCANNER_NORMAL (Standard) oder INI_SCANNER_RAW sein. Ist INI_SCANNER_RAW gesetzt, so werden die Werte der Optionen nicht geparst.

Seit PHP 5.6.1 kann auch INI_SCANNER_TYPED angegeben werden. In diesem Modus werden soweit möglich die Typen von Boolean-, Null- oder Integer-Werten beibehalten. Die Zeichenketten "true", "on" und "yes" werden zu true konvertiert. "false", "off", "no" und "none" werden als false angesehen. "null" wird in diesem Modus zu null. Soweit möglich werden alle numerischen Zeichenketten zu Integertypen umgewandelt.

Rückgabewerte

Im Erfolgsfall werden die Einstellungen als assoziatives Array zurückgegeben, ansonsten false.

Beispiele

Beispiel #1 Inhalt der sample.ini

; Dies ist ein Beispiel für eine Konfigurationsdatei
; Kommentare beginnen wie in der php.ini mit ';'

[erste_gruppe]
eins = 1
fünf = 5
tier = VOGEL

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

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

urls[svn] = "http://svn.php.net"
urls[git] = "http://git.php.net"

Beispiel #2 parse_ini_file()-Beispiel

Abgesehen von "magischen Konstanten" wie __FILE__ können auch Konstanten in einer Ini-Datei geparst werden, indem man einen INI-Wert als Konstante definiert, bevor parse_ini_file() aufgerufen wird. Diese Konstante wird in die Ergebnisse integriert. Dabei werden nur INI-Werte ausgewertet und der Wert muss genau die Konstante sein. Zum Beispiel:

<?php

define
('VOGEL', 'Amsel');

// Ohne Gruppen analysieren
$ini_array = parse_ini_file("sample.ini");
print_r($ini_array);

// Mit Gruppen analysieren
$ini_array = parse_ini_file("sample.ini", TRUE);
print_r($ini_array);

?>

Das oben gezeigte Beispiel erzeugt eine ähnliche Ausgabe wie:

Array
(
    [eins] => 1
    [fünf] => 5
    [tier] => Amsel
    [pfad] => /usr/local/bin
    [URL] => http://www.example.com/~username
    [phpversion] => Array
        (
            [0] => 5.0
            [1] => 5.1
            [2] => 5.2
            [3] => 5.3
        )

    [urls] => Array
        (
            [svn] => http://svn.php.net
            [git] => http://git.php.net
        )

)
Array
(
    [erste_gruppe] => Array
        (
            [eins] => 1
            [fünf] => 5
            [tier] => Amsel
        )

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

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

            [urls] => Array
                (
                    [svn] => http://svn.php.net
                    [git] => http://git.php.net
                )

        )

)

Beispiel #3 parse_ini_file() parst eine php.ini

<?php
// Eine einfache Funktion, um das Ergebnis zu vergleichen
function janein($expression)
{
return(
$expression ? 'Ja' : 'Nein');
}

// Pfad der php.ini mittels der Funktion php_ini_loaded_file() holen
$ini_path = php_ini_loaded_file();

// Parsen der php.ini
$ini = parse_ini_file($ini_path);

// Werte ausgeben und vergleichen. Beachten Sie dass die Verwendung von
// get_cfg_var() die gleichen Ergebnisse für geparste und geladene
// Werte geben wird
echo '(geparst) magic_quotes_gpc = ' . janein($ini['magic_quotes_gpc']) . PHP_EOL;
echo
'(geladen) magic_quotes_gpc = ' . janein(get_cfg_var('magic_quotes_gpc')) . PHP_EOL;
?>

Das oben gezeigte Beispiel erzeugt eine ähnliche Ausgabe wie:

(geparst) magic_quotes_gpc = Ja
(geladen) magic_quotes_gpc = Nein

Beispiel #4 Wert-Interpolation

Neben der Auswertung von Konstanten haben bestimmte Zeichen eine besondere Bedeutung in einem ini-Wert. Darüber hinaus können Umgebungsvariablen und zuvor definierte Konfigurationsoptionen (siehe get_cfg_var()) mit der ${}-Syntax gelesen werden.

; | wird für bitweises OR verwendet
three = 2|3

; & wird für bitweises AND verwendet
four = 6&5

; ^ wird für bitweises XOR verwendet
five = 3^6

; ~ wird für bitweises Negieren verwendet
negative_two = ~1

; () wird für die Gruppierung verwendet
seven = (8|7)&(6|5)

; Auswerten der Umgebungsvariablen PATH
path = ${PATH}

; Auswerten der Konfigurationsoption "memory_limit".
configured_memory_limit = ${memory_limit}

Beispiel #5 Zeichen maskieren

Einige Zeichen haben in Zeichenketten in doppelten Anführungszeichen eine besondere Bedeutung und müssen durch das Backslash-Präfix maskiert werden. Dies sind vor allem das doppelte Anführungszeichen " als Begrenzungszeichen und der Backslash \ selbst (wenn darauf ein Sonderzeichen folgt):

quoted = "She said \"Exactly my point\"." ; Ergibt eine Zeichenkette mit Anführungszeichen darin.
hint = "Use \\\" to escape double quote" ; Ergibt: Use \" to escape double quote

Es gibt eine Ausnahme für Windows-ähnliche Pfade: Es ist möglich, den abschließenden Backslash nicht zu maskieren, wenn auf die Zeichenkette in Anführungsstrichen direkt ein Zeilenumbruch folgt:

save_path = "C:\Temp\"

Wenn man doppelte Anführungszeichen gefolgt von einem Zeilenumbruch in einem mehrzeiligen Wert vermeiden muss, ist es möglich, die Verkettung von Werten auf folgende Weise zu verwenden (eine Zeichenkette mit zwei direkt aufeinanderfolgenden Anführungszeichen):

long_text = "Lorem \"ipsum\"""
 dolor" ; Ergibt: Lorem "ipsum"\n dolor

Ein weiteres Zeichen mit besonderer Bedeutung ist $ (das Dollarzeichen). Wenn darauf eine öffnende geschweifte Klammer folgt, muss es maskiert werden:

code = "\${test}"

Das Maskieren von Zeichen wird im Modus INI_SCANNER_RAW nicht unterstützt (in diesem Modus werden alle Zeichen verarbeitet wie sie sind).

Zu beachten ist, dass der ini-Parser keine Standard-Maskierungssequenzen unterstützt (\n, \t etc.). Falls erforderlich, muss das Ergebnis von parse_ini_file() mit der Funktion stripcslashes() nachbearbeitet werden.

Anmerkungen

Hinweis:

Diese Funktion hat nichts mit dem Laden der php.ini-Datei zu tun. Diese ist zum Ausführungszeitpunkt Ihres Skriptes bereits vollständig verarbeitet. Diese Funktion kann verwendet werden, um die Konfigurationsdateien Ihrer eigenen Anwendung zu lesen.

Hinweis:

Falls ein Wert der Ini-Datei ein nicht alphanumerisches Zeichen enthält muss dieser Wert in doppelte Anführungszeichen (") eingeschlossen werden.

Hinweis: Es gibt reservierte Schlüsselwörter, welche nicht als Schlüssel in Ini-Dateien verwendet werden dürfen. Diese umfassen: null, yes, no, true, false, on, off, none. Die Werte null, off, no und false ergeben "" und die Werte on, yes and true ergeben "1", solange der Modus INI_SCANNER_TYPED nicht verwendet wird . Die Zeichen ?{}|&~!()^" dürfen in einem Schlüssel nicht verwendet werden und haben im Wert besondere Bedeutung.

Hinweis:

Einträge ohne Gleichheitszeichen werden ignoriert. Beispielsweise würde "foo" ignoriert werden, während "bar =" geparst und mit einem leeren Wert hinzugefügt würde. Beispielsweise hat MySQL eine Einstellung "no-auto-rehash" in der my.cnf welche keinen Wert enthält und somit ignoriert würde.

Hinweis:

Ini-Dateien werden von Webservern in der Regel als reiner Text behandelt und daher den Browsern auf Anfrage zur Verfügung gestellt. Das bedeutet, dass Sie aus Sicherheitsgründen entweder Ihre ini-Dateien außerhalb des Web-Wurzelverzeichnisses (DocRoot) aufbewahren müssen oder Ihren Webserver so umkonfigurieren, dass sie nicht ausgeliefert werden. Wenn Sie beides nicht tun, kann dies ein Sicherheitsrisiko darstellen.

Siehe auch

add a note add a note

User Contributed Notes 12 notes

up
29
jeremygiberson at gmail dot com
15 years ago
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($filename, true);
       
$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
*/
?>
up
13
Rekam
10 years ago
You may want, in some very special cases, to parse multi-dimensional array with N levels in your ini file. Something like setting[data][config][debug] = true will result in an error (expected "=").

Here's a little function to match this, using dots (customizable).
<?php
function parse_ini_file_multi($file, $process_sections = false, $scanner_mode = INI_SCANNER_NORMAL) {
   
$explode_str = '.';
   
$escape_char = "'";
   
// load ini file the normal way
   
$data = parse_ini_file($file, $process_sections, $scanner_mode);
    if (!
$process_sections) {
       
$data = array($data);
    }
    foreach (
$data as $section_key => $section) {
       
// loop inside the section
       
foreach ($section as $key => $value) {
            if (
strpos($key, $explode_str)) {
                if (
substr($key, 0, 1) !== $escape_char) {
                   
// key has a dot. Explode on it, then parse each subkeys
                    // and set value at the right place thanks to references
                   
$sub_keys = explode($explode_str, $key);
                   
$subs =& $data[$section_key];
                    foreach (
$sub_keys as $sub_key) {
                        if (!isset(
$subs[$sub_key])) {
                           
$subs[$sub_key] = [];
                        }
                       
$subs =& $subs[$sub_key];
                    }
                   
// set the value at the right place
                   
$subs = $value;
                   
// unset the dotted key, we don't need it anymore
                   
unset($data[$section_key][$key]);
                }
               
// we have escaped the key, so we keep dots as they are
               
else {
                   
$new_key = trim($key, $escape_char);
                   
$data[$section_key][$new_key] = $value;
                    unset(
$data[$section_key][$key]);
                }
            }
        }
    }
    if (!
$process_sections) {
       
$data = $data[0];
    }
    return
$data;
}
?>

The following file:
<?php
/*
[normal]
foo = bar
; use quotes to keep your key as it is
'foo.with.dots' = true

[array]
foo[] = 1
foo[] = 2

[dictionary]
foo[debug] = false
foo[path] = /some/path

[multi]
foo.data.config.debug = true
foo.data.password = 123456
*/
?>

will result in:
<?php
parse_ini_file_multi
('file.ini', true);

Array
(
    [
normal] => Array
        (
            [
foo] => bar
           
[foo.with.dots] => 1
       
)
    [array] => Array
        (
            [
foo] => Array
                (
                    [
0] => 1
                   
[1] => 2
               
)
        )
    [
dictionary] => Array
        (
            [
foo] => Array
                (
                    [
debug] =>
                    [
path] => /some/path
               
)
        )
    [
multi] => Array
        (
            [
foo] => Array
                (
                    [
data] => Array
                        (
                            [
config] => Array
                                (
                                    [
debug] => 1
                               
)
                            [
password] => 123456
                       
)
                )
        )
)
?>
up
4
dschnepper at box dot com
8 years ago
The documentation states:
Characters ?{}|&~!()^" must not be used anywhere in the key and have a special meaning in the value.

Here's the results of my experiments on what they mean:

; | is used for bitwise OR
three = 2|3

; & is used for bitwise AND
four = 6&5

; ^ is used for bitwise XOR
five = 3^6

; ~ is used for bitwise negate
negative_two = ~1

; () is used for grouping
seven = (8|7)&(6|5)

; ${...} is used for grabbing values from the environment, or previously defined values.
path = ${PATH}
also = ${five}

; ? I have no guess for
; ! I have no guess for
up
5
YAPs
8 years ago
This function for save ini files

<?php
function array_to_ini($array,$out="")
{
   
$t="";
   
$q=false;
    foreach(
$array as $c=>$d)
    {
        if(
is_array($d))$t.=array_to_ini($d,$c);
        else
        {
            if(
$c===intval($c))
            {
                if(!empty(
$out))
                {
                   
$t.="\r\n".$out." = \"".$d."\"";
                    if(
$q!=2)$q=true;
                }
                else
$t.="\r\n".$d;
            }
            else
            {   
               
$t.="\r\n".$c." = \"".$d."\"";
               
$q=2;
            }
        }
    }
    if(
$q!=true && !empty($out)) return "[".$out."]\r\n".$t;
    if(!empty(
$out)) return  $t;
    return
trim($t);
}

function
save_ini_file($array,$file)
{
   
$a=array_to_ini($array);
   
$ffl=fopen($file,"w");
   
fwrite($ffl,$a);
   
fclose($ffl);
}
?>
up
3
info () gaj ! design
8 years ago
Not mentioned in the documentation, this function acts like include:

"Files are included based on the file path given or, if none is given, the include_path specified. If the file isn't found in the include_path, include will finally check in the calling script's own directory and the current working directory before failing."

(At least for PHP 7; have not checked PHP 5.)
up
2
kieran dot huggins at rogers dot com
21 years ago
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
up
4
Justin Hall
18 years ago
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] => I (walked) | {to} "the" park yesterday & saw ~three~ dogs!
)
?>
up
3
goulven.ch AT gmail DOT com
17 years ago
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 ) == 0 ) { 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( $line, 1, -1 );
           
$i++;
            continue;
        }
       
// Key-value pair
       
list( $key, $value ) = explode( '=', $line, 2 );
       
$key = trim( $key );
       
$value = trim( $value );
        if (
$i == 0 ) {
           
// Array values
           
if ( substr( $line, -1, 2 ) == '[]' ) {
               
$globals[ $key ][] = $value;
            } else {
               
$globals[ $key ] = $value;
            }
        } else {
           
// Array values
           
if ( substr( $line, -1, 2 ) == '[]' ) {
               
$values[ $i - 1 ][ $key ][] = $value;
            } else {
               
$values[ $i - 1 ][ $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.
*/
?>
up
5
simon dot riget at gmail dot com
11 years ago
.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;
}
?>
up
1
eciruam35 at gmail dot com
1 year ago
fix a little bug (here) in function put_ini_file:

function put_ini_file($config, $file, $has_section = false, $write_to_file = true){
    $fileContent = '';
    if(!empty($config)){
        foreach($config as $i=>$v){
            if($has_section){
                $fileContent .= "\n[$i]".PHP_EOL.put_ini_file($v, $file, false, false);
            }
            else{
                if(is_array($v)){
                    foreach($v as $t=>$m){
//--->>> Here                        $fileContent .= "-->$i[$t] = ".(is_numeric($m) ? $m : '"'.$m.'"').PHP_EOL;
                        $fileContent .= "$i"."[] = ".(is_numeric($m) ? $m : '"'.$m.'"').PHP_EOL;
                    }
                }
                else $fileContent .= "$i = ".(is_numeric($v) ? $v : '"'.$v.'"').PHP_EOL;
            }
        }
    }

    if($write_to_file && strlen($fileContent)) return file_put_contents($file, $fileContent, LOCK_EX);
    else return $fileContent;
}
up
0
manngo
1 year ago
Securing your .ini file:

“ini files are generally treated as plain text by web servers and thus served to browsers if requested. That means for security you must either keep your ini files outside of your docroot or reconfigure your web server to not serve them. Failure to do either of those may introduce a security risk.”

Alternatively, you can save you file as:

stuff.ini.php

add this to the beginning:

;<?php die('go away'); ?>

The semicolon at the beginning is treated as comment, so this line has no effect on the ini file.

Since the file has a .php extension, it will run through the PHP interpreter if you attempt to access this file directly, and the php block will be processed and exit.

The file extension has no ill effect on the parse_ini_file() function, and the .ini part is, of course, a matter of taste.
up
0
jbricci at ya-right dot com
9 years ago
This core function won't handle ini key[][] = value(s), (multidimensional arrays), so if you need to support that kind of setup you will need to write your own function. one way to do it is to convert all the key = value(s) to array string [key][][]=value(s), then use parse_str() to convert all those [key][][]=value(s) that way you just read the ini file line by line, instead of doing crazy foreach() loops to handle those (multidimensional arrays) in each section, example...

ini file...... config.php

<?php

; 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"

urls[svn] = "http://svn.php.net"
urls[git] = "http://git.php.net"

[fourth_section]

a[][][] = b
a
[][][][] = c
a
[test_test][][] = d
test
[one][two][three] = true

?>

echo parse_ini_file ( "C:\\services\\www\\docs\\config.php" );

results in...

// PHP Warning:  syntax error, unexpected TC_SECTION, expecting '=' line 27 -> a[][][] = b

Here it simple function that handles (multidimensional arrays) without looping each key[][]= value(s)

<?php

function getIni ( $file, $sections = FALSE )
{
   
$return = array ();

   
$keeper = array ();

   
$config = fopen ( $file, 'r' );

    while ( !
feof ( $config ) )
    {
       
$line = trim ( fgets ( $config, 1024 ) );

       
$line = ( $line == '' ) ? ' ' : $line;

        switch (
$line{0} )
        {
            case
' ':
            case
'#':
            case
'/':
            case
';':
            case
'<':
            case
'?':

            break;

            case
'[':

            if (
$sections )
            {
               
$header = 'config[' . trim ( substr ( $line, 1, -1 ) ) . ']';
            }
            else
            {
               
$header = 'config';
            }

            break;

            default:

           
$kv = array_map ( 'trim', explode ( '=', $line ) );

           
$kv[0] = str_replace ( ' ', '+', $kv[0] );

           
$kv[1] = str_replace ( ' ', '+', $kv[1] );

            if ( (
$pos = strpos ( $kv[0], '[' ) ) !== FALSE )
            {
               
$kv[0] = '[' . substr ( $kv[0], 0, $pos ) . ']' . substr ( $kv[0], $pos );
            }
            else
            {
               
$kv[0] = '[' . $kv[0] . ']';
            }

           
$bt = strtolower ( $kv[1] );

            if (
in_array ( $bt, array ( 'true', 'false', 'on', 'off' ) ) )
            {
               
$kv[1] = ( $bt == 'true' || $bt == 'on' ) ? TRUE : FALSE;
            }

           
$keeper[] = $header . $kv[0] . '=' . $kv[1];
        }
    }

   
fclose ( $config );

   
parse_str ( implode ( '&', $keeper ), $return );

    return
$return['config'];
}

// usage...

$sections = TRUE;

print_r ( $config->getIni ( "C:\\services\\www\\docs\\config.php" ),  $sections );

?>
To Top