PHP Conference Japan 2024

parse_ini_string

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

parse_ini_string解析設定字串

說明

parse_ini_string(字串 $ini_string, 布林值 $process_sections = false, 整數 $scanner_mode = INI_SCANNER_NORMAL): 陣列|false

parse_ini_string() 會將字串 ini_string 中的設定值返回為一個關聯式陣列。

ini 字串的結構與 php.ini 的結構相同。

參數

ini_string

要被解析的 ini 檔案內容。

process_sections

process_sections 參數設定為 true,您將會得到一個多維陣列,其中包含區段名稱和設定值。 process_sections 的預設值為 false

scanner_mode

可以是 INI_SCANNER_NORMAL(預設值)或 INI_SCANNER_RAW。如果提供 INI_SCANNER_RAW,則選項值將不會被解析。

從 PHP 5.6.1 開始,也可以指定為 INI_SCANNER_TYPED。在此模式下,布林值、null 和整數類型會盡可能被保留。字串值 "true""on""yes" 會被轉換為 true"false""off""no""none" 會被視為 false"null" 在類型化模式下會被轉換為 null。此外,所有數字字串都會盡可能地轉換為整數類型。

返回值

成功時,設定值會以關聯式 陣列 返回,失敗時則返回 false

注意事項

注意:有一些保留字不能用作 ini 檔案的鍵值。這些保留字包括:nullyesnotruefalseonoffnone。值 nulloffnofalse 會導致 "",而值 onyestrue 會導致 "1",除非使用 INI_SCANNER_TYPED 模式。字元 ?{}|&~![()^" 不能在鍵值中的任何位置使用,並且在值中具有特殊含義。

參見

新增筆記

使用者貢獻的筆記 4 則筆記

24
epicmaxim at gmail dot com
11 年前
parse_ini_string_m 是 parse_ini_string 函式的類似函式。

由於某些主機上缺少 php 5.3,因此必須編寫此函式。

parse_ini_string_m
- 忽略以 ";" 或 "#" 開頭的註釋行
- 忽略不包含 "=" 的斷行
- 支援陣列值和陣列值的鍵

<?php
function parse_ini_string_m($str) {

if(empty(
$str)) return false;

$lines = explode("\n", $str);
$ret = Array();
$inside_section = false;

foreach(
$lines as $line) {

$line = trim($line);

if(!
$line || $line[0] == "#" || $line[0] == ";") continue;

if(
$line[0] == "[" &amp;&amp; $endIdx = strpos($line, "]")){
$inside_section = substr($line, 1, $endIdx-1);
continue;
}

if(!
strpos($line, '=')) continue;

$tmp = explode("=", $line, 2);

if(
$inside_section) {

$key = rtrim($tmp[0]);
$value = ltrim($tmp[1]);

if(
preg_match("/^\".*\"$/", $value) || preg_match("/^'.*'$/", $value)) {
$value = mb_substr($value, 1, mb_strlen($value) - 2);
}

$t = preg_match("^\[(.*?)\]^", $key, $matches);
if(!empty(
$matches) &amp;&amp; isset($matches[0])) {

$arr_name = preg_replace('#\[(.*?)\]#is', '', $key);

if(!isset(
$ret[$inside_section][$arr_name]) || !is_array($ret[$inside_section][$arr_name])) {
$ret[$inside_section][$arr_name] = array();
}

if(isset(
$matches[1]) &amp;&amp; !empty($matches[1])) {
$ret[$inside_section][$arr_name][$matches[1]] = $value;
} else {
$ret[$inside_section][$arr_name][] = $value;
}

} else {
$ret[$inside_section][trim($tmp[0])] = $value;
}

} else {

$ret[trim($tmp[0])] = ltrim($tmp[1]);

}
}
return
$ret;
}
?>

範例用法

<?php
$ini
= '

[simple]
val_one = "some value"
val_two = 567

[array]
val_arr[] = "arr_elem_one"
val_arr[] = "arr_elem_two"
val_arr[] = "arr_elem_three"

[array_keys]
val_arr_two[6] = "key_6"
val_arr_two[some_key] = "some_key_value"

'
;

$arr = parse_ini_string_m($ini);
?>

變數 $arr 輸出

陣列
(
[simple] => 陣列
(
[val_one] => some value
[val_two] => 567
)

[array] => 陣列
(
[val_arr] => 陣列
(
[0] => arr_elem_one
[1] => arr_elem_two
[2] => arr_elem_three
)
)

[array_keys] => 陣列
(
[val_arr_two] => 陣列
(
[6] => key_6
[some_key] => some_key_value
)

)

)
3
Peter Baylies
11 年前
適用於 PHP 5.3 之前版本的 php_ini_string() 替代方案 - 使用 php_ini_file() 和串流

<?php
if ( !function_exists( 'parse_ini_string' ) ) {
function
parse_ini_string( $string, $process_sections ) {
if ( !
class_exists( 'parse_ini_filter' ) ) {
/* 定義我們的過濾器類別 */
class parse_ini_filter extends php_user_filter {
static
$buf = '';
function
filter( $in, $out, &$consumed, $closing ) {
$bucket = stream_bucket_new( fopen('php://memory', 'wb'), self::$buf );
stream_bucket_append( $out, $bucket );
return
PSFS_PASS_ON;
}
}
/* 向 PHP 註冊我們的過濾器 */
stream_filter_register("parse_ini", "parse_ini_filter")
or return
false;
}
parse_ini_filter::$buf = $string;
return
parse_ini_file( "php://filter/read=parse_ini/resource=php://memory", $process_sections );
}
}
?>
1
msegit post pl
6 年前
使用下方的 parse_ini_stringM() 函式,您可以
- 修正未賦值的欄位 ('key' (無效) ==> 'key=' (有效) )
- 修正包含等號 '=' 且未加引號的值 ('key=value_part1=value_part2' ==> 'key="value_part1=value_part2"')
- 修正 (解決) 多維陣列 (使 'key[key1][key2]=value' 有效)

parse_ini_stringM() 函式位於 github https://gist.github.com/msegu/c43a871c5a874a1d9bff978b448a0aa4 (這裡太長了)

// 範例

$ini = '[a]
b
c=d
e=';

var_export(parse_ini_string($ini, TRUE)); /* array (
'a' =>
array (
'c' => 'd',
'e' => '',
),
)
*/

$ini .= '
f[g][2]=h
f[g][i]=j
f[g][][]=k
m=n=o';

var_export(parse_ini_string($ini, TRUE)); // false

var_export(parse_ini_stringM($ini, TRUE)); /* 陣列 (
'a' =>
array (
'b' => '',
'c' => 'd',
'e' => '',
'f' =>
array (
'g' =>
array (
2 => 'h',
'i' => 'j',
3 =>
array (
0 => 'k',
),
),
),
'm' => 'n=o',
),
)
*/
0
Philo
11 個月前
嗨,
至少在 PHP 8.3 之前,INI_SCANNER_TYPED 在嘗試從常數獲取值時似乎被忽略了。
例如
<?php
// https://3v4l.org/qK5o8

const OK = true;
const
KO = false;
const
NIL = null;

$ini = <<<'INI'
a = TRUE
b = FALSE
c = null
d = 9223372036854775807
INI;
var_dump(parse_ini_string($ini, false, INI_SCANNER_NORMAL), parse_ini_string($ini, false, INI_SCANNER_TYPED));
$ini = <<<'INI'
a = OK
b = KO
c = NIL
d = PHP_INT_MAX
INI;
var_dump(parse_ini_string($ini, false, INI_SCANNER_NORMAL), parse_ini_string($ini, false, INI_SCANNER_TYPED));
?>

我覺得這點值得一提。
To Top