在INI文件中使用关键字作为变量名

问题描述

| 我的INI文件中包含以下内容:
[country]
SE = Sweden
NO = Norway
FI = Finland
但是,当var_dump()使用PHP的parse_ini_file()函数时,我得到以下输出:
PHP Warning:  syntax error,unexpected BOOL_FALSE in test.ini on line 2
in /Users/andrew/sandbox/test.php on line 1
bool(false)
看来\“ NO \”已保留。我还有其他方法可以设置名为\“ NO \”的变量吗?     

解决方法

另一个技巧是使用其值反转您的ini键并使用array_flip:
<?php

$ini =
\"
    [country]
    Sweden = \'SE\'
    Norway = \'NO\'
    Finland = \'FI\'
\";

$countries = parse_ini_string($ini,true);
$countries = array_flip($countries[\"country\"]);
echo $countries[\"NO\"];
不过,如果您这样做,则仍需要至少使用引号(至少)
Norway = NO
您不会收到错误,但$ countries [\“ NO \”]的值将为空字符串。     ,这可能有点晚了,但是PHP的parse_ini_file的工作方式使我非常烦恼,以至于我编写了自己的小解析器。 可以随意使用它,但小心使用它只是经过初步测试!
// the exception used by the parser
class IniParserException extends \\Exception {

    public function __construct($message,$code = 0,\\Exception $previous = null) {
        parent::__construct($message,$code,$previous);
    }

    public function __toString() {
        return __CLASS__ . \": [{$this->code}]: {$this->message}\\n\";
    }

}

// the parser
function my_parse_ini_file($filename,$processSections = false) {
    $initext = file_get_contents($filename);
    $ret = [];
    $section = null;
    $lineNum = 0;
    $lines = explode(\"\\n\",str_replace(\"\\r\\n\",\"\\n\",$initext));
    foreach($lines as $line) {
        ++$lineNum;

        $line = trim(preg_replace(\'/[;#].*/\',\'\',$line));
        if(strlen($line) === 0) {
            continue;
        }

        if($processSections && $line{0} === \'[\' && $line{strlen($line)-1} === \']\') {
            // section header
            $section = trim(substr($line,1,-1));
        } else {
            $eqIndex = strpos($line,\'=\');
            if($eqIndex !== false) {
                $key = trim(substr($line,$eqIndex));
                $matches = [];
                preg_match(\'/(?<name>\\w+)(?<index>\\[\\w*\\])?/\',$key,$matches);
                if(!array_key_exists(\'name\',$matches)) {
                    throw new IniParserException(\"Variable name must not be empty! In file \\\"$filename\\\" in line $lineNum.\");
                }
                $keyName = $matches[\'name\'];
                if(array_key_exists(\'index\',$matches)) {
                    $isArray = true;
                    $arrayIndex = trim($matches[\'index\']);
                    if(strlen($arrayIndex) == 0) {
                        $arrayIndex = null;
                    }
                } else {
                    $isArray = false;
                    $arrayIndex = null;
                }

                $value = trim(substr($line,$eqIndex+1));
                if($value{0} === \'\"\' && $value{strlen($value)-1} === \'\"\') {
                    // too lazy to check for multiple closing \" let\'s assume it\'s fine
                    $value = str_replace(\'\\\\\"\',\'\"\',substr($value,-1));
                } else {
                    // special value
                    switch(strtolower($value)) {
                        case \'yes\':
                        case \'true\':
                        case \'on\':
                            $value = true;
                            break;
                        case \'no\':
                        case \'false\':
                        case \'off\':
                            $value = false;
                            break;
                        case \'null\':
                        case \'none\':
                            $value = null;
                            break;
                        default:
                            if(is_numeric($value)) {
                                $value = $value + 0; // make it an int/float
                            } else {
                                throw new IniParserException(\"\\\"$value\\\" is not a valid value! In file \\\"$filename\\\" in line $lineNum.\");
                            }
                    }
                }

                if($section !== null) {
                    if($isArray) {
                        if(!array_key_exists($keyName,$ret[$section])) {
                            $ret[$section][$keyName] = [];
                        }
                        if($arrayIndex === null) {
                            $ret[$section][$keyName][] = $value;
                        } else {
                            $ret[$section][$keyName][$arrayIndex] = $value;
                        }
                    } else {
                        $ret[$section][$keyName] = $value;
                    }
                } else {
                    if($isArray) {
                        if(!array_key_exists($keyName,$ret)) {
                            $ret[$keyName] = [];
                        }
                        if($arrayIndex === null) {
                            $ret[$keyName][] = $value;
                        } else {
                            $ret[$keyName][$arrayIndex] = $value;
                        }
                    } else {
                        $ret[$keyName] = $value;
                    }
                }
            }
        }
    }

    return $ret;
}
有什么不同?变量名只能由字母数字字符组成,但除此之外没有任何限制。字符串必须用\“封装。其他所有值都必须是一个特殊值,例如
no
yes
true
false
on
off
null
none
。有关映射的信息,请参见代码。     ,有点骇客,但您可以在键名周围添加反引号:
[country]
`SE` = Sweden
`NO` = Norway
`FI` = Finland
然后像这样访问它们:
$result = parse_ini_file(\'test.ini\');
echo \"{$result[\'`NO`\']}\\n\";
输出:
$ php test.php
Norway
    ,当字符串中有单引号组合(例如\'t或\'s)时,出现此错误。为了解决这个问题,我将字符串用双引号引起来: 之前:
You have selected \'Yes\' but you haven\'t entered the date\'s flexibility
后:
\"You have selected \'Yes\' but you haven\'t entered the date\'s flexibility\"
    ,我遇到了同样的问题,并试图以各种可能的方式来逃避这个名字。 然后我记得由于INI语法,名称和值都将被修剪,因此以下变通办法可以解决这个问题:
NL = Netherlands
; A whitespace before the name
 NO = Norway
PL = Poland
而且有效;)只要您的同事阅读了评论(并非总是如此)并且不要意外删除它。因此,是的,阵列翻转解决方案是安全的选择。     ,在
parse_ini_file
的手册页中:   有保留字,不能将其用作ini文件的键。其中包括:null,yes,no,true,false,on,off,none。 因此,不能,您不能设置变量
NO
。     

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...