PHP parse_ini_string() 函数

提示:parse_ini_string() 函数用于解析INI格式的配置字符串,并将其内容转换为关联数组或多维数组。与parse_ini_file()不同,它从字符串而不是文件中读取配置。

定义和用法

parse_ini_string() 函数用于解析INI格式的配置字符串,并将其内容转换为数组。

此函数与parse_ini_file()类似,但输入源是一个字符串而不是文件。它通常用于从数据库、API响应或其他非文件源读取配置。

语法

parse_ini_string ( string $ini_string , bool $process_sections = false , int $scanner_mode = INI_SCANNER_NORMAL ) : array|false

参数

参数 类型 说明
ini_string 字符串 要解析的INI格式字符串
process_sections 布尔值 设置为true时返回多维数组,包含节(section)名称。默认为false
scanner_mode 整数 可以是INI_SCANNER_NORMAL(默认),INI_SCANNER_RAW或INI_SCANNER_TYPED

scanner_mode 常量

常量 说明
INI_SCANNER_NORMAL 默认模式。值被解析为字符串,但保留常量替换
INI_SCANNER_RAW 原始模式。值被原样返回,不解析常量
INI_SCANNER_TYPED 类型模式。尝试将值转换为适当的PHP类型(布尔值、整数、浮点数、字符串)

返回值

成功时返回一个包含配置设置的关联数组或多维数组,失败时返回 false

示例

示例 1:基本用法 - 解析简单INI字符串

<?php
$iniString = <<<INI
site_name = "我的网站"
debug_mode = on
max_users = 100
version = 1.5
; 这是一个注释
INI;

$config = parse_ini_string($iniString);
if ($config !== false) {
    echo "配置解析成功!\n";
    echo "网站名称: " . $config['site_name'] . "\n";
    echo "调试模式: " . ($config['debug_mode'] ? '开启' : '关闭') . "\n";
    echo "最大用户数: " . $config['max_users'] . "\n";
    echo "版本: " . $config['version'] . "\n";

    // 打印所有配置
    echo "\n所有配置:\n";
    print_r($config);
} else {
    echo "解析INI字符串失败\n";
}
?>

示例 2:处理节(sections)

<?php
$iniString = <<<INI
; 全局设置
app_name = "My Application"
debug = true

[database]
host = "localhost"
username = "admin"
password = "secret"
port = 3306

[mail]
smtp_server = "smtp.example.com"
smtp_port = 587
from = "noreply@example.com"

[features]
enabled[] = "logging"
enabled[] = "caching"
enabled[] = "api"
INI;

// 解析并处理节
$config = parse_ini_string($iniString, true);
if ($config !== false) {
    echo "配置解析成功!\n\n";

    echo "应用程序名称: " . $config['app_name'] . "\n";
    echo "调试模式: " . ($config['debug'] ? '开启' : '关闭') . "\n\n";

    echo "数据库配置:\n";
    echo "  主机: " . $config['database']['host'] . "\n";
    echo "  用户名: " . $config['database']['username'] . "\n";
    echo "  端口: " . $config['database']['port'] . "\n\n";

    echo "邮件配置:\n";
    echo "  SMTP服务器: " . $config['mail']['smtp_server'] . "\n";
    echo "  SMTP端口: " . $config['mail']['smtp_port'] . "\n\n";

    echo "功能列表:\n";
    foreach ($config['features']['enabled'] as $feature) {
        echo "  - " . $feature . "\n";
    }
} else {
    echo "解析INI字符串失败\n";
}
?>

示例 3:使用不同的扫描模式

<?php
$iniString = <<<INI
bool_true = true
bool_false = false
int_value = 42
float_value = 3.14159
string_value = "hello world"
null_value = null
const_value = PATH_SEPARATOR
INI;

echo "INI_SCANNER_NORMAL (默认):\n";
$normal = parse_ini_string($iniString, false, INI_SCANNER_NORMAL);
print_r($normal);

echo "\nINI_SCANNER_RAW:\n";
$raw = parse_ini_string($iniString, false, INI_SCANNER_RAW);
print_r($raw);

echo "\nINI_SCANNER_TYPED:\n";
$typed = parse_ini_string($iniString, false, INI_SCANNER_TYPED);
print_r($typed);

// 显示类型信息
echo "\n类型信息 (INI_SCANNER_TYPED):\n";
foreach ($typed as $key => $value) {
    $type = gettype($value);
    echo "$key = ";
    var_export($value);
    echo " ($type)\n";
}
?>

示例 4:从数据库读取配置

<?php
// 模拟从数据库获取配置字符串
function getConfigFromDatabase($configName) {
    // 这里模拟数据库查询
    $configs = [
        'site_config' => <<<INI
app_name = "电子商务网站"
timezone = "Asia/Shanghai"
currency = "CNY"
currency_symbol = "¥"

[db]
host = "127.0.0.1"
name = "ecommerce"
user = "ecom_user"

[features]
enable_cache = true
enable_logging = true
maintenance_mode = false
INI
    ];

    return $configs[$configName] ?? '';
}

// 从数据库获取配置字符串
$configString = getConfigFromDatabase('site_config');
if (!empty($configString)) {
    $config = parse_ini_string($configString, true, INI_SCANNER_TYPED);

    if ($config !== false) {
        echo "从数据库加载配置成功!\n\n";
        echo "应用程序名称: " . $config['app_name'] . "\n";
        echo "时区: " . $config['timezone'] . "\n";
        echo "货币: " . $config['currency_symbol'] . $config['currency'] . "\n\n";

        echo "数据库配置:\n";
        echo "  主机: " . $config['db']['host'] . "\n";
        echo "  数据库名: " . $config['db']['name'] . "\n";
        echo "  用户名: " . $config['db']['user'] . "\n\n";

        echo "功能状态:\n";
        echo "  缓存: " . ($config['features']['enable_cache'] ? '开启' : '关闭') . "\n";
        echo "  日志: " . ($config['features']['enable_logging'] ? '开启' : '关闭') . "\n";
        echo "  维护模式: " . ($config['features']['maintenance_mode'] ? '是' : '否') . "\n";
    } else {
        echo "解析配置失败\n";
    }
} else {
    echo "未找到配置\n";
}
?>

示例 5:与parse_ini_file()的对比使用

<?php
// 场景:从文件读取配置,然后动态修改并解析

// 方法1:使用parse_ini_file()
$fileConfig = parse_ini_file('config.ini', true);
echo "从文件读取的配置:\n";
print_r($fileConfig);

// 方法2:读取文件内容后用parse_ini_string()解析
$iniContent = file_get_contents('config.ini');
if ($iniContent !== false) {
    $stringConfig = parse_ini_string($iniContent, true);
    echo "\n从字符串解析的配置:\n";
    print_r($stringConfig);

    // 比较两种方法的结果
    echo "\n两种方法结果是否相同: " .
        ($fileConfig == $stringConfig ? '是' : '否') . "\n";
}

// 动态修改配置字符串
$dynamicIni = $iniContent . "\n[dynamic]\nadded_at = \"" . date('Y-m-d H:i:s') . "\"\n";
$dynamicConfig = parse_ini_string($dynamicIni, true);
echo "\n动态修改后的配置:\n";
print_r($dynamicConfig['dynamic']);
?>

INI字符串语法规则

  1. 注释:以分号(;)或井号(#)开头
  2. 键值对:格式为 key = value,等号周围可以有空格
  3. 值类型:字符串、整数、浮点数、布尔值(true/false, on/off, yes/no, 1/0)
  4. 字符串:可以用双引号或单引号括起来,也可以不用引号
  5. 节:用方括号定义,如 [section_name]
  6. 数组:通过添加空方括号表示,如 key[] = value
  7. 常量替换:在INI_SCANNER_NORMAL模式下,会解析PHP常量
  8. 特殊字符:包含空格、等号、分号等特殊字符的值应该用引号括起来

注意事项

  • 输入验证:确保输入的INI字符串格式正确,否则函数返回false
  • 内存使用:对于非常大的INI字符串,注意内存使用情况
  • 性能:对于频繁解析的配置,考虑缓存解析结果
  • 安全性:不要从未经信任的源解析INI字符串,特别是允许常量替换时
  • 字符编码:字符串应该使用UTF-8编码,否则可能遇到编码问题
  • 行结束符:支持Unix(\n)、Windows(\r\n)和Mac(\r)行结束符
  • 嵌套节:不支持嵌套节(节中包含节)
  • 错误处理:总是检查返回值是否为false,以处理解析失败的情况

常见应用场景

  1. 数据库存储配置:将配置以INI格式存储在数据库中
  2. API响应解析:解析返回INI格式的API响应
  3. 动态配置生成:动态生成配置字符串并解析
  4. 配置模板:从模板生成配置,填入动态值后解析
  5. 测试:在单元测试中创建临时配置
  6. 环境配置:从环境变量构建配置字符串

与parse_ini_file()的区别

特性 parse_ini_string() parse_ini_file()
输入源 字符串 文件
文件I/O 不需要 需要
适用场景 数据库、API、动态生成的配置 静态配置文件
错误处理 解析失败返回false 文件不存在或解析失败返回false
性能 通常更快(无文件I/O) 有文件I/O开销

相关函数