Inserire array in più righe

JackIlPazzo

Utente Attivo
25 Lug 2014
69
0
6
Ciao di nuovo,

sto letteralmente impazzendo per questo problema, sarà che mi si addice al mio nickname :crying:
ora vi spiego la situazione. Ho creato una tabella dinamica, che tramite un codice javascript riesce a far aggiungere o rimuovere delle righe all'interno della medesima. Ogni riga corrisponde ad un prodotto che l'utente inserisce, una specie di workpaper. Ecco come si presenta la mia tabella:

8ttot5oaxbn7bnlfg.jpg

Come potete vedere sono state aggiunte due righe, all'interno delle quali è possibile inserire un prodotto, fornitore, descrizione, quantità e il prezzo. Cliccando su salva, tutti questi dati devono essere inviati ad una tabella MySQL; qui nasce il problema. Io ho creato all'interno delle celle della tabella, dei campi input che catturano array, ecco:

Codice:
input1.name = "prodotto[]";

input2.name = "fornitore[]";

input3.name = "descrizione[]";

input4.name = "quantita[]";

input5.name = "prezzo[]";

Mettiamo il caso che la tabella sia così popolata:

s67fkxlk2zlqbrzfg.jpg

Cliccando su salva dovrebbe arrivarmi nella tabella del DB in questo modo:

r3u9pcaz4vvrhhpfg.jpg

"Questi campi li ho inseriti io a mano". È il risultato che spero di ottenere.

Il codice però non lo fa, di seguito vi riporto il codice che ho creato per eseguire la registrazione nel DB. Come potete vedere in $row mi salvo i campi letti dalla tabella workpaper, poi andando avanti controllo se i dati sono stati inviati da quel form, ed in particolare se è stato premuto il tasto salva; a questo punto valorizzo alcune variabili, ed infine dovrebbero essere inserite nel DB. Tutto questo però non funziona, dapprima mi dice che nel ciclo foreach viene inserito un argomento non valido, poi fa capricci anche sulla variabile $row dandomi che l'index non è definito. A questo punto mi rivolgo a voi 0:)

Codice:
public function esegui_registrazione()
	{
	
	$connection = mysql_connect('localhost', 'root', '');
			
	mysql_select_db('bibliotecaarticoli');
			
	$query = "SELECT * FROM workpaper"; 
			
	$result = mysql_query($query) or die(mysql_error());
			
	$row = mysql_fetch_array($result);
	
	$con = new MySQLi(HOST, USER, PASSWORD, DATABASE);
	
	
		if(isset($_POST['sending']))
		{
			if($_POST['sending'] == "Salva")
			{
				$row_data = array();
				foreach($_POST['sending'] as $key => $value) 
				{ 
					$prodotto=mysqli_real_escape_string($con,($_POST['prodotto'][$row]));
					$fornitore=mysqli_real_escape_string($con,($_POST['fornitore'][$row]));
					$descrizione=mysqli_real_escape_string($con,($_POST['descrizione'][$row]));
					$quantita=mysqli_real_escape_string($con,($_POST['quantita'][$row]));
					$prezzo=mysqli_real_escape_string($con,($_POST['prezzo'][$row]));
					$dipendente=mysqli_real_escape_string($con,($_POST['dipendente'][$row]));
					$row_data[] = "('$prodotto', '$fornitore', '$descrizione','$quantita', '$prezzo', '$dipendente')";
				}
					if (!empty($row_data))
					{
						$sql = 'INSERT INTO workpaper(prodotto,fornitore,descrizione,quantita,prezzo,dipendente) VALUES '.implode(',', $row_data);
						$result = mysqli_query($con, $sql );
						
						if ($result)
						echo 'Inserimento completato: ' . mysqli_affected_rows($con);
						else
						echo 'La query ha fallito' ;
					} 			
			} // if ($_POST['sending'] == "Salva")
		} // if (isset($_POST['sending'])) 
	}//close method
}
 
Ultima modifica:
C'è un po di confusione nel tuo codice, ad esempio apri due connessioni distinte al database tramite le funzioni mysql_ e mysqli_ (e anche la versione ad oggetti), inoltre se ti aspetti che il parametro sending contenga una stringa..
PHP:
if($_POST['sending'] == "Salva")
..non puoi aspettarti che sia anche un array.
PHP:
foreach($_POST['sending'] as $key => $value)

Gli input che vedo nel modulo e che crei dinamicamente sono 5, ma i parametri da inserire sono 6: da dove prendi la colonna "dipendente" ?

Inoltre, sarebbe utile conoscere anche la struttura della tua tabella sul db.
 
C'è un po di confusione nel tuo codice, ad esempio apri due connessioni distinte al database tramite le funzioni mysql_ e mysqli_ (e anche la versione ad oggetti), inoltre se ti aspetti che il parametro sending contenga una stringa..
PHP:
if($_POST['sending'] == "Salva")
..non puoi aspettarti che sia anche un array.
PHP:
foreach($_POST['sending'] as $key => $value)

Gli input che vedo nel modulo e che crei dinamicamente sono 5, ma i parametri da inserire sono 6: da dove prendi la colonna "dipendente" ?

Inoltre, sarebbe utile conoscere anche la struttura della tua tabella sul db.

Ciao grazie per la risposta :)

Allora, diciamo che le connessioni per il momento sono una cosa provvisoria, visto che una la sfrutto tramite una classe che si occupa di gestire le varie configurazioni e l'altra è settata al momento.
Per quanto riguarda il post sending, sarebbe il modulo contenente la tabella generata con tutti i campi da inviare.
Il foreach è sbagliato, ma come ho detto non ho mai gestito il contenuto di array multipli da inviare in tabella con PHP.
Per quanto riguarda dipendente è semplicemente un parametro che prendo dalla sessione non è un array, tramite l'id verifico quale dipendente ha aggiunto quelle informazioni nel workpaper.
Per struttura cosa intendi? Ho inserito l'immagine della tabella workpaper, di lì si vede com'è strutturata.
 
No, lì si vedono i dati presenti nella tabella, io invece sono più interessato a conoscere le definizioni delle colonne (dovrebbe esserci una tab chiamata proprio struttura).

Il valore di sessione invece sai indicarmi qual è?
 
No, lì si vedono i dati presenti nella tabella, io invece sono più interessato a conoscere le definizioni delle colonne (dovrebbe esserci una tab chiamata proprio struttura).

Il valore di sessione invece sai indicarmi qual è?

Ecco la struttura che mi hai chiesto:

Cattura.JPG

Per quanto riguarda il valore di sessione varia in base al dipendente loggato, quando un dipendente viene registrato il sistema assegna un id nella riga tabella corrispondente, l'id è auto increment. Quindi può partire da 1 fino ad un numero indefinito.
 
Pardon, mi riferivo al nome del parametro di sessione in cui archivi quel valore, ma tranquillo.
Ho revisionato un po il tuo codice ma soprattutto ho tolto da mezzo tutte quelle funzioni superflue mysql_ e mysqli_: stai lavorando su un oggetto, di conseguenza ho usato la versione ad oggetti di mysqli.

Per quanto riguarda la sicurezza ho adoperato una query parametrizzata e questo ti rende lo script molto solido contro tentativi di sql injection, sostituendo tutti i real_escape_string.

L'unica cosa che devi fare è aggiornare la variabile del dipendente col valore indicato nei due punti specificati con i commenti che ti ho lasciato.

PHP:
public function esegui_registrazione() {
    #> Avvia la connessione al database
    $MySqli = new mysqli('localhost', 'root', '', 'bibliotecaarticoli');
   
    #> Sono stati inviati dei dati col metodo appropriato ?
    if(isset($_POST['sending']) && $_POST['sending'] == 'Salva') {
        $affectedRows = 0;
        $errors = array();
        
        #> Ok, prepariamo la query di inserimento
        $stmt = $db->prepare(
            "INSERT INTO workpaper (prodotto, fornitore, descrizione, quantita, prezzo, dipendente) 
            VALUES (?, ?, ?, ?, ?, ?)"
            );
        
        #> E specifichiamo i parametri da inserire con la query
        $stmt->bind_param(
            "sssiii", 
            $prodotto, 
            $fornitore, 
            $descrizione, 
            $quantita, 
            $prezzo, 
            $dipendente
            );
        
        #> Scorriamo quindi le righe da salvare
        foreach (array_keys($_POST['prodotto']) as $row) {
            
            #> Valorizziamo i parametri per ogni riga inserita
            $prodotto = $_POST['prodotto'][$row];
            $fornitore = $_POST['fornitore'][$row];
            $descrizione = $_POST['descrizione'][$row]; 
            $quantita = $_POST['quantita'][$row];
            $prezzo = $_POST['prezzo'][$row];
            $dipendente = ;  // Qui devi inserire il parametro di sessione che contiene l'id del dipendente
            
            #> Eseguiamo la query
            if ($stmt->execute()) {
                #> e se riesce, aumentiamo il conteggio delle righe inserite
                $affectedRows += $stmt->affected_rows;
            } else {
                #> Se la query non è riuscita, segniamoci l'indice della riga
                $errors[] = $row;
            }
        }
        
        #> Chiudiamo la preparazione della query che ormai non ci serve più
        $stmt->close();
        
        #> Vediamo quante righe sono state inserite
        echo 'Inserimento completato: ' . $affectedRows;
        
        #> E se ci sono stati degli errori
        if (!empty($errors)) {
            #> Li mostriamo..
            echo "Si sono verificati degli errori durante l'inserimento delle seguenti righe:",
                "<pre>";
            
            #> ..scorrendo gli indici delle righe di cui non è riuscito l'inserimento
            foreach ($errors as $row) {
                echo $_POST['prodotto'][$row], ", ", 
                    $_POST['fornitore'][$row], ", ",
                    $_POST['descrizione'][$row], ", ",
                    $_POST['quantita'][$row], ", ",
                    $_POST['prezzo'][$row], ", ",
                    # Qui devi inserire il parametro di sessione che contiene l'id del dipendente eliminando questo commento
                    , ";\n";
            }
            
            echo "</pre>";
        }
    }
}

Fammi sapere come va ;)
 
Pardon, mi riferivo al nome del parametro di sessione in cui archivi quel valore, ma tranquillo.
Ho revisionato un po il tuo codice ma soprattutto ho tolto da mezzo tutte quelle funzioni superflue mysql_ e mysqli_: stai lavorando su un oggetto, di conseguenza ho usato la versione ad oggetti di mysqli.

Per quanto riguarda la sicurezza ho adoperato una query parametrizzata e questo ti rende lo script molto solido contro tentativi di sql injection, sostituendo tutti i real_escape_string.

L'unica cosa che devi fare è aggiornare la variabile del dipendente col valore indicato nei due punti specificati con i commenti che ti ho lasciato.

PHP:
public function esegui_registrazione() {
    #> Avvia la connessione al database
    $MySqli = new mysqli('localhost', 'root', '', 'bibliotecaarticoli');
   
    #> Sono stati inviati dei dati col metodo appropriato ?
    if(isset($_POST['sending']) && $_POST['sending'] == 'Salva') {
        $affectedRows = 0;
        $errors = array();
        
        #> Ok, prepariamo la query di inserimento
        $stmt = $db->prepare(
            "INSERT INTO workpaper (prodotto, fornitore, descrizione, quantita, prezzo, dipendente) 
            VALUES (?, ?, ?, ?, ?, ?)"
            );
        
        #> E specifichiamo i parametri da inserire con la query
        $stmt->bind_param(
            "sssiii", 
            $prodotto, 
            $fornitore, 
            $descrizione, 
            $quantita, 
            $prezzo, 
            $dipendente
            );
        
        #> Scorriamo quindi le righe da salvare
        foreach (array_keys($_POST['prodotto']) as $row) {
            
            #> Valorizziamo i parametri per ogni riga inserita
            $prodotto = $_POST['prodotto'][$row];
            $fornitore = $_POST['fornitore'][$row];
            $descrizione = $_POST['descrizione'][$row]; 
            $quantita = $_POST['quantita'][$row];
            $prezzo = $_POST['prezzo'][$row];
            $dipendente = ;  // Qui devi inserire il parametro di sessione che contiene l'id del dipendente
            
            #> Eseguiamo la query
            if ($stmt->execute()) {
                #> e se riesce, aumentiamo il conteggio delle righe inserite
                $affectedRows += $stmt->affected_rows;
            } else {
                #> Se la query non è riuscita, segniamoci l'indice della riga
                $errors[] = $row;
            }
        }
        
        #> Chiudiamo la preparazione della query che ormai non ci serve più
        $stmt->close();
        
        #> Vediamo quante righe sono state inserite
        echo 'Inserimento completato: ' . $affectedRows;
        
        #> E se ci sono stati degli errori
        if (!empty($errors)) {
            #> Li mostriamo..
            echo "Si sono verificati degli errori durante l'inserimento delle seguenti righe:",
                "<pre>";
            
            #> ..scorrendo gli indici delle righe di cui non è riuscito l'inserimento
            foreach ($errors as $row) {
                echo $_POST['prodotto'][$row], ", ", 
                    $_POST['fornitore'][$row], ", ",
                    $_POST['descrizione'][$row], ", ",
                    $_POST['quantita'][$row], ", ",
                    $_POST['prezzo'][$row], ", ",
                    # Qui devi inserire il parametro di sessione che contiene l'id del dipendente eliminando questo commento
                    , ";\n";
            }
            
            echo "</pre>";
        }
    }
}

Fammi sapere come va ;)

Allora, ho modificato come hai detto, però ottengo questi errori:

Notice: Undefined variable: db in C:\xampp\htdocs\system\workpaper.php on line 104

Fatal error: Call to a member function prepare() on a non-object in C:\xampp\htdocs\system\workpaper.php on line 104

Questa è la riga incriminata:

Codice:
 $stmt = $db->prepare

Cosa può essere?
 
Occhio, mi sono lasciato sfuggire una piccola distrazione.

Questo pezzo:
PHP:
#> Ok, prepariamo la query di inserimento
$stmt = $db->prepare(
va sostituito così:
PHP:
#> Ok, prepariamo la query di inserimento
$stmt = $MySqli->prepare(
 
Occhio, mi sono lasciato sfuggire una piccola distrazione.

Questo pezzo:
PHP:
#> Ok, prepariamo la query di inserimento
$stmt = $db->prepare(
va sostituito così:
PHP:
#> Ok, prepariamo la query di inserimento
$stmt = $MySqli->prepare(

Incredibile, sei un genio!!
Era da una settimana che ci perdevo tempo e ora grazie a te, ho risolto il problema! Ti ringrazio davvero tanto, ora mi studio un po' la tua soluzione. Grazie, grazie, grazie!!
Ti auguro una buona giornata!! Grazie ancora :elvis:
 

Discussioni simili