2011-05-26 13 views
7

He lo siguiente en un archivo INI:El uso de una palabra clave como nombre de variable en un archivo INI

[country] 
SE = Sweden 
NO = Norway 
FI = Finland 

Sin embargo, cuando var_dump() ing función de PHP parse_ini_file(), me sale el siguiente resultado:

PHP Warning: syntax error, unexpected BOOL_FALSE in test.ini on line 2 
in /Users/andrew/sandbox/test.php on line 1 
bool(false) 

Parece que "NO" está reservado. ¿Hay alguna otra forma en que pueda establecer una variable llamada "NO"?

Respuesta

4

Otro truco haría debe invertir sus claves ini con sus valores y usar 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"]; 

Aún tendrá que utilizar comillas no (por lo menos), si lo hace

Norway = NO 

usted no obtiene un error, pero el valor para los países $ [ "NO"] será una cuerda vacía.

+0

+1 Oh, buena solución :-) – lonesomeday

+1

Gracias, esa es probablemente la única manera de hacerlo. –

+0

¿No se rompería esto si sus valores no son únicos? Después de todo, son * valores *, no claves. – Pacerier

-1

Desde la página del manual para parse_ini_file:

No son palabras reservadas que no deben ser usadas como claves en los archivos ini. Estos incluyen: nulo, sí, no, verdadero, falso, encendido, apagado, ninguno.

Así que no, no puede establecer una variable NO.

+1

Él está pidiendo una solución. – Pacerier

2

especie de truco, pero puede agregar acentos abiertos alrededor de los nombres clave:

[country] 
`SE` = Sweden 
`NO` = Norway 
`FI` = Finland 

A continuación, acceder a ellos de esta manera:

$result = parse_ini_file('test.ini'); 
echo "{$result['`NO`']}\n"; 

Salida:

$ php test.php 
Norway 
+1

Eso no es diferente a cambiar el nombre de la variable a otra cosa. Con su solución, el nombre de la variable es \ 'NO \', no NO. Podría hacer '' πNOπ = Norway' en el archivo de configuración. –

0

Recibí este error cuando había combinaciones de comillas simples en la cadena como 't' o 's'. Para deshacerse del problema, envolví la cadena en comillas dobles:

Antes:

You have selected 'Yes' but you haven't entered the date's flexibility 

Después:

"You have selected 'Yes' but you haven't entered the date's flexibility" 
3

Esto además probablemente llega un poco tarde, pero la forma en que los PHP parse_ini_file obras molestaba tanto que escribí mi propio pequeño analizador.

Siéntase libre de usarlo, pero úselo con cuidado, ¡solo ha sido probado superficialmente!

// 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, 0, $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, -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; 
} 

¿Qué diferencia tiene? Los nombres de las variables solo pueden consistir en caracteres alfanuméricos, pero aparte de eso, no hay restricciones para ellos. Las cadenas deben ser encapsulados con "todo lo demás tiene que ser un valor especial como no, yes, true, false, on, off, null o none. Para ver el mapeo de código.

0

Me encontré con el mismo problema e intenté escaparme del nombre de todas las maneras posibles.

Entonces me acordé de que, debido a la sintaxis INI se recortarán los dos nombres y valores, por lo que la siguiente solución quizás debería hacer el truco:

NL = Netherlands 
; A whitespace before the name 
NO = Norway 
PL = Poland 

y funciona;) Mientras sus compañeros de trabajo lea los comentarios (que no siempre es el caso) y no los elimine accidentalmente. Entonces, sí, la solución de volteo de matriz es una apuesta segura.

Cuestiones relacionadas