Vai al contenuto

Problema con ciclo While e variabili


magomac

Messaggi raccomandati

Ciao a tutti!

Ho un problemino in php..... ho un form con un numero di campi variabili che viene creato con un ciclo while (ad ogni giro il ciclo stampa un <input type ....) ed il nome di ogni campo del ciclo contiene il contatore.....

Mi spiego meglio.....

il contatore si chiama $i_OK ed ovviamente viene incrementato ad ogni giro.

il nome di ogni campo del form è "pos_$i_OK"

Il tutto funziona, infatti, se guardo il codice della pagina da browser vedo nei vari campi del form, come nome, "pos_1", "pos_2" etc....

Nella pagina che riceve i dati del form ho fatto un altro while con le stesse condizioni di quello che crea il form, con l'unica differenza che, al posto di crearlo, acquisisce i risultati con $_POST....

Il codice è questo:

 
$i_OK=1;
while ($i_OK<=$nOK) {$pos_$i_OK = $_POST['pos_$i_OK'];

$i_OK++;

};

Il grave problema è che non riesco a far si che il nome della variabile che sto creando contenga la variabile contatore!

Ovviamente PHP non mi va a sostituire "$pos_$i_OK" con ad esempio "$pos_1" ma da errore perchè c'è due volte la $ ....

Ho provato tutto ciò che mi veniva in mente, apici non apici, punti non punti etc ma non sono riuscito a risolvere!!!

Sapete aiutarmi??

Grazie ciao

Link al commento
Condividi su altri siti

domanda banale:

ma nel fare il parsing dei campi nel codice php di elaborazione perchè usi n variabili $pos_1_OK, $pos_2_OK eccetera invece di un molto più semplice, comodo e maneggevole array $pos_OK[$i_OK] per memorizzare i risultati del POST?

ti si semplifica di brutto anche il codice:

$pos_OK[$i_OK] = $_POST['pos_$i_OK'];

Serve aiuto? Posso darti una mano in

Webmasters - Aiuto Software - Da Windows a Mac

Mappa Utenti ItaliaMac

[[miao]]

Link al commento
Condividi su altri siti

domanda banale:

ma nel fare il parsing dei campi nel codice php di elaborazione perchè usi n variabili $pos_1_OK, $pos_2_OK eccetera invece di un molto più semplice, comodo e maneggevole array $pos_OK[$i_OK] per memorizzare i risultati del POST?

ti si semplifica di brutto anche il codice:

$pos_OK[$i_OK] = $_POST['pos_$i_OK'];

Non ci avevo pensato....

Cmq $i_OK è il nome della variabile contatore... quindi le n variabili sono poi pos_1 non pos_1_OK...

A parte questo.... ti spiego brevemente a cosa mi serve il tutto.

E' una pagina per inserire i risultati di una regata: nella pagina del form lui via mysql si va a vedere quanti sono gli iscritti e mette tanti campi text (uno per iscritto).

Quini io compilo il form mettendo i numeri velici in ORDINE DI ARRIVO.

La pagina sulla quale sto lavorando dovrebbe prenderli tutti, ho fatto quindi un ciclo while con le stesse condizioni di quello della pagina precedente in modo da sapere quanti sono le variabili che deve acquisire...

A questo punto per ogni numero va a controllare nel db che esista e quindi ristampa la pagina precedente con scritto CORRETTO di fianco ad ogni numero (ERRATO se per caso il numero non esiste).

Quando tutto è corretto invio il form alla pagina di salvataggio che, sempre con lo stesso ciclo, va a mettere le posizioni nel record di ogni partecipante (ad esempio se ITA 100 è arrivato primo lui va ad updattare il suo record e mette 1 nella colonna "provaX") etc..

Con l'array in effetti forse semplificherei...

Mi potresti scrivere esattamente il codice per creare l'array a partire dai dati del form e soprattutto quello per prendere i dati dall'array IN ORDINE?

Grazie

P.S.Visto che cmq ho già scritto tutto il resto del codice senza array, anche se effettivamente non sarà il modo più corretto, c'è modo di far funzionare quelle variabili come le avevo scritte o no?

Come sempre, GRAZIE MILLE!!!

Ciao

Link al commento
Condividi su altri siti

nel modo in cui le intendevi usare, temo non sia possibile perché si crea una ambiguità di codice dovuta al doppio $.

nella programmazione non c'è mai una soluzione unica o univoca, si sceglie di volta in volta in base anche alla propria esperienza e al proprio "stile" di programmazione. per un lavoro come quello che descrivi tu, gli array rappresentano la struttura più adeguata, anche perché consentono di usare metodi per esempio per determinare in un colpo solo la loro dimensione (cosa che nel tuo caso serve) senza dover scrivere codice aggiuntivo solo per dover contare quante sono le variabili in gioco.

Serve aiuto? Posso darti una mano in

Webmasters - Aiuto Software - Da Windows a Mac

Mappa Utenti ItaliaMac

[[miao]]

Link al commento
Condividi su altri siti

beh per esempio se vuoi sapere quante sono le variabili da acquisire c'è un sistema molto più semplice: usare il form come mezzo per trasferire un dato tra due file php differente.

faccio un esempio: tramite il file elenco1.php tu generi il form con tutti gli iscritti e tutti i campi text, uno per iscritto. ma nel php memorizzi anche tramite mysql_num_rows il numero di iscritti, per esempio nella variabile $totaleIscritti. poi nell'output che genera il form fai aggiungere questo tag:

<input type="hidden" name="totaleIscritti" value="$totaleIscritti">

in questo modo quando esegui il POST, il secondo file php, quello che deve elaborare la classifica, può sapere da subito quanti dati aspettarsi senza dover ricorrere a cicli di conteggio:

$totaleDati = $_POST['totaleIscritti'];

a questo punto il ciclo di acquisizione può diventare questo:

$totaleDati = $_POST['totaleIscritti'];

for ($i_OK=0; $i_OK < $totaleDati; $I_OK++) {

$pos_OK[$i_OK] = $_POST['pos_$i_OK'];

....

}

Serve aiuto? Posso darti una mano in

Webmasters - Aiuto Software - Da Windows a Mac

Mappa Utenti ItaliaMac

[[miao]]

Link al commento
Condividi su altri siti

Ciao, inizialmente mi scuso poichè visito il forum molto saltuariamente ma dove sono adesso non ho un comodo accesso a internet...

Cmq ieri sera mi sono messo a fare un po' di esperimenti e sono arrivato a molte delle cose che mi hai detto tu....

Il problema che mi è sorto è questo:

il codice che avevo messo nel primo post era semplificato poichè in realtà le variabili associate ad ogni iscritto sono due: la posizione ed il numero velico.

Questo perchè il form è diviso in due: una parte per raccogliere i numeri velici di quelli arrivati regolarmente (per ogni partecipanti c'è un campo HIDDEN che contiene la posizione (1,2,3 etc) e si chiama "pos" e un campo text per il velico che si chiama "vel").

La seconda parte invece serve a raccogliere i numeri velici di quelli che sono arrivati con una penalità (creando il form il php fa una sottrazione tra il numero degli iscritti e il numero di quelli con penalità in modo da potermi dividere il form...) e ci sono due campi text (sempre "pos" e "vel") perchè, in questo caso, nel campo "pos" devo mettere la sigla della penalità e nel campo vel sempre il numero velico.

Ho provato a documentarmi su internet ma non ho risolto..... come faccio in un array ad associare la variabile "pos" e la variabile "vel" in modo che, in fase di memorizzazione nel database, possa disporre delle due varaibili per me indispensabili?

Grazie mille!

P.S. Una volta creato l'array che ciclo mi conviene usare per estrarne i dati? Grazie

Link al commento
Condividi su altri siti

beh per la penalità io avrei usato una variabile con nome diverso da pos, può sempre venire comodo distinguere le due cose.

un trucco molto semplice per generare un array è questo: ai campi che tu adesso chiami "pos" assegna come nome "pos[0]", "pos[1]" ecc. (questo puoi farlo all'interno del php che genera il primo form tramite un ciclo for o while). idem per "vel".

in pratica avrai un form html che si presenta più o meno così:

Posizione: <input type="text" name="pos[0]">

Num. Velico: <input type="text" name="vel[0]">

Posizione: <input type="text" name="pos[1]">

Num. Velico: <input type="text" name="vel[1]">

ecc.

a questo punto quando elabori la prima form via php il tuo codice può essere scritto in questo modo:

$posizioni = $_POST['pos'];

$numeroVelico = $_POST['vel'];

ma $posizioni e $numeroVelico saranno già degli array in cui

$posizioni[0] = valore del campo pos[0]

$posizioni[1] = valore del campo pos[1] e così via, idem per $numeroVelico

in questo modo ogni elemento dell'array è associato 1:1 con il corrispondente campo della form.

a questo punto, con la normale funzione di array count(), puoi sapere già anche quanti campi contengono $posizioni e $numeroVelico

per l'aggiornamento del db se per esempio usi come entry il numero velico, il ciclo potrebbe essere qualcosa di questo tipo:

$numeroElementi = count($numeroVelico);

for ($i=0; $i<$numeroElementi; $i++) {

$query = "update tabella .... where numeroVelico=$numeroVelico[$i];

...

}

Serve aiuto? Posso darti una mano in

Webmasters - Aiuto Software - Da Windows a Mac

Mappa Utenti ItaliaMac

[[miao]]

Link al commento
Condividi su altri siti

Perfetto! Direi che funziona tutto!

Mi è sorto però un problema alquanto ostico:

La pagina di controllo sulla quale ho lavorato con il ciclo prende tutti i numeri velici dall'array e controlla che esistono.

A quel punto riscrive la classifica e, se il numero esiste, si limita a scriverlo, se invece è errato, rimette il campo di testo.

Ho fatto in oltre una variabile chiamata $risultatoCheck che, se tutti i campi sono corretti ha come valore "OK", se c'è qualche campo errato ha come valore "ERROR".

In teoria la mia idea è far si che, se alla fine di tutti i cicli il valore è OK metta il tasto submit chiamato "Salva" che invia tutti i dati alla pagina che si occupa di fare il salvataggio nel database, se invece il valore è ERROR mette il tasto "Ricontrolla" che rinvia tutto alla stessa pagina in modo che i controlli vengano ripetuti.....

Il problema è questo.

L'apertura del form (<form name...action....>) è all'inizio della pagina mentre il valore della variabile $risultatoCheck viene determinato in seguito, durante i cicli che si occupano anche di ristampare la classifica....

Come faccio quindi a far si che l'attributo ACTION del FORM vari a seconda di una variabili PHP che viene determinata in seguito?????

Spero che ci sia un modo se no sono bloccato!!!

Grazie, ciao!

Link al commento
Condividi su altri siti

soluzione: usi un unico file php nella action del form a cui passi il valore di $risultatoCheck, per esempio tramite un input di tipo hidden

questo file php è sostanzialmente composto in questo modo:

$risultatoCheck= $_POST['risultatoCheck'];
if ($risultatoCheck == OK ) {
   gestione del risultato corretto
  }
else  {
   gestione del risultato errato
  }

Serve aiuto? Posso darti una mano in

Webmasters - Aiuto Software - Da Windows a Mac

Mappa Utenti ItaliaMac

[[miao]]

Link al commento
Condividi su altri siti

secondo me però forse l'impostazione che hai scelto potrebbe essere semplificata in questo modo.

nel php che deve controllare i risultati, disaccoppia la parte di controllo dalla parte di visualizzazione: in fin dei conti, se i risultati sono corretti e devono essere solo salvati, perché rivisualizzarli ancora? e per di più, in questo modo in caso di errori potresti ripresentare solo i campi errati, semplificando la vita a chi deve correggerli.

in pratica la struttura di alto livello del codice potrebbe essere una cosa di questo tipo:

// parte prima: controllo dei dati inseriti
$risultato_OK = OK;
$contaErrori = 0;

$posizione = $_POST['pos'];
$numeroVelico = $_POST['vel'];
$numeroElementi = count($numeroVelico);

for ($i=0; $i<$numeroElementi; $i++) {
   [i]esegue il controllo[/i]
   if ([i]il controllo è errato[/i]) {
        $risultato_OK = KO;
        // memorizza i dati errati nell'array $datoErrato
       $posErrata[$contaErrori] = $posizione[$i];
       $numVelicoErrato[$contaErrori] = $numeroVelico[i];
       $posizioneErrore[$contaErrori] = $i;
       $contaErrori++;
       }
}

// parte seconda: visualizza la form opportuna
if ($risultato_OK == OK) {
   echo "<form action=\"salva.php\">";
   echo "I dati sono corretti, vuoi salvare?";
   [i]trasferisce tutti i valori tramite un input type="hidden"[/i]
   echo "<input type=\"submit\" value=\"Salva\">;
   echo "</form>";
else {
   echo "I dati seguenti risultano errati. Correggili per la corretta inserzione";
   echo "<form action=\"correggi.php\">";
   [i]trasferisce tutti i valori dell'elenco tramite un input type="hidden"[/i]
   for ($i=0; $i<$contaErrori; $i++) {
        // stampa in esplicito solo i campi di input da correggere
       echo "<input type=\"text\" name=\"pos[$posizioneErrore[$contaErrori]]\" value=\"$posErrata[$contaErrori]\">";
       echo "<input type=\"text\" name=\"vel[$posizioneErrore[$contaErrori]]\" value=\"$numeroVelicoErrato[$contaErrori]\">";
       }
   echo "<input type=\"submit\" value=\"Inserisci\">;
   echo "</form>";
 }

In questo modo la form può essere richiamata più volte, in caso di errori ripetuti, fino a quando non ci sono più errori, a ogni passaggio tramite l'uso dei campi "hidden" viene sempre salvato e trasferito l'intero elenco di input.

Serve aiuto? Posso darti una mano in

Webmasters - Aiuto Software - Da Windows a Mac

Mappa Utenti ItaliaMac

[[miao]]

Link al commento
Condividi su altri siti

Ciao. Scusa se sono ritornato sul forum solo oggi ma ho avuto una settimana veramente strana...

Cmq in effetti quello che mi dici non è male però ci sono due cose:

1) Il fatto che me li ripresenti se sono corretti serve per controllare che la classifica digitata sia giusta..... ad esempio per accorgersi se copiando dal cartaceo non si sono invertite due posizioni

2) il fatto che, se c'è qualche campo errato, mi ripresenti tutto è essenziale poichè spesso i fogli da cui copiamo sono fogli di carta dove sono stati appuntati velocemente i numeri in mare.... quindi per poter capire qual'è il numero ertrato bisogna poter vedere quello precedente e quello successivo....

Link al commento
Condividi su altri siti

ok chiaro. in questo caso puoi sempre mantenere l'impostazione di disaccoppiare il controllo dalla visualizzazione come ti ho suggerito perchè questo comunque ti serve per migliorare anche la correzione di eventuali errori.

nel ciclo di controllo puoi memorizzare (come nell'esempio) la posizione (indice dell'array) in cui trovi gli errori. nella parte relativa alla visualizzazione poi nel ciclo che stampa l'elenco puoi anche verificare se l'elemento da stampare contiene o meno degli errori e quindi farlo visualizzare evidenziato, per esempio in rosso o in grassetto, semplificando la vita a chi deve correggere i dati.

Serve aiuto? Posso darti una mano in

Webmasters - Aiuto Software - Da Windows a Mac

Mappa Utenti ItaliaMac

[[miao]]

Link al commento
Condividi su altri siti

Avrei pensato di poter risolvere così:

mantengo le due fasi separate, come mi hai suggerito ma, oltre agli array Velico e Posizione avrei anche bisogno anche di un array Status che contiene in valore OK o ERRORE.

In questo modo tutti i partecipanti continuano ad essere nello stesso array ma grazie a questo terzo valore in fase di stampa posso determinare se quel determinato numero velico e corretto o no.

Mi basta quindi far si che se nell'array Status c'è il valore ERRORE lui all'inizio metta come action la stessa pagina e se no la pagina di salvataggio.

Sembrerebbe funzionare no?

A questo punto.... come faccio a far si che, ad ogni passaggio del ciclo for della prima fase (che mi hai gentilmente scritto), mi vada a mettere questo valore nell'array Status???

Spero di essermi spiegato... Grazie mille!

Link al commento
Condividi su altri siti

secondo me il punto consiste nel tener conto correttamente delle due cose che ti servono:

- un'indicazione generica che ti consenta di stabilire in un colpo solo se sono stati rilevati errori oppure no in modo da scegliere quale action associare alla form

- un'indicazione specifica per ogni record che indichi se in quel record ci sono errori oppure no

da un punto di vista di programmazione, questo si può risolvere in questo modo:

- un flag booleano (variabile singola a due valori possibili) tipo $risultatoErrato che può valere FALSE o TRUE (oppure OK/KO) per l'indicazione generica

- un array associato agli array $posizione e $numVelico che indichi per ogni indice se il risultato corrispondente è corretto o errato.

un esempio di codice potrebbe essere il seguente:

$posizione=$_POST['pos'];
$numeroVelico=$_POST['vel'];
$risultatoErrato = FALSE;
$numeroDati = count($numeroVelico);

// ciclo di controllo
for ($i=0; $i<$numeroDati; $i++) {
    [i]controllo del risultato[/i]
    if ([i]risultato corretto[/i]) {
           recordCorretto[$i] = TRUE;
           }
    else {
           $risultatoErrato = TRUE;
           recordCorretto[$i] = FALSE;
           }
  }

//ciclo di visualizzazione
if ($risultatoErrato == FALSE) {
   echo "<form action=\"salva.php\">";
  }
else
  {
   echo "<form action=\"correggi.php\">";
  }

for ($i=0; $i<$numeroDati; $i++) {
  if (recordCorretto[$i] == FALSE) {
     echo "<strong>!!!  </strong>";
    }
  echo "Pos. <input type =\"text\" name=\"pos[$i]\" value=\"$posizione[$i]\">";
  echo "Num. velico <input type =\"text\" name=\"vel[$i]\" value=\"$numeroVelico[$i]\"> <br />";
}

if ($risultatoErrato == FALSE) {
 echo "<input type=\"submit\" value=\"Salva\">";
 }
else {
 echo "<input type=\"submit\" value=\"Correggi\">";
 }

echo "</form>";

con questo codice in corrispondenza di un errore compariranno tre punti esclamativi in grassetto subito prima dei campi da correggere

Serve aiuto? Posso darti una mano in

Webmasters - Aiuto Software - Da Windows a Mac

Mappa Utenti ItaliaMac

[[miao]]

Link al commento
Condividi su altri siti

Allora..... ho fatto tutto come mi hai indicato e sembra essere perfetto!!!!!!

Solo che adesso mi da uno stranissimo malfunzionamento....

Se c'è qualcuno che ha ricevuto penalità, cioè se la variabile $nPenalty è diversa da zero, non ci sono problemi, il php fa il suo lavoro ed esegue tutti i controlli.

Se invece non ci sono partecipanti con penalità, cioè se la variabile $nPenalty è uguale a zero, i controlli vengono eseguiti perfettamente però del codice HTML vengono prese in considerazione solo le linee dalla 217 in poi!!!!!!!!!!!

Mi accorgo che il php ha funzionato poichè alla fine della pagina c'è il tasto "Salva" o "Ricontrolla" a seconda che io abbia inserito o meno alcuni numeri sbagliati ma....... tutta la grafica e tutte le scritte che ci dovrebbero essere (COMPRESI GLI ECHO DI TUTTI I TAG PHP PRECEDENTI) non si vedono!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Non so assolutamente quale potrebbe essere il problema, non mi è mai capitata una cosa simile! Penso che sia una dimenticanza di qualche parentesi o simili ma ho controllato e ricontrollato il codice e non la trovo!

Visto che non mi sembra problematico incollarti tutto il codice io farei che darti la pagina, forse è più semplice anche per te per aiutarmi.....

GRAZIE MILLE!!!!!!

Pagina in questione: http://andreabenedetti.netsons.org/ProblemaPHP.zip

(nello zip c'è anche un file di testo che contiene il codice visto dal browser....)

Grazie ancora, ciao

Link al commento
Condividi su altri siti

Allora, verificando il codice dalla linea 60 in avanti mi sembra di osservare uno sbilanciamento nella chiusura delle parentesi graffe. Per inciso: le parentesi graffe di chiusura dei blocchi di codice non andrebbero mai seguite dal ;

in effetti manca la graffa di chiusura del blocco "if ($nPenalty !=0)". questo vuol dire che nel caso in cui $nPenalty sia uguale a zero, viene saltato tutto il codice (HTML compreso) fino alla prima graffa di chiusura considerata "utile": che è quella che si trova alla linea 210, perché anche in questo secondo caso nel codice c'è una parentesi graffa di chiusura di troppo.

per verificare la corretta chiusura delle graffe, c'è un trucco molto semplice: conta quante sono le parentesi {, poi conta quante sono le }, se il numero non coincide o c'è una parentesi graffa di apertura in meno o c'è una parentesi graffa di chiusura in più.

ti riporto come secondo me dovrebbe essere la sezione di codice dalla riga 60:

for ($i_OK=1; $i_OK<=$numVel; $i_OK++) {

	$pos_i=$pos[$i_OK];
	$vel_i=$vel[$i_OK];

	if ($vel_i!='') {

		$queryCheck_i="SELECT nome FROM $classe WHERE velicoNum='$vel_i'";
		$esecCheck_i=mysql_query($queryCheck_i) or die(mysql_error());
		$numrisultati=mysql_num_rows($esecCheck_i);


		if ($numrisultati==1) {
           	$recordCorretto[$i_OK] = TRUE;
			$dati_i= mysql_fetch_object($esecCheck_i);
		    $nome_i=$dati_i->nome;
			$nome[$i_OK]=$nome_i;
			}
    		else {
          		$risultatoErrato = TRUE;
          		$recordCorretto[$i_OK] = FALSE;
           	}
 			}
 		}

// ciclo di controllo: 2. Penalizzati
if ($nPenality!=0) {
for ($i_Pen=1; $i_Pen<=$numPen; $i_Pen++) {


		$pen_i=$pen[$i_Pen];
		$velPen_i=$velPen[$i_Pen];

		if ($velPen_i!='') {

			$queryCheck_iPen="SELECT nome FROM $classe WHERE velicoNum='$velPen_i'";
			$esecCheck_iPen=mysql_query($queryCheck_iPen) or die(mysql_error());
			$numrisultati=mysql_num_rows($esecCheck_iPen);

			if ($numrisultati==1) {
           		$recordCorrettoPen[$i_Pen] = TRUE;
				$dati_iPen= mysql_fetch_object($esecCheck_iPen);
			    $nome_iPen=$dati_iPen->nome;
				$nomePen[$i_Pen]=$nome_iPen;
				}
    			else {
          			$risultatoErrato = TRUE;
          			$recordCorrettoPen[$i_Pen] = FALSE;
           		}

		}										

}
}

per la sezione di codice della riga 176, dovrebbe essere sufficiente eliminare una parentesi graffa nella linea 207

Serve aiuto? Posso darti una mano in

Webmasters - Aiuto Software - Da Windows a Mac

Mappa Utenti ItaliaMac

[[miao]]

Link al commento
Condividi su altri siti

Io sul libro di PHP avevo studiato che andavano SEMPRE chiuse con il ;

in realtà non è così perché sintatticamente il ";" termina un'istruzione mentre le parentesi graffe non terminano un'istruzione ma un blocco di istruzioni che sono già terminate di per sè dal ";"

Serve aiuto? Posso darti una mano in

Webmasters - Aiuto Software - Da Windows a Mac

Mappa Utenti ItaliaMac

[[miao]]

Link al commento
Condividi su altri siti

Archiviato

Questa discussione è archiviata e chiusa a future risposte.

×
×
  • Crea Nuovo...