Newsgroup: it.comp.www.php
Titolo: riferimenti su array

Ciao a tutti,
ho la necessità di inserire delle key su un'array multidimensionale creato in run-time.
Dovrei quindi, di volta in volta, salvare su una variabile il riferimento del 'livello' cui sono all'interno del mio array
multidimensionale.
Ma, provando e riprovando sembra non sia possibile o (spero!) non sono ancora arrivato alla giusta soluzione.
Vi posto due blocchi di codice che 'dovrebbero' ottenere lo stesso risultato.
Il primo blocco ritorna il risultato corretto
<?
$arr = array();
$c = "aa";
$arr[$c] = array();
$r = "ee";
$arr[$c][$r] = array();
$f = "rr";
$arr[$c][$r][$f] = 1;
print_r($arr);
/* result
 Array ( [aa] => Array ( [ee] => Array ( [rr] => 1 ) ) )
*/
?>
il secondo invece si ferma esattamente allo stesso punto in cui salvo in una variabile il 'livello' attuale dell'array, e lo tratta
quasi come un nuovo elemento.
<?
$arr = array();
$c = "aa";
$arr[$c] = array();
$arrb = $arr[$c];
$r = "ee";
$arrb[$r] = array();
$arrc = $arrb[$r];
$f = "rr";
$arrc[$f] = 1;
print_r($arr);
/* result
 Array ( [aa] => Array ( ) )
*/
?>
boh? non so proprio come procedere ed è tutta la giornata che mi continuo a sfogliare 
php.net
 alla ricerca di una soluzione, ma
nada.
grazie
-- 
Sousa - 
http://laBoratorio.sousa.it/

  Array ( [aa] => Array ( ) )
Ma è giusto.
$arr è un array che ha un solo indice "aa" che è un array. Gli altri array non sono altro che copie di array, tu gli passi il valore. 
Non sono molto azzeccato con i riferimenti ma forse dovresti fare una cosa del genere:
$arrb = & $arr[$c];
ma non son sicuro...
CIAO


Prova così:
<?php
$arr = array();
$c = "aa";
$arr[$c] = array();
$arrb =& $arr[$c];
$r = "ee";
$arrb[$r] = array();
$arrc =& $arrb[$r];
$f = "rr";
$arrc[$f] = 1;
print_r($arr);
/* result
  Array ( [aa] => Array ( [ee] => Array ( [rr] => 1 ) ) )
*/
?>
La spiegazione è semplice. Quando scrivi $arrb = $arr[$c]; in realtà 
$arrb conterrà una copia del valore della variabile $arr[$c] e non un 
riferimento ad essa. Per il riferimento devi scriver $arrb =& $arr[$c];

grazie ad entrambi per la risposta.
In effetti il riferimento avviene usando il =&.
Putroppo il problema persiste, nel senso che nella funzione che sto sviluppando mi riesce riferire l'array ma non mi permette di
aggiungere una key.
function searchPosition($argsArray,$riga)
 {
  // esplodo la riga
  $row = explode("|",$riga);
  // ne prendo il primo record, il codice di riferimento al padre
  $actMachine = $this->estraiPadre($row);
  // ed il terzo, corrispondente al figlio..
  $actFiglio = $this->estraiFiglio($row);
  // creo un ciclo per trovare la parola chiave corrispondente al padre
  foreach ($argsArray as $key => $value)
  {
   // se la trova
   if ($actMachine==$key)
   {
    // se non è già presente l'array della lista lo setto
    if (!isset($argsArray[$key]))
    {
     $argsArray[$key] = array();
    }
    $refer =& $argsArray[$key];
    if (!isset($refer[$actFiglio]))
    {
     $refer[$actFiglio] = array();
     print_r($argsArray);
    }
    // ed aggiungo i records alla riga
    $actRow = $this->parseDistinta($riga);
    array_push($refer[$actFiglio],$actRow);
   }
   else
   {
    // controllo se l'attuale chiave è array e se lo è ne ripeto la ricerca
    if (is_array($argsArray[$key]))
    {
     $this->searchPosition($argsArray[$key],$riga);
    }
   }
  }
 }
facendo un print_r dell'array principale alla fine della funzione, scopro che non è stata aggiunta alcuna chiave (che è un'altro
array) nell'array principale.
se invece faccio un print_r al momento dell'aggiunta della chiave mi da l'array principale con la chiave appena inserita.
$refer[$actFiglio] = array();
print_r($argsArray);
E' come se ogni volta mi vada a sovrascrivere la chiave.


 
non capisco quale è il tuo problema..
<?
error_reporting(E_ALL);
$a = 'aa';
$e = 'ee';
$r = 'rr';
$arr[$a][$e][$r] = 1;
print_r($arr);
/* result
  Array ( [aa] => Array ( [ee] => Array ( [rr] => 1 ) ) ) 
*/
?>
-- 
www.iuz-lab.info

 
se spieghi meglio il problema magari posso aiutarti intanto prova questo
codice..
<?
error_reporting(E_ALL);
$a = 'aa';
$e = 'ee';
$r = 'rr';
$arr[$a][$e][$r] = 1;
print_r($arr);
echo '<br />';
// percorre tutta la lista multidimensionale del tipo array => array =>
array => 1 puntando in $pointer ad ogni iterazione il prossimo 'livello'
$pointer = & $arr;
while(is_array($pointer)){
        echo "puntatore a: " . key($pointer) . "<br />";
        $pointer = & $pointer[key($pointer)];
}
?>
-- 
www.iuz-lab.info

grazie iuz, provo a spiegarti questo tarlo che mi sta rodendo il fegato.. :)
su un file esterno ho una lista composta da più righe a sua volta composte di dati separati da pipe.
questi dati corrispondono ad una lista delle parti di una o più macchine in cui alcuni pezzi sono figli di altri.
Io devo ricreare la struttura gerarchica di questa lista parti in un'array multidimensionale.
la lista (in cui il secondo record rappresenta la macchina/pezzo padre ed il quarto il pezzo figlio) è così composta:
1D4010|80B080000|000010|B08960003|C8|||00000002,0000|||||03/11/2004
1D4010|80B080000|000020|B08975002|P6|||00000002,0000|||||03/11/2004
1D4010|80B080000|000030|B08998000|A3|||00000024,0000|||||03/11/2004
1D4010|B08998000|000010|B08970001|P4|||00000024,0000|||||03/11/2004
1D4010|B08998000|000200|999700031||||00000024,0000|||||03/11/2004
1D4010|80B080000|000040|B08970000|P4|||00000024,0000|||||03/11/2004
Allora mi son scritto una classe per farlo che prima di tutto mi trova le macchine e le salva come array dentro l'array principale
delle macchine ($arrMacchine).
La macchina corrisponde alla key dell'array, ad esempio
$arrMacchine = array( [80B080000]=>array(), ... , ...)
poi riapro il file e faccio il parsing delle righe (naturalmente prima divise) associando le varie parti alle varie macchine e
ricreando la gerarchia creando un'array per ogni parte che poi verrà riempita con le eventuale sotto parti
ad esempio
$arrMacchine = array
                                ( [80B080000]=>array
                                                                    ([B08960003]=>array(),
                                                                      [B08998000]=>array
                                                                                                        ( [B08970001]=>array(),
                                                                                                          [B08970001]=>array()
                                                                                                         ),
                                                                      ),
                                    ... ,
                                    ...
                                 );
il problema persiste nella funzione searchPosition() che mi dovrebbe fare ciò, ma di fatto quando creo gli array su quello
principale non lo fa. se faccio un print_r dell'array al ciclo, mi ritorna l'array principale
Array ( [80B080000] => Array ( ) )
con l'attuale array aggiunto
Array ( [80B080000] => Array ( [B08960003] => Array ( ) ) )
Array ( [80B080000] => Array ( [B08975002] => Array ( ) ) )
ma non con tutti gli altri aggiunti prima.
In parole povere alla fine dell'operazione mi ritrovo con l'array iniziale, come non fosse mai stato elaborato.
Pensavo fosse una questione di riferimenti all'array, ma ho provato con le soluzioni postate ed il risultato è sempre quello.
class Commessa
{
    var $arrMacchine;
// funzione di inizializzazione
    function Commessa($mainFile)
    {
          $this->arrMacchine = $this->estraiMacchine($mainFile);
          $this->dividiRighe($mainFile);
    }
// INIZIO funzione di estrazione delle macchine
function estraiMacchine($file)
 {
  $distinta = fopen($file,"r");
  $contents = fread($distinta, filesize($file));
  $parti = explode("\n",$contents);
  $tmparray = array();
  $keysarray = array();
  for ($i=0;$i<count($parti);$i++)
  {
   $thereIs = false;
   $row = explode("|",$parti[$i]);
   $actMachine = $row[1];
   $actFiglio = $row[3];
   $keysarray[$actFiglio] = 1;
   if (!array_key_exists($actMachine,$tmparray))
   {
    $tmparray[$actMachine] = array();
   }
  }
  fclose($distinta);
  // controllo che le macchine salvate non siano in realtà delle parti di questa
  foreach ($keysarray as $key => $value)
  {
   if (array_key_exists($key,$tmparray))
   {
    unset($tmparray[$key]);
   }
  }
  return $tmparray;
 }
// FINE funzione di estrazione macchine
// INIZIO funzione per la divisione delle righe della lista parti
function dividiRighe($file)
 {
  $distinta = fopen($file,"r");
  $contents = fread($distinta, filesize($file));
  $parti = explode("\n",$contents);
  for ($i=0;$i<count($parti);$i++)
  {
   $this->searchPosition($this->arrMacchine,$parti[$i]);
  }
  fclose($distinta);
 }
// FINE funzione per la divisione delle righe della lista parti
function searchPosition($argsArray,$riga)
 {
  // esplodo la riga
  $row = explode("|",$riga);
  // ne prendo il primo record, il codice di riferimento al padre
  $actMachine = $row[1];
  // e quello al figlio..
  $actFiglio = $row[3];
  // creo un ciclo per trovare la parola chiave corrispondente al padre
  foreach ($argsArray as $key => $value)
  {
   // se la trova
   if ($actMachine==$key)
   {
    // se non è già presente l'array della lista lo setto
    if (!isset($argsArray[$key]))
    {
     $argsArray[$key] = array();
    }
    //$refer =& $argsArray[$key];
    if (!isset($refer[$actFiglio]))
    {
     $argsArray[$key][$actFiglio] = array();
    }
    // ed aggiungo i records alla riga
    $actRow = $this->parseDistinta($riga);
    array_push($argsArray[$key][$actFiglio],$actRow);
   }
   else
   {
    // controllo se l'attuale chiave è array e se lo è ne ripeto la ricerca
    if (is_array($argsArray[$key]))
    {
     $this->searchPosition($argsArray[$key],$riga);
     echo $key;


trovato l'inghippo.
di volta in volta devo ritornare il nuovo array e sovrascriverlo a quello esistente
function dividiRighe($file)
 {
  $distinta = fopen($file,"r");
  $contents = fread($distinta, filesize($file));
  $parti = explode("\n",$contents);
  for ($i=0;$i<count($parti);$i++)
  {
   $this->arrMacchine = $this->searchPosition($this->arrMacchine,$parti[$i]);
  }
  fclose($distinta);
 }
function searchPosition($argsArray,$riga)
 {
  // esplodo la riga
  $row = explode("|",$riga);
  // ne prendo il primo record, il codice di riferimento al padre
  $actMachine = $this->estraiPadre($row);
  // e quello al figlio..
  $actFiglio = $this->estraiFiglio($row);
  // creo un ciclo per trovare la parola chiave corrispondente al padre
  foreach ($argsArray as $key => $value)
  {
   if ($actMachine==$key)
   {
    // se non è già presente l'array della lista lo setto
    if (!isset($argsArray[$key]))
    {
     $argsArray[$key] = array();
    }
    if (!isset($refer[$actFiglio]))
    {
     $argsArray[$key][$actFiglio] = array();
    }
   }
   else
   {
    // controllo se l'attuale chiave è array e se lo è ne ripeto la ricerca
    if (is_array($argsArray[$key]))
    {
     $argsArray[$key] = $this->searchPosition($argsArray[$key],$riga);
    }
    else
    {
     $argsArray[$key][$actFiglio] = array();
    }
   }
  }
  return $argsArray;
 }
-- 
Sousa - 
http://laBoratorio.sousa.it/
"Sousa" <no-...@laBoratorio.sousa> ha scritto nel messaggio news:cnhs5k$fic$1...@newsread.albacom.net...


 
attento, procedendo così sprechi molte risorse.. prova a passare un
puntatore, altrimenti se il file da parsare non è di piccole dimensioni
rischi di sovraccaricare il server..
-- 
www.iuz-lab.info

 attento, procedendo cosě sprechi molte risorse.. prova a passare un puntatore,
[..]
intendi un riferimento all'array principale? non mi funziona se faccio riferimento a quello, ho provato in mille modi ma non
funge...
o intendi altro?


 
intendo quello.. mi dispiace solo che non ho tempo per leggere tutto il
codice che hai postato, ti vorrei aiutare..
ma posso chiederti perchè non usi un DB?
e mi potresti dare dieci righe di esempio del file input e il relativo array
finale che vorresti ottenere..
-- 
www.iuz-lab.info

 finale che vorresti ottenere..
1D4010|80B080000|000010|B08960003|C8|||00000002,0000|||||03/11/2004
1D4010|80B080000|000020|B08975002|P6|||00000002,0000|||||03/11/2004
1D4010|80B080000|000030|B08998000|A3|||00000024,0000|||||03/11/2004
1D4010|B08998000|000010|B08970001|P4|||00000024,0000|||||03/11/2004
1D4010|B08998000|000200|999700031||||00000024,0000|||||03/11/2004
1D4010|999700031|000010|B08970051|P4|||00000024,0000|||||03/11/2004
1D4010|999700031|000200|999700051||||00000024,0000|||||03/11/2004
1D4010|999700051|000200|999700061||||00000024,0000|||||03/11/2004
1D4010|80B080000|000040|B08970000|P4|||00000024,0000|||||03/11/2004
1D4010|80B080000|000050|B08316005|D1|||00000024,0000|||||03/11/2004
il secondo record sta a rappresentare il padre, il quarto il figlio
l'array che ho ottenuto parsando i dati tramite la seguente funzione
function searchPosition($argsArray,$riga)
 {
  // esplodo la riga
  $row = explode("|",$riga);
  // ne prendo il primo record, il codice di riferimento al padre
  $actMachine = $this->estraiPadre($row);
  // e quello al figlio..
  $actFiglio = $this->estraiFiglio($row);
  // creo un ciclo per trovare la parola chiave corrispondente al padre
  foreach ($argsArray as $key => $value)
  //for ($j=0;$j<count($argsArray);$j++)
  {
   // se la trova
   //$key = key($argsArray);
   if ((string)$actMachine==(string)$key)
   {
    // se non è già presente l'array della lista lo setto
    if (!isset($argsArray[$key]))
    {
     $argsArray[$key] = array();
    }
    if (!isset($refer[$actFiglio]))
    {
     $argsArray[$key][$actFiglio] = array();
    }
    // ed aggiungo i records relativi alla parte riconoscibili tramite key "rootparams"
    $actRow = array("figlio" => $actFiglio);
    $argsArray[$key][$actFiglio]["rootparams"] = $actRow;
   }
   else
   {
    // controllo se l'attuale chiave è array e se lo è ne ripeto la ricerca
    // altrimenti la funzione termina
    if (is_array($argsArray[$key]))
    {
     $argsArray[$key] = $this->searchPosition($argsArray[$key],$riga);
    }
   }
  }
  return $argsArray;
 }
è questo
Array ( [80B080000] => Array (
                                                    [B08960003] => Array ( [rootparams] => Array ( [figlio] => B08960003 ) )
                                                    [B08975002] => Array ( [rootparams] => Array ( [figlio] => B08975002 ) )
                                                    [B08998000] => Array ( [rootparams] => Array ( [figlio] => B08998000 )
                                                                        [B08970001] => Array ( [rootparams] => Array ( [figlio] =>
B08970001 ) )
                                                                        [999700031] => Array ( [rootparams] => Array ( [figlio] =>
999700031 )
                                                                                            [B08970051] => Array ( [rootparams] =>
Array ( [figlio] => B08970051 ) )
                                                                                            [999700051] => Array ( [rootparams] =>
Array ( [figlio] => 999700051 )
                                                                                                                [999700061] => Array
( [rootparams] => Array ( [figlio] => 999700061 ) ) ) ) )
                                                    [B08970000] => Array ( [rootparams] => Array ( [figlio] => B08970000 ) )
                                                    [B08316005] => Array ( [rootparams] => Array ( [figlio] => B08316005 ) )  ) )
in realtà l'array multidimensionale mi serve successivamente per rielaborarlo come xml in cui la struttura gerarchica dei dati
corrisponde a quella gerarchica della lista parti delle varie macchine.
in questo caso la struttura diventa
    <?xml version="1.0" encoding="iso-8859-1"?>
    <node label="cliente" commessa="1D4010">
        <node label="80B080000">
            <node label="B08960003"/>
            <node label="B08975002"/>
            <node label="B08998000">
            <node label="B08970001"/>
                <node label="999700031">
                    <node label="B08970051"/>
                    <node label="999700051">
                        <node label="999700061"/>
                    </node>
                </node>
            </node>
            <node label="B08970000"/>
            <node label="B08316005"/>
        </node>
    </node>
sono riuscito a ricreare l'array come struttura, creare l'XML etc. ma son sempre disposto (e felice) a rivedere il codice se mi dici
che lo si può ottimizzare.
grazie ciao


 
mi sono strippato un'pò per scriverlo però funziona..
(spero che leggerai altrimenti apro un altro thread..)
naturalmente file.txt contiene le dieci righe che mi hai fornito per il
testing.. (e lo script risponde bene)..
<?php
$ch = fopen('file.txt', 'r');
$p_list = $result = array();
while(FALSE !== ($line = fgets($ch))){
        list(, $father, , $current) = explode('|', $line, 5);
        if(!isset($p_list[$father])){
                $result[$father] = array();
                $p_list[$father] =& $result[$father];
                $p_list[$father][$current] = array();
        }
        else{
                $p_list[$father][$current] = array();
                $p_list[$current] =& $p_list[$father][$current];
 
        }
}
function print_xml_result($array){
        while(list($label, $subarray) = each($array)){
                if(count($subarray) < 1){
                        echo "<node label='$label'/>\n";
                }
                else{
                        echo "<node label='$label'>\n";
                        print_xml_result($subarray);
                        echo "</node>\n";
                }
        }
}
print_xml_result($result);
?>
-- 
www.iuz-lab.info

tranquillo, il thread è sempre in cima alla lista :)
quel che si dice far le cose fatte bene!
Devo dire che la differenza di velocità (e conseguente spreco di risorse) dal mio script è a dir poco impressionante :).
grazie iuz, e a buon rendere


 
di niente.. e grazie a te..
-- 
www.iuz-lab.info