Domanda

Sto cercando di creare un array multidimensionale le cui parti sono determinate da una stringa. Sto usando . come delimitatore e ogni parte (tranne l'ultima) dovrebbe essere una matrice
es:

config.debug.router.strictMode = true

Voglio gli stessi risultati che se dovessi digitare:

$arr = array('config' => array('debug' => array('router' => array('strictMode' => true))));

Questo problema mi ha davvero fatto andare in cerchio, ogni aiuto è apprezzato. Grazie!

È stato utile?

Soluzione

Supponiamo che abbiamo già la chiave e il valore in $ key e $ val , quindi puoi farlo:

$key = 'config.debug.router.strictMode';
$val = true;
$path = explode('.', $key);

Creazione di un array da sinistra a destra:

$arr = array();
$tmp = &$arr;
foreach ($path as $segment) {
    $tmp[$segment] = array();
    $tmp = &$tmp[$segment];
}
$tmp = $val;

E da destra a sinistra:

$arr = array();
$tmp = $val;
while ($segment = array_pop($path)) {
    $tmp = array($segment => $tmp);
}
$arr = $tmp;

Altri suggerimenti

Dico di dividere tutto, iniziare con il valore e lavorare all'indietro da lì, ogni volta, avvolgendo ciò che hai all'interno di un altro array. In questo modo:

$s = 'config.debug.router.strictMode = true';
list($parts, $value) = explode(' = ', $s);

$parts = explode('.', $parts);
while($parts) {
   $value = array(array_pop($parts) => $value);
}

print_r($parts);

Sicuramente riscrivilo in modo che abbia il controllo degli errori.

La risposta di Gumbo sembra buona.

Tuttavia, sembra che tu voglia analizzare un tipico file .ini.

Valuta di usare il codice della libreria invece di creare il tuo.

Ad esempio, Zend_Config gestisce questo tipo piacevolmente.

Mi piace molto la risposta di JasonWolf a questo.

Per quanto riguarda i possibili errori: sì, ma ha fornito un'ottima idea, ora spetta al lettore renderlo a prova di proiettile.

Il mio bisogno era un po 'più semplice: da un elenco delimitato, creare un array MD. Ho leggermente modificato il suo codice per darmi proprio questo. Questa versione fornisce un array con o senza una stringa di definizione o anche una stringa senza il delimitatore.

Spero che qualcuno possa renderlo ancora migliore.

$parts = "config.debug.router.strictMode";

$parts = explode(".", $parts);

$value = null;

while($parts) {
  $value = array(array_pop($parts) => $value);
}


print_r($value);
// The attribute to the right of the equals sign
$rightOfEquals = true; 

$leftOfEquals = "config.debug.router.strictMode";

// Array of identifiers
$identifiers = explode(".", $leftOfEquals);

// How many 'identifiers' we have
$numIdentifiers = count($identifiers);


// Iterate through each identifier backwards
// We do this backwards because we want the "innermost" array element
// to be defined first.
for ($i = ($numIdentifiers - 1); $i  >=0; $i--)
{

   // If we are looking at the "last" identifier, then we know what its
   // value is. It is the thing directly to the right of the equals sign.
   if ($i == ($numIdentifiers - 1)) 
   {   
      $a = array($identifiers[$i] => $rightOfEquals);
   }   
   // Otherwise, we recursively append our new attribute to the beginning of the array.
   else
   {   
      $a = array($identifiers[$i] => $a);
   }   

}

print_r($a);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top