Visualizzazione dei risultati da 1 a 8 su 8
  1. #1
    Utente di HTML.it
    Registrato dal
    Feb 2003
    Messaggi
    698

    Ciclo foreach sembra corrompere un array

    Come da topic, codice:

    Codice PHP:
      // Questa linea stampa correttamente l'array, gli elementi sono visualizzati nell'ordine atteso
      
    print "<pre>";print_r($players);print("</pre>");
      
      foreach (
    $players as $p)
      {
        
    $pass serialize($p['pass']);
        
        
        
    $data explode('-',$p['data']);
        list(
    $y,$m,$d) = $data;
        
    $data mktime(0,0,0$m$d$y);
        
       
        
        
    $insert .= "(".$p['pid'].",0,'".mysql_escape_string($p['nome'])."','".mysql_escape_string($p['cognome'])."',$data,'m',".$p['altezza'].",".$p['peso'].",'".$passaporto."',".$p['posizione'].",''),";
        
        
      }
      
      
    // Questa linea stampa l'array evidenziando un errore nell'ultimo elemento, che è stato sovrascritto con una copia del penunltimo.
      
    print "<pre>";print_r($players);print("</pre>");die(); 
    Il problema è segnalato nel codice, nei commenti: in sintesi io stampo un array prima di un ciclo foreach, e il suo contenuto è corretto; lo stampo subito dopo (senza manipolare alcun elemento) ed il suo contenuto è scombinato.

    La cosa curiosa è che commentando tutto il codice del foreach il problema continua a manifestarsi, cioè il solo scorrere gli elementi causa il problema. Ho risolto utilizzando l'alias $p per riferimento ( &$p). Se faccio cosi tutto torna a funzionare.

    Quello che va detto è che prima di questa porzione di codice avevo gia ciclato sullo stesso array utilizzando l'alias come riferimento..anche se questo continua a non spiegarmi del tutto il comportamento anomalo, mi da solo un indizio per attribuire le cause a qualcosa

    Mi sembra di ricordare che ci fosse qualche problema legato a questo tipo di situazioni..ma proprio non mi viene in mente

    E' un bug noto, oppure qualcuno sa spiegarmi cosa succede?

    Grazie!

  2. #2
    Difficile dire senza poter testare i dati reali, puoi postare il contenuto di $players? O un pezzo di codice completo che riproduca il problema?

  3. #3
    Utente di HTML.it
    Registrato dal
    Feb 2003
    Messaggi
    698
    Codice PHP:

    $players 
    = array ('uno','due','tre','quattro');

    foreach (
    $players as &$p) {}

    // Questa linea stampa correttamente l'array, gli elementi sono visualizzati nell'ordine atteso
      
    print "<pre>";print_r($players);print("</pre>");
      
      foreach (
    $players as $p)
      {
        
    $pass serialize($p['pass']);
        
        
        
    $data explode('-',$p['data']);
        list(
    $y,$m,$d) = $data;
        
    $data mktime(0,0,0$m$d$y);
        
       
        
        
    $insert .= "(".$p['pid'].",0,'".mysql_escape_string($p['nome'])."','".mysql_escape_string($p['cognome'])."',$data,'m',".$p['altezza'].",".$p['peso'].",'".$passaporto."',".$p['posizione'].",''),";
        
        
      }
      
      
    // Questa linea stampa l'array evidenziando un errore nell'ultimo elemento, che è stato sovrascritto con una copia del penunltimo.
      
    print "<pre>";print_r($players);print("</pre>");die(); 
    Questo stamperà :

    codice:
    Array
    (
        [0] => uno
        [1] => due
        [2] => tre
        [3] => tre
    )

  4. #4
    Utente di HTML.it
    Registrato dal
    Feb 2003
    Messaggi
    698
    La cosa in effetti si può riassumere cosi:

    Codice PHP:

      $players 
    = array ('uno','due','tre','quattro');

      foreach (
    $players as &$p) {}

      
    // Questa linea stampa correttamente l'array, gli elementi sono visualizzati nell'ordine atteso
      
    print "<pre>";print_r($players);print("</pre>");
      
      foreach (
    $players as $p) { }
      
      
    // Questa linea stampa l'array evidenziando un errore nell'ultimo elemento, che è stato sovrascritto con una copia del penunltimo.
      
    print "<pre>";print_r($players);print("</pre>");die(); 

  5. #5
    Ah ok, ora ho capito. Quello che succede e' questo: tu nel primo ciclo "colleghi" la variabile $p ad un valore dell'array. Finito il ciclo, $p punta all'ultimo valore. Nel secondo ciclo invece usi $p "normalmente", cioe' sovrascrivi il suo valore senza modificare l'elemento a cui $p e' collegato, in questo modo ogni volta che assegni qualcosa a $p, quel qualcosa finisce nell'ultima cella dell'array (perche' e' li' che il primo ciclo l'ha lasciato).

    Quando esegui il secondo ciclo, e' come se tu mettessi il valore di ogni elemento dell'array nell'ultima casella dell'array stesso, quindi l'array assume questi valori:

    codice:
    (uno)(due)(tre)(uno)
      \--------------/
    (uno)(due)(tre)(due)
           \---------/
    (uno)(due)(tre)(tre)
                \----/
    (uno)(due)(tre)(tre)
                    \/
    Non so se mi sono spiegato bene, mi sembrava molto piu' semplice prima di scriverlo

    Comunque, soluzione rapida: se proprio devi usare una reference nel primo, usa un altro indice nel secondo ciclo.

  6. #6
    Utente di HTML.it
    Registrato dal
    Feb 2003
    Messaggi
    698
    Uhm ho capito cosa vuoi dire, ma non sono del tutto convinto

    Cioe i cicli non contengono codice, non sono io a scrivere qualcosa nell'array

  7. #7
    Certo che sei tu

    codice:
    foreach ( $players as $p ) {}
    significa

    codice:
    for ( $x = 0; $x < count($players); $x++ ) {
    	$p = $players[$x];
    }
    solo che l'assegnamento e' implicito e il "codice" e' la dichiarazione stessa del ciclo.

  8. #8
    Utente di HTML.it
    Registrato dal
    Feb 2003
    Messaggi
    698
    Ok ora ci sono, mi mancava la semantica del foreach
    Grazie, prezioso chiarimento!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.