Iterazione array

MarcoGrazia

Utente Attivo
15 Dic 2009
852
20
28
62
Udine
www.stilisticamente.com
Ciao, ho un array multidimensionale a lunghezza variabile che definisce l'indice di un libro.
E' formato da tra Array: voce, dallaPagina, allaPagina e devo iterarlo.

l'Array:
Codice:
$target = [
  'Voce' => [
      1 => string 'Capitolo 1' (length=10)
      2 => string 'Capitolo 2' (length=10)
      3 => string 'Capitolo 3' (length=10)
  ],
  'DallaPagina' => [
      1 => string '1' (length=1)
      2 => string '99' (length=2)
      3 => string '151' (length=3)
  ],
  'AllaPagina' => [
      1 => string '98' (length=2)
      2 => string '150' (length=3)
      3 => string '160' (length=3)
   ]
]

Il tutto va iterato per inserirlo in un record di database ed avevo pensato di fare una cosa del genere:
PHP:
            $sql = 'INSERT INTO indici ';
            $sql .= '(libro_id, voce, dalla_pagina, alla_pagina) ';
            $sql .= 'VALUES (:idI, :v, :dp, :ap); --';
            $handle = $pdo->prepare($sql);
            $index = 1;
            $idFascicolo = 3;
            try {
                //    Inserimento selettivo delle voci
                $pdo->beginTransaction();
                foreach( $target as $t ) {

                    $handle->bindValue(':idI', $idFascicolo, PDO::PARAM_INT);
                    $handle->bindValue(':v', $t['Voce'][$index], PDO::PARAM_STR);
                    $handle->bindValue(':dp', $t['DallaPagina'][$index], PDO::PARAM_STR);
                    $handle->bindValue(':ap', $t['AllaPagina'][$index], PDO::PARAM_STR);
                    $handle->execute();
                    
                    $index++;
                }
                $pdo->commit();
                unset( $pdo, $handle, $sql, $target );
            }
            catch( PDOException $err ) {
                $pdo->rollback();
                throw $err;
            }
ma il sistema mi da errori: Notice: Trying to access array offset on value of type int in C:\Apache\users\marco\moduli-2\putVoci.php on line 105 dove la riga 105 nel mio listato corrisponde all'istruzione: $handle->bindValue(':v', $t['cellaVoce'][$index], PDO::pARAM_STR); e così via per le altre due chiavi dell'array $target, ovvero le due righe seguenti del Binding sempre lo stesso errore.
Quindi infine: Fatal error: Uncaught PDOException: SQLSTATE[23000]: Integrity constraint violation: 1048 La colonna 'voce' non puo` essere nulla in C:\Apache\users\marco\moduli-2\putVoci.php on line 108 dove la riga 108 corrisponde a $handle->execute();
Che appunto mi fa capire che non ho iterato un bel nulla.
 

WmbertSea

Moderatore
Membro dello Staff
MOD
28 Nov 2014
436
73
28
Ciao, mi pare ci sia un problema di logica.

In quel foreach stai iterando proprio la prima dimensione del vettore $target, per cui il ciclo è eseguito esattamente per quei tre elementi ('Voce', 'DallaPagina' e 'AllaPagina'). La variabile $t, ad ogni iterazione, assume rispettivamente il riferimento a $target['Voce'], $target['DallaPagina'] e $target['AllaPagina'], però tu stai già riferendoti specificatamente (e in modo statico) a quegli elementi nel codice dentro il ciclo.

In sostanza, con questo tuo codice:
PHP:
$handle->bindValue(':v', $t['Voce'][$index], PDO::PARAM_STR);
$handle->bindValue(':dp', $t['DallaPagina'][$index], PDO::PARAM_STR);
$handle->bindValue(':ap', $t['AllaPagina'][$index], PDO::PARAM_STR);

alla prima iterazione del ciclo foreach, ottieni un risultato equivalente a questo codice:
PHP:
$handle->bindValue(':v', $target['Voce']['Voce'][1], PDO::PARAM_STR);
$handle->bindValue(':dp', $target['Voce']['DallaPagina'][1], PDO::PARAM_STR);
$handle->bindValue(':ap', $target['Voce']['AllaPagina'][1], PDO::PARAM_STR);

alla seconda iterazione, ottieni questo:
PHP:
$handle->bindValue(':v', $target['DallaPagina']['Voce'][2], PDO::PARAM_STR);
$handle->bindValue(':dp', $target['DallaPagina']['DallaPagina'][2], PDO::PARAM_STR);
$handle->bindValue(':ap', $target['DallaPagina']['AllaPagina'][2], PDO::PARAM_STR);

e così via.

Puoi capire che l'impostazione è sbagliata a livello logico.

Se conosci già a priori la prima dimensione (dal momento che le stesse chiavi le usi staticamente dentro il ciclo), e se la seconda dimensione ha una lunghezza uguale per tutti gli elementi della prima dimensione, puoi iterare solo la seconda dimensione (cioè l'indice) con un semplice for, dove &index parte da 1 e arriva alla lunghezza X (valore che puoi recuperare contando la lunghezza di un qualsiasi elemento della prima dimensione).

Potrebbe essere quindi una cosa del genere:
PHP:
$target = [
  'Voce' => [
      1 =>  'Capitolo 1',
      2 =>  'Capitolo 2',
      3 =>  'Capitolo 3'
  ],
  'DallaPagina' => [
      1 => '1',
      2 => '99',
      3 => '151'
  ],
  'AllaPagina' => [
      1 => '98' ,
      2 => '150',
      3 => '160'
   ]
];

for ($index = 1; $index <= count($target['Voce']); $index++) {

    $handle->bindValue(':idI', $idFascicolo, PDO::PARAM_INT);
    $handle->bindValue(':v', $target['Voce'][$index], PDO::PARAM_STR);
    $handle->bindValue(':dp', $target['DallaPagina'][$index], PDO::PARAM_STR);
    $handle->bindValue(':ap', $target['AllaPagina'][$index], PDO::PARAM_STR);
    $handle->execute();

}

A prescindere dal metodo usato, è essenziale che si riesca a comprendere la logica per ottenere il risultato voluto.

Fai sapere :)
 

MarcoGrazia

Utente Attivo
15 Dic 2009
852
20
28
62
Udine
www.stilisticamente.com
Allora @WmbertSea :

utilizzando un ciclo for in luogo di quello foreach funziona, in effetti ho compreso il motivo per cui non poteva andare nel mio modo, ora però mi si è presentato un altro problema.

Mi registra solo le voci dispari.

Ecco un pezzetto del codice originale dopo le correzioni da te suggerite
PHP:
            $len = count($target['cellaVoce']); echo $len . '<br>';
            try {
                //    Inserimento selettivo delle voci
                $pdo->beginTransaction();
                echo 'Riporto ciclo for:<br>';
                for ( $index = 1; $index <= $len; $index++ ) {
                   
                    $handle->bindValue(':idF', $idFascicolo, PDO::PARAM_INT);
                    $handle->bindValue(':v', $target['cellaVoce'][$index], PDO::PARAM_STR);
                    $handle->bindValue(':dp', $target['cellaDalla'][$index], PDO::PARAM_STR);
                    $handle->bindValue(':ap', $target['cellaAlla'][$index], PDO::PARAM_STR);
                    $handle->execute();
                   
                    echo $index . ') ' . $target['cellaVoce'][$index] . '<br>';
                    $index++;
                }
                $pdo->commit();
                unset( $pdo, $handle, $sql, $target );
            }
            catch( Exception $err ) {
                $pdo->rollback();
                throw $err;
            }

le echo le ho messe per evidenziare le righe effettivamente processate, qui sotto metto il risultato così come viene riportato dall'analizzatore, dati riportati sono ovviamente fittizi anche se è una simulazione reale.
I dati sono passati tramite Ajax al file putVoci.php e qui processati e memorizzati nel database, quello riportato è il var_dump() dell'array $target dopo il filtraggio dei dati.
Come si vede ci sono tutti, ma solo i dispari vengono registrati come riportato in fondo

Codice:
C:\Apache\users\marco\moduli-2\putVoci.php:71:
array (size=7)
  'docElettronica' => null
  'ufficio' => int 1
  'numero' => int 1
  'anno' => int 2022
  'cellaVoce' =>
    array (size=4)
      1 => string 'Nota di iscrizione a ruolo' (length=26)
      2 => string 'Accordo di Negoziazione tra le parti ex lege 162/2014 art. 6' (length=60)
      3 => string 'Provvedimento del PM' (length=20)
      4 => string 'Allegati non catalogabili' (length=25)
  'cellaDalla' =>
    array (size=4)
      1 => string '1' (length=1)
      2 => string '2' (length=1)
      3 => string '9' (length=1)
      4 => string '10' (length=2)
  'cellaAlla' =>
    array (size=4)
      1 => string '*' (length=1)
      2 => string '8' (length=1)
      3 => string '*' (length=1)
      4 => string '*' (length=1)

4
Riporto cicolo for:
1) Nota di iscrizione a ruolo
3) Provvedimento del PM
 
Ultima modifica:

WmbertSea

Moderatore
Membro dello Staff
MOD
28 Nov 2014
436
73
28
Fai attenzione, la variabile $index (che è il cosiddetto contatore del ciclo for) viene incrementata già nella inizializzazione del ciclo, per ogni iterazione che sarà eseguita. Non hai quindi bisogno di incrementarla nuovamente tra le istruzioni interne del ciclo.

RTF (BB code):
for ( $index = 1; $index <= $len; $index++ ) // Il contatore viene già incrementato qui
{
    [...]
    $index++; // Questo va rimosso
}
 

MarcoGrazia

Utente Attivo
15 Dic 2009
852
20
28
62
Udine
www.stilisticamente.com
Fai attenzione, la variabile $index (che è il cosiddetto contatore del ciclo for) viene incrementata già nella inizializzazione del ciclo, per ogni iterazione che sarà eseguita. Non hai quindi bisogno di incrementarla nuovamente tra le istruzioni interne del ciclo.

RTF (BB code):
for ( $index = 1; $index <= $len; $index++ ) // Il contatore viene già incrementato qui
{
    [...]
    $index++; // Questo va rimosso
}
Uh porc.... che resti tra noi :D
era un ciclo creato prima con foreach... va bè capita. o_O
 
Discussioni simili
Autore Titolo Forum Risposte Data
P Iterazione in PHP PHP 8
P Iterazione Foreach dentro un ciclo for PHP 9
otto9due Leggere valore da array multidimensionale a chiavi dinamiche PHP 1
M Passaggio variabili array php su un tasto jq PHP 3
M Somma inversa di Array C/C++ 2
N Passare array da php a javascript PHP 5
G Ordinare un array multidimensionale PHP 4
H Errore su array associativo PHP 1
K Array senza ripetizioni Presentati al Forum 4
A Gestione array multidimensionale PHP 6
otto9due Più chiavi in array con array_key_exists() PHP 0
M Array associativi php su 2 campi mysql PHP 10
T ALTRO PROBLEMA CON ARRAY PHP PHP 1
T PROBLEMA CON ARRAY PHP 8
L Sessione e array per utenti PHP 0
R Importazione csv su mysql tramite array PHP 2
elpirata Ricavare e stampare indirizzo ip da array associativo PHP 0
P Ciclare tra array di oggetti PHP 1
R Raggruppare valori array PHP 5
S Come conoscere la posizione di numeri in un array escludendo i doppioni PHP 4
D Popolare array PHP 8
R Includere elementi array fra apici PHP 1
P Array da foreach PHP 2
N Variabile di sessione è un array PHP7 PHP 3
R Scorporare array e recuperare record tabella PHP 10
A Contare gli elementi di un array PHP 13
A Importare array in mysql PHP 1
A Array di immagini Sviluppo app per Android 10
D Chiave unica in estrazione dati da array php PHP 0
D Spazio vuoto in un elemento di un array php PHP 2
S Come filtrare valori di un array PHP 4
mazman mysqli_query() mi ritorna un array vuoto anche se presente un record nella tabella PHP 13
A Non è un array e nemmeno un intero, che tipo di dato è? Javascript 1
max1974 PHP, Array Multidimensionale e Grafici PHP 22
S [PHP] Confrontare due array con valori quasi uguali PHP 2
MarcoGrazia [PHP] Unioni di due array con somma di valori PHP 6
R [PHP] Visualizzazione dati Array PHP 2
S [PHP] Eliminare doppioni array e rinumerare le posizioni PHP 2
M Importare - Manipolare Json Array Sviluppo app per Android 2
M [PHP] Problemi su inserimento array nel db PHP 7
M [PHP] Visualizzare un array partendo dal numero 1 e non 0 PHP 5
G [ASP] Ciclare i valori di 2 array Classic ASP 2
S [PHP] Estrarre elementi array su più variabili PHP 5
S [PHP] Estrarre dati tabella in diversi array PHP 2
max1974 [PHP] Raggruppare array PHP 4
A [PHP] Caricamento database in array PHP 11
G sql select con array in php PHP 1
L [Java] Aggiungere elementi ad array JSON Java 0
S [PHP] individuare chiave elemento array PHP 7
A [PHP] Script con array con numeri che iniziano per 00 PHP 2

Discussioni simili