[résolu] Problème upload fichier

Eléphant du PHP | 97 Messages

03 janv. 2012, 18:34

Bonjour,

je cherche un moyen de mettre à jour une table de ma base de données directement à partir de l'import de fichier .csv dans une page accessible par l'administrateur.

Pour cela, je crée un formulaire par lequel je vais uploader les fichiers : update_base.php
<?php
include_once("../include/header.php");
include_once("adm_common.php");
$nbr_fichier_par_region = 3;

checkRights();
rubriquesAdm(2,"Mettre à jour la base de données");
echo '
			<form method="post" action="confirmation_fill.php" enctype="multipart/form-data">
				<p>
					<h3>Instructions :</ br></h3>
					<ol>
						<li>Sélectionnez les fichiers csv précédemment créés dans la case en regard du nom de la région correspondante (Remarque : 
						il est possible de rentrer deux fichiers par région car certaines régions sont sur deux fichiers)</li>
						<li>Entrez l\'année correspondante aux fichiers sélectionnés (Obligatoire)</li>
						<li>Validez</li>
					</ol>
				</p>
				<p>
				<table>
					';
						$req="SELECT nom_region, id_region FROM region ORDER BY id_region";
						$result=mysql_query($req) or die('Requête invalide : ' . mysql_error() . "\n" . 'Requête complète : ' . $req);
						while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
							
							echo '<tr><td><label>'.$row['nom_region'].'</label>';
							for($i = 1 ; $i <= $nbr_fichier_par_region ; $i++){
								echo '<td><input type="file" name="' . $row['id_region'] . '_' . $i .'"></input></td>';
							}
							echo '</tr>';
						}
						mysql_free_result($result);
						echo '<tr><td><label for="annee">Année :</label></td>
							<td><input type="text" name="annee" id="annee"/></td></tr>';
						echo '<tr><td><label for="separateur">Séparateur : </label></td>
							<td>
								<input type="radio" name="separateur" value=";" id="point_virgule" checked="checked"/> <label for="point_virgule">;</label>
								<input type="radio" name="separateur" value="," id="virgule"  /> <label for="virgule">,</label>
							</td></tr>';
						echo '<input type="hidden" name = "nbr_fichier_par_region" value ="' . $nbr_fichier_par_region . '"/>';
				echo'
				</table>
				</p>
				<div class="boutons"><!-- BOUTONS -->
					<input type="submit" value="Valider"/>
					<input type="reset" tabindex=55/> 
				</div>
			</form>	
			';	
				fermeAdm();
				?>
<?php
include("../include/footer.php");
?> 
Ensuite, je dois traiter les informations transmises dans le formulaire, ces informations sont envoyées à confirmation_fill.php, comme vous pouvez le voir dans le formulaire.
Dans cette fonction, je vérifie si on a bien inséré un fichier à uploader, je fais les test d'erreur, je vérifie si on upload bien un fichier .csv et enfin je transfère mes fichiers dans le dossier que je souhaite.
<?php
include_once("../include/header.php");
?>
<?php
		$req="SELECT nom_region, id_region FROM region ORDER BY id_region";
		$result=mysql_query($req) or die('Requête invalide : ' . mysql_error() . "\n" . 'Requête complète : ' . $req);
		$array_nom_region = array();
		$array_id_region = array();
		$files_number = 0;
		echo '<table>';
		while ($row = mysql_fetch_array($result, MYSQL_ASSOC)){
			for($i = 1 ; $i <= $_POST['nbr_fichier_par_region'] ; $i++){
				$nom_region_courrant = $row['nom_region'] . '_' . $i;
				$id_region_courrant = $row['id_region'] . '_' . $i;
				if (isset($_FILES[$id_region_courrant])){
					// GESTION DES ERREURS
					if ($_FILES[$id_region_courrant]['error']){
						switch ($_FILES[$id_region_courrant]['error']){
							case 1: // UPLOAD_ERR_INI_SIZE
							$message = ' : Le fichier dépasse la limite autorisée par le serveur (fichier php.ini) !';
							break;
							case 2: // UPLOAD_ERR_FORM_SIZE
							$message = ' : Le fichier dépasse la limite autorisée dans le formulaire HTML !';
							break;
							case 3: // UPLOAD_ERR_PARTIAL
							$message = ' : L\'envoi du fichier a été interrompu pendant le transfert !';
							break;
							case 4: // UPLOAD_ERR_NO_FILE
							$message = ' : Pas de fichiers sélectionné';
							break;
						}
					}
					else{
					// $_FILES[$id_region_courrant]['error'] vaut 0 soit UPLOAD_ERR_OK   
					// ce qui signifie qu'il n'y a eu aucune erreur
					
						// On vérifie que le fichier est bien un .csv
						// récupère la partie de la chaine à partir du dernier . pour connaître l'extension.
						$extension = strrchr($_FILES[$id_region_courrant]['name'], '.');
						//Ensuite on teste
						if($extension != '.csv'){ //Si l'extension n'est pas dans le tableau
							$message = ' : Vous devez uploader un fichier de type csv';
						}
						else{
							$dossier = '../upload/';
							if(move_uploaded_file($_FILES[$id_region_courrant]['tmp_name'], $dossier . $nom_region_courrant . '.csv')){ //Si la fonction renvoie TRUE, c'est que ça a fonctionné...
								$message = ' : Upload effectué avec succès !';
								$array_nom_region[] = $nom_region_courrant;
								$array_id_region[] = $id_region_courrant;
								$files_number++;
							}
							else{ //Sinon (la fonction renvoie FALSE).
								$message = ' : Echec de l\'upload !';
							}
						}
					}
				}
				else{
					$message = ' : Le fichier n\'existe pas';
				}
				echo '<tr><td>' . $nom_region_courrant . '</td>
						<td>' . $message . '</td></tr>';
			}
		}
		echo '</table>';
		?>
			<form  method="post" action="fill_base.php">
				<input type="hidden" name = "array_nom_region" value ="<?php echo implode("|", $array_nom_region); ?>"/>
				<input type="hidden" name = "array_id_region" value ="<?php echo implode("|", $array_id_region); ?>"/>
				<input type="hidden" name = "files_number" value ="<?php echo $files_number; ?>"/>
				<input type="hidden" name = "annee" value ="<?php echo $_POST['annee']; ?>"/>
				<input type="hidden" name = "separateur" value ="<?php echo $_POST['separateur']; ?>"/>
				<input type="submit" value="Valider" tabindex=50/>
			</form>
<?php
include("../include/footer.php");
?>
Mais alors j'obtiens des choses que je ne peux pas expliquer :
En tout, j'ai 8 régions (Grand-Centre, Ile-de-France, Méditerranée, Ouest, Rhone-Alpes/Auvergne, Sud-Ouest, Nord-Ouest, Est) donc 8 fichiers .csv à uploader (+2fichiers car la région Ile de France est répartie en 3fichiers). Et lorsque j'upload mes 8+2=10 fichiers, ma page PHP m'informe que je n'ai rien uploadé :

Grand Centre_1 : Le fichier n'existe pas
Grand Centre_2 : Le fichier n'existe pas
Grand Centre_3 : Le fichier n'existe pas
Île-de-France_1 : Le fichier n'existe pas
Île-de-France_2 : Le fichier n'existe pas
Île-de-France_3 : Le fichier n'existe pas
Méditerranée_1 : Le fichier n'existe pas
Méditerranée_2 : Le fichier n'existe pas
Méditerranée_3 : Le fichier n'existe pas
Ouest_1 : Le fichier n'existe pas
Ouest_2 : Le fichier n'existe pas
Ouest_3 : Le fichier n'existe pas
Rhône-Alpes Auvergne_1 : Le fichier n'existe pas
Rhône-Alpes Auvergne_2 : Le fichier n'existe pas
Rhône-Alpes Auvergne_3 : Le fichier n'existe pas
Sud Ouest_1 : Le fichier n'existe pas
Sud Ouest_2 : Le fichier n'existe pas
Sud Ouest_3 : Le fichier n'existe pas
Nord Ouest_1 : Le fichier n'existe pas
Nord Ouest_2 : Le fichier n'existe pas
Nord Ouest_3 : Le fichier n'existe pas
Est_1 : Le fichier n'existe pas
Est_2 : Le fichier n'existe pas
Est_3 : Le fichier n'existe pas
National_1 : Le fichier n'existe pas
National_2 : Le fichier n'existe pas
National_3 : Le fichier n'existe pas

J'ai fait un
<pre><?php  print_r($_FILES); ?></pre>
pour en être bien sur et effectivement, rien n'est trouvé !!
Alors je décide de faire ca au fur et à mesure et j'observe que jusqu'à "Nord-Ouest", l'upload fonctionne correctement, ce qui correspond à un upload de 33,8Mo.
Dans le doute de me dire que c'était un problème de capacité d'upload j'ai modifié des valeurs dans php.ini, à savoir :
post_max_size=60M
upload_max_filesize=50M

Malgré tout ça, je n'arrive pas a uploader tous mes fichiers. Alors je ne sais pas vraiment quoi faire.. En soit, je ne pense pas qu'il s'agisse d'une erreur de code PHP mais plus une erreur de réglage de paramètre, mais lequel ?

Merci d'avance pour votre aide.
Modifié en dernier par ladinho58 le 06 janv. 2012, 16:15, modifié 1 fois.

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

03 janv. 2012, 20:53

Salut,

il donne quoi le print_r($_FILES) ? (ou avec var_dump ;) ).
Même si tu n'a pas les fichiers tu doit avoir l'index error qui te donne quelque chose ?

Y a quoi dans le source html du formulaire (celui généré par le 1er script) ?

@+
Il en faut peu pour être heureux ......

Eléphant du PHP | 97 Messages

04 janv. 2012, 10:11

Voici ce que donne le print_r : Il est fait pour les 3 premières régions (grand centre, ile de france et mediterannée, le reste est vide)

Array
(
[1_1] => Array
(
[name] => GC_2010.csv
[type] => application/vnd.ms-excel
[tmp_name] => C:\wamp\tmp\phpE3C9.tmp
[error] => 0
[size] => 3483935
)

[1_2] => Array
(
[name] =>
[type] =>
[tmp_name] =>
[error] => 4
[size] => 0
)

[1_3] => Array
(
[name] =>
[type] =>
[tmp_name] =>
[error] => 4
[size] => 0
)

[2_1] => Array
(
[name] => IDF1_2010.csv
[type] => application/vnd.ms-excel
[tmp_name] => C:\wamp\tmp\phpE447.tmp
[error] => 0
[size] => 7147511
)

[2_2] => Array
(
[name] => IDF2_2010.csv
[type] => application/vnd.ms-excel
[tmp_name] => C:\wamp\tmp\phpE551.tmp
[error] => 0
[size] => 55402
)

[2_3] => Array
(
[name] => IDF3_2010.csv
[type] => application/vnd.ms-excel
[tmp_name] => C:\wamp\tmp\phpE590.tmp
[error] => 0
[size] => 535459
)

[3_1] => Array
(
[name] => MED_2010.csv
[type] => application/vnd.ms-excel
[tmp_name] => C:\wamp\tmp\phpE62D.tmp
[error] => 0
[size] => 4779773
)

[3_2] => Array
(
[name] =>
[type] =>
[tmp_name] =>
[error] => 4
[size] => 0
)

[3_3] => Array
(
[name] =>
[type] =>
[tmp_name] =>
[error] => 4
[size] => 0
)

Eléphant du PHP | 97 Messages

04 janv. 2012, 10:17

Et voici le code source du formulaire ( je suis désolé ça manque peut-être de lisibilité )
				
		<!-- Le corps -->
		<div class="corps">
	<div>
		<table class="center" style="width: 100%;">
		<tr valign="top">
			<td style="width:205px">
				<div id="navigation">
					<fieldset>

						<legend>Rubrique</legend>	
						<a href="adm_list.php" class="admlink">Gestion des utilisateurs</a><br />
						<a href="adm_bdd.php" class="admlinkactive">Gestion base de données</a><br />
						<a href="adm_template.php" class="admlink">Gestion modèle rapport</a><br />
						<a href="adm_stat.php" class="admlink">Statistiques</a><br />
						<a href="adm_system.php" class="admlink">Informations système</a>

				</fieldset>
				</div>
			</td>
			<td valign="top">
				<div id="corps">
					<fieldset>
						<legend>Mettre à jour la base de données</legend>
			
			<form method="post" action="confirmation_fill.php" enctype="multipart/form-data">

				<p>
					<h3>Instructions :</ br></h3>
					<ol>
						<li>Sélectionnez les fichiers csv précédemment créés dans la case en regard du nom de la région correspondante (Remarque : 
						il est possible de rentrer deux fichiers par région car certaines régions sont sur deux fichiers)</li>
						<li>Entrez l'année correspondante aux fichiers sélectionnés (Obligatoire)</li>
						<li>Validez</li>
					</ol>

				</p>
				<p>
				<table>
					<tr><td><label>Grand Centre</label><td><input type="file" name="1_1"></input></td><td><input type="file" name="1_2"></input></td><td><input type="file" name="1_3"></input></td></tr><tr><td><label>Île-de-France</label><td><input type="file" name="2_1"></input></td><td><input type="file" name="2_2"></input></td><td><input type="file" name="2_3"></input></td></tr><tr><td><label>Méditerranée</label><td><input type="file" name="3_1"></input></td><td><input type="file" name="3_2"></input></td><td><input type="file" name="3_3"></input></td></tr><tr><td><label>Ouest</label><td><input type="file" name="4_1"></input></td><td><input type="file" name="4_2"></input></td><td><input type="file" name="4_3"></input></td></tr><tr><td><label>Rhône-Alpes Auvergne</label><td><input type="file" name="5_1"></input></td><td><input type="file" name="5_2"></input></td><td><input type="file" name="5_3"></input></td></tr><tr><td><label>Sud Ouest</label><td><input type="file" name="6_1"></input></td><td><input type="file" name="6_2"></input></td><td><input type="file" name="6_3"></input></td></tr><tr><td><label>Nord Ouest</label><td><input type="file" name="7_1"></input></td><td><input type="file" name="7_2"></input></td><td><input type="file" name="7_3"></input></td></tr><tr><td><label>Est</label><td><input type="file" name="8_1"></input></td><td><input type="file" name="8_2"></input></td><td><input type="file" name="8_3"></input></td></tr><tr><td><label>National</label><td><input type="file" name="9_1"></input></td><td><input type="file" name="9_2"></input></td><td><input type="file" name="9_3"></input></td></tr><tr><td><label for="annee">Année :</label></td>

							<td><input type="text" name="annee" id="annee"/></td></tr><tr><td><label for="separateur">Séparateur : </label></td>
							<td>
								<input type="radio" name="separateur" value=";" id="point_virgule" checked="checked"/> <label for="point_virgule">;</label>
								<input type="radio" name="separateur" value="," id="virgule"  /> <label for="virgule">,</label>
							</td></tr><input type="hidden" name = "nbr_fichier_par_region" value ="3"/>
				</table>

				</p>
				<div class="boutons"><!-- BOUTONS -->
					<input type="submit" value="Valider"/>
					<input type="reset" tabindex=55/> 
				</div>
			</form>	
			
					</fieldset>
				</div>
			</td>
		</tr>

	</table>
	
					</div>
		
		
		</div>
	</body>

ViPHP
ViPHP | 2577 Messages

04 janv. 2012, 12:10

Bonjour,

C'est dans le "else" de la condition : if (isset($_FILES[$id_region_courrant]))
qu'apparait le message. Ajoute $id_region_courrant au message pour voir la valeur. Elle peut être différente de 1_1...

Eléphant du PHP | 97 Messages

04 janv. 2012, 15:12

En fait c'est bon, en réésayant ça a fonctionné. Je pense que j'ai du oublier de relancer Apache ou une connerie comme ca, donc mes changements de paramètres ont pas été pris en compte.
En revanche, j'obtiens désormais une autre erreur un peu plus loin.

Une fois que ma page PHP m'indique que les uploads ont été réalisés avec succès, il faut maintenant se servir de ces fichiers pour modifier les tables de la base de données qui correspondent aux uploads. Donc en dessous de mes phrases "uploads réalisé avec succès" je clique sur "valider" qui amène sur une page qui traite les informations et modifie la BD en conséquence. Mais après pas moins de 3heures de chargement, j'arrive sur une erreur :

Notice: Undefined offset: 14 in C:\wamp\www\vespa_b1\administration\fill_base.php on line 187

En me renseignant un peu sur internet, je vois qu'il s'agit d'un problème d'effet de bord ( ??? ). En gros si j'ai bien compris, c'est lorsqu'une fonction modifie une valeur qui est autre que sa valeur output. Enfin, ca ne m'avance pas trop..
J'ai envie de me dire qu'il ne s'agit "que" d'une erreur Notice et donc normalement ma BD devrait être modifiée comme il faut, non ? Mais bon, une erreur c'est pas très beau, alors j'aimerai savoir si vous savez d'où pourrait provenir cette erreur encore pour ma part inconnue au bataillon ?

Voici mon fichier fill_base.php :
<?php
include_once('../include/header.php');
?>


<?php 
$files_number = $_POST['files_number'];
$array_nom_region = explode("|", $_POST['array_nom_region']);
$array_id_region = explode("|", $_POST['array_id_region']);
$separateur = $_POST['separateur'];

// On vérifie qu'au moins une région a été entrée
if(!$files_number){
	echo '<p class="erreur"> Veuillez saisir au moins une région dans le <a href="update_base.php">formulaire</a></p>';
	include('../include/footer.php');
	exit;
}

// On vérifie que le champs année a bien été renseigné
if(isset($_POST['annee']) and $_POST['annee'] != 0){
	$annee_courrant = $_POST['annee'];
}
else{
	echo '<p class="erreur"> Veuillez entrer l\'année dans le <a href="update_base.php">formulaire</a></p>';
	include('../include/footer.php');
	exit;
}

	// On ouvre une transaction
	mysql_query('BEGIN');
	// On supprime de la BDD les clients des régions entrées
	mysql_query('TRUNCATE TABLE `client'.$annee_courrant.'`');

while($files_number){
	// ********************************************************************
	// PARTIE : Lecture du fichier tempo.csv et enregistrement des données dans un tableau
	// ********************************************************************	
	$nom_region_courrant = $array_nom_region[$files_number - 1];
	$array_id_region_courrant = explode("_",$array_id_region[$files_number - 1]);
	$id_region_courrant = $array_id_region_courrant[0];
	
	if(file_exists('../upload/' . $nom_region_courrant . '.csv')){
		// ouverture du fichier en mode lecture (r = ready)
		$fichier = fopen('../upload/' . $nom_region_courrant . '.csv',"r+");
		if(!$fichier){
			echo '	<p class="erreur">
						Veuillez vérifier que le fichier upload/' . $nom_region_courrant . '.csv existe, possède les bons droits et n\'est pas ouvert.
					</p>
					<p><br /><div class="faux_bouton">
						<a href="update_base.php">Retour</a></div>
					</p>';
			include('../include/footer.php');
			exit;
		}
	}
	else{
		echo '	<p class="erreur">
					Veuillez vérifier que le fichier upload/' . $nom_region_courrant . '.csv existe et possède les bons droits
				</p>
				<p><br /><div class="faux_bouton">
					<a href="update_base.php">Retour</a></div>
				</p>';
		include('../include/footer.php');
		exit;
	}
	$reqcreate = "
			CREATE TABLE IF NOT EXISTS `client".$annee_courrant."` (
	  `id_client` mediumint(11) unsigned NOT NULL AUTO_INCREMENT,
	  `superficie` smallint(11) unsigned DEFAULT NULL,
	  `personnes` smallint(11) unsigned DEFAULT NULL,
	  `annee` int(11) NOT NULL,
	  `id_tarif` int(11) NOT NULL,
	  `id_versionabo` int(11) NOT NULL,
	  `id_typeoffre` int(11) NOT NULL,
	  `id_region` int(11) NOT NULL,
	  `id_naf` int(11) NOT NULL,
	  `hph_souscrite` int(11) NOT NULL,
	  `hpd_souscrite` int(11) NOT NULL,
	  `hch_souscrite` int(11) NOT NULL,
	  `hcd_souscrite` int(11) NOT NULL,
	  `hpe_souscrite` int(11) NOT NULL,
	  `hce_souscrite` int(11) NOT NULL,
	  `ja_souscrite` int(11) NOT NULL,
	  `pte_souscrite` int(11) NOT NULL,
	  PRIMARY KEY (`id_client`),
	  KEY `id_region` (`id_region`),
	  KEY `id_tarif` (`id_tarif`),
	  KEY `id_versionabo` (`id_versionabo`),
	  KEY `id_typeoffre` (`id_typeoffre`),
	  KEY `tarif_naf_pte` (`id_tarif`,`id_naf`,`id_versionabo`,`id_typeoffre`,`pte_souscrite`),
	  KEY `tarif_naf_hce` (`id_tarif`,`id_naf`,`id_versionabo`,`id_typeoffre`,`hce_souscrite`),
	  KEY `tarif_naf_ja` (`id_tarif`,`id_naf`,`id_versionabo`,`id_typeoffre`,`ja_souscrite`),
	  KEY `tarif_naf_hph` (`id_tarif`,`id_naf`,`id_versionabo`,`id_typeoffre`,`hph_souscrite`),
	  KEY `tarif_region_naf` (`id_tarif`,`id_region`,`id_naf`,`id_versionabo`,`id_typeoffre`),
	  KEY `id_tarif_2` (`id_tarif`,`id_naf`,`id_versionabo`,`id_typeoffre`),
	  KEY `tarif_naf_hpd` (`id_tarif`,`id_naf`,`id_versionabo`,`id_typeoffre`,`hpd_souscrite`),
	  KEY `tarif_naf_hpe` (`id_tarif`,`id_naf`,`id_versionabo`,`id_typeoffre`,`hpe_souscrite`),
	  KEY `tarif_naf_hcd` (`id_tarif`,`id_naf`,`id_versionabo`,`id_typeoffre`,`hcd_souscrite`),
	  KEY `tarif_naf_hch` (`id_tarif`,`id_naf`,`id_versionabo`,`id_typeoffre`,`hch_souscrite`)
	) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT = 1 ;
			";
	mysql_query($reqcreate) or die('Requête invalide : ' . mysql_error() . "\n Requête complète : ".$reqcreate."\n");
	$reqfk ="
			ALTER TABLE `client".$annee_courrant."`
	  ADD CONSTRAINT `client".$annee_courrant."_ibfk_2` FOREIGN KEY (`id_region`) REFERENCES `region` (`id_region`),
	  ADD CONSTRAINT `client".$annee_courrant."_ibfk_3` FOREIGN KEY (`id_naf`) REFERENCES `naf` (`id_naf`),
	  ADD CONSTRAINT `client".$annee_courrant."_ibfk_4` FOREIGN KEY (`id_tarif`) REFERENCES `tarif` (`id_tarif`),
	  ADD CONSTRAINT `client".$annee_courrant."_ibfk_5` FOREIGN KEY (`id_versionabo`) REFERENCES `versionabo` (`id_versionabo`),
	  ADD CONSTRAINT `client".$annee_courrant."_ibfk_6` FOREIGN KEY (`id_typeoffre`) REFERENCES `typeoffre` (`id_typeoffre`);
			
			";
	mysql_query($reqfk);
    // lecture ligne par ligne tant qu'on ne rencontre pas le code: fin de fichier(feof)
	$i = 0;
	$tableau = array();
	fgets($fichier,500);
    while(!feof($fichier)){
            // l'instruction explode() sépare la ligne en autant de valeurs que de point-virgules rencontrés
            // fgets() prend les valeurs dans le fichier et lit 500 caractères par ligne (à adapter)
            // $tableau[] est une variable tableau ou array qui va recevoir ce qui est lu dans le fichier
			// En fait $tableau[][] contiendra exactement ce que contient la feuille excel initiale avec en premier indice le numéro de la ligne 
			// (qui commence à 0!) et en second indice le numéro de la colonne (qui commence aussi à 0)
            $tableau[$i] = explode($separateur, fgets($fichier,500));
            $i++;
    }
	
    // fermeture du fichier
    fclose($fichier);
	//On supprime du serveur le fichier qui vient d'être entré
	unlink('../upload/' . $nom_region_courrant . '.csv');
    $nblignes = $i - 1;
    
    $array_naf = array();
    $array_tarif = array();
    $array_version = array();
    $array_offre = array();
    
    //Chargement de tous les codes NAF
    $req = mysql_query('SELECT id_naf, code_naf FROM naf');
    while($result=mysql_fetch_array($req)){
    	$array_naf[strtolower($result[1])]=(int)$result[0];
    }
	//Chargement de tous les TARIFS
    $req = mysql_query('SELECT id_tarif, nom_tarif FROM tarif');
    while($result=mysql_fetch_array($req)){
    	$array_tarif[strtolower($result[1])]=(int)$result[0];
    }
	//Chargement de toutes les VERSION
    $req = mysql_query('SELECT id_versionabo, nom_version FROM versionabo');
    while($result=mysql_fetch_array($req)){
    	$array_version[strtolower($result[1])]=(int)$result[0];
    }
	//Chargement de toutes les OFFRE
    $req = mysql_query('SELECT id_typeoffre, type_offre FROM typeoffre');
    while($result=mysql_fetch_array($req)){
    	$array_offre[strtolower($result[1])]=(int)$result[0];
    }
    
    if(!isset($tableau[1][14]) or isset($tableau[1][15])){
		echo '<p class="erreur"> Le fichier ' . $nom_region_courrant . ' n\'est pas valide. Retournez au <a href="update_base.php">formulaire</a> et réessayez avec un fichier valide</p>';
		break;
	}
	else{	
		// ********************************************************************
		// PARTIE : Traitements des données reçues
		// ********************************************************************

		// On va traiter les données de la variable $tableau ligne par ligne en commencant par la deuxième (ligne d'indice 1 car on ne traite pas la ligne d'en-têtes)
		for ($i = 1 ; $i < $nblignes ; $i++){		
				//On commence par récupérer chacune des valeurs de la ième ligne dans des varibles
				//Attention si le fichier excel d'origine a ses colonnes disposées dans un ordre différent de celui-ci, il faut modifier les valeurs du second indice 
				//de la variable $tableau
				$CODE_NAF = $tableau[$i][0];
				$LIBELLE_CODE_NAF = $tableau[$i][1];
				$TOV = $tableau[$i][2];
				$VERSION = $tableau[$i][3];
				$SUPERFICIE = (int) $tableau[$i][4];
				$NB_PERSONNE = (int) $tableau[$i][5];
				$TYPE_OFFRE = $tableau[$i][6];
				$HCD_SOUSCRITE = (int) $tableau[$i][7];
				$HCE_SOUSCRITE = (int) $tableau[$i][8];
				$HCH_SOUSCRITE = (int) $tableau[$i][9];
				$HPD_SOUSCRITE = (int) $tableau[$i][10];
				$HPE_SOUSCRITE = (int) $tableau[$i][11];
				$HPH_SOUSCRITE = (int) $tableau[$i][12];
				$JA_SOUSCRITE = (int) $tableau[$i][13];
				$PTE_SOUSCRITE = (int) $tableau[$i][14];                             //LIGNE 187
				
				//On échappe la chaîne de caractère correspondant au libellé du code naf pour ne pas avoir de problème avec des appostrophes éventuelles
				//$LIBELLE_CODE_NAF = mysql_real_escape_string($LIBELLE_CODE_NAF);
				
				set_time_limit(120);
				
				
			//Pour les 2 paragraphes suivants (respectivement TARIF et NAF) :
			//1 - On regarde si la valeur de la ième ligne existe déjà dans la base de donnée en recherchant son id (1ère requête).
			//2 - Si elle existe on ne fait rien, sinon on l'ajoute (2ème requête) puis on récupère son id (3ème requête)
			//3 - On transtype ensuite l'id récupéré (à l'étape 1 ou 2 suivant les cas) en entier (int)
		
			//TARIF
				/*$existTarif = mysql_query('SELECT id_tarif FROM tarif WHERE nom_tarif = "' . $TOV . '" LIMIT 1');
				$res_tarif = mysql_fetch_array($existTarif);
				$id_tarif_courrant = (int)$res_tarif[0];
		
			//NAF
				$existNaf = mysql_query('SELECT id_naf FROM naf WHERE code_naf = "' . $CODE_NAF . '" LIMIT 1');
				$res_naf = mysql_fetch_array($existNaf);
				$id_naf_courrant = (int)$res_naf[0];
			//VERSION
				//echo substr($TOV,0,1)."-".$VERSION;
				$existversion = mysql_query('SELECT id_versionabo FROM versionabo WHERE lower(nom_version) = lower("' .$VERSION . '") LIMIT 1');
				$res_version = mysql_fetch_array($existversion);
				$id_version_courrant = (int)$res_version[0];
				if($id_version_courrant==0){
					echo $VERSION."\n";
				}
				
			//TYPE OFFRE
				$existoffre = mysql_query('SELECT id_typeoffre FROM typeoffre WHERE type_offre = "' .$TYPE_OFFRE . '" LIMIT 1');
				$res_offre = mysql_fetch_array($existoffre);
				$id_offre_courrant = (int)$res_offre[0];
				//Echec de la récupération du type d'offre. Par défaut on met la version de base	
				if($id_offre_courrant==0){
					if(substr($TOV,0,1)=="J"){
						$id_offre_courrant=1;
					}
					else{
						$id_offre_courrant=3;
					}
				}*/
			$id_naf_courrant =$array_naf[strtolower($CODE_NAF)];
				
			if(isset($array_tarif[strtolower($TOV)]))
				$id_tarif_courrant = $array_tarif[strtolower($TOV)];
			
			if(isset($array_version[strtolower ($VERSION)]))
				$id_version_courrant = $array_version[strtolower ($VERSION)];
			
			if(isset($array_version[strtolower ($TYPE_OFFRE)]))
				$id_offre_courrant = $array_offre[strtolower($TYPE_OFFRE)];
			elseif(isset($array_offre[strrev(strtolower($TYPE_OFFRE))]))
				$id_offre_courrant = $array_offre[strrev(strtolower($TYPE_OFFRE))];
			
				
			
			if($id_naf_courrant=="" || !isset($id_naf_courrant))
				$id_naf_courrant=1;
			
			if($id_tarif_courrant==0){
					if(substr($TOV,0,1)=="J"){
						$id_tarif_courrant=1;
					}
					else{
						$id_tarif_courrant=3;
					}
			}
			if($id_version_courrant==0){
					if(substr($TOV,0,1)=="J"){
						$id_version_courrant=2;
					}
					else{
						$id_version_courrant=3;
					}
			}
			if(!($id_naf_courrant=="" || $id_offre_courrant=="" || $id_region_courrant=="" || $id_tarif_courrant=="" || $id_version_courrant==""
			))
				{
							//CLIENT
			//La table client peut maintenant être remplie car on est assuré de l'existence des clés étrangères par l'étape précédente
				$req = 'INSERT INTO client'.$annee_courrant.' SET superficie=' . $SUPERFICIE . ', personnes=' . $NB_PERSONNE . ', hph_souscrite=' . $HPH_SOUSCRITE . 
							', hpd_souscrite=' . $HPD_SOUSCRITE . ',hch_souscrite=' . $HCH_SOUSCRITE . ', hcd_souscrite=' . $HCD_SOUSCRITE . 
							', hpe_souscrite=' . $HPE_SOUSCRITE . ', hce_souscrite=' . $HCE_SOUSCRITE . ',ja_souscrite=' . $JA_SOUSCRITE . 
							',pte_souscrite=' . $PTE_SOUSCRITE . ', id_tarif=' . $id_tarif_courrant . ', id_region=' . $id_region_courrant . 
							', id_naf=' . $id_naf_courrant . ', annee= ' . $annee_courrant .', id_versionabo=' . $id_version_courrant .', id_typeoffre=' .$id_offre_courrant ;
				 
				mysql_query($req) or die('Requête invalide : ' . mysql_error() . "\n Requête complète : ".$req."\n");

				}
			}
		
		$files_number-- ;
	}

}            

	
    


		// ********************************************************************
		// PARTIE : Mise à jour de la table moyennes_toutes_regions
		// ********************************************************************

	// On commence par vider la table moyennes_toutes_regions, qui sera recalculée à la fin du script
	//mysql_query('TRUNCATE TABLE `moyennes_toutes_regions`');
	mysql_query('DELETE FROM `moyennes_toutes_regions` WHERE annee = '.$annee_courrant.' ');
	
	// On fait le précalcule des valeurs moyennes et des écart-types
	$req_division_tarif = 'SELECT id_division_naf, nom_tarif FROM division, tarif ORDER BY id_division_naf';
	$query_division_tarif = mysql_query($req_division_tarif) or die('Requête invalide : ' . mysql_error() . "\n" . 'Requête complète : ' . $req_division_tarif);
	while($division_tarif = mysql_fetch_row($query_division_tarif)){
		set_time_limit(120);
		$req = 'SELECT COUNT(c.id_client) AS NBR_CLIENTS, AVG(c.pte_souscrite), AVG(c.hph_souscrite), AVG(c.hch_souscrite), AVG(c.hpe_souscrite),
															AVG(c.hce_souscrite), AVG(c.hpd_souscrite), AVG(c.hcd_souscrite), AVG(c.ja_souscrite),
															STDDEV(c.pte_souscrite), STDDEV(c.hph_souscrite), STDDEV(c.hch_souscrite), STDDEV(c.hpe_souscrite),
															STDDEV(c.hce_souscrite), STDDEV(c.hpd_souscrite), STDDEV(c.hcd_souscrite), STDDEV(c.ja_souscrite)			
				FROM client'.$annee_courrant.' c USE INDEX (id_tarif_2), naf n, tarif t
				WHERE (t.nom_tarif = "' . $division_tarif[1] . '") AND (t.id_tarif = c.id_tarif)
				AND (n.id_division_naf = ' . $division_tarif[0] . ') AND (n.id_naf = c.id_naf)';
		$query = mysql_query($req) or die('Requête invalide : ' . mysql_error() . "\n" . 'Requête complète : ' . $req);
		$result = mysql_fetch_row($query);
	
		// On fait le précalcule des zéros
		$periode = array(1 => 'hce', 2 => 'hpe', 3 => 'hch', 4 => 'hph', 5 => 'hcd', 6 => 'hpd', 7 => 'ja', 8 => 'pte');
		$valeurs_zero = array();
		for($i = 1 ; $i < 9 ; $i++){
			$req_zero = 'SELECT COUNT(c.id_client) 
					FROM client'.$annee_courrant.' c, naf n, tarif t
					WHERE (t.nom_tarif = "' . $division_tarif[1] . '") AND (t.id_tarif = c.id_tarif)
					AND (n.id_division_naf = ' . $division_tarif[0] . ') AND (n.id_naf = c.id_naf)
					AND ' . $periode[$i] . '_souscrite = 0';
			$query_zero = mysql_query($req_zero) or die('Requête invalide : ' . mysql_error() . "\n" . 'Requête complète : ' . $req_zero);
			$result_zero = mysql_fetch_row($query_zero);
			$valeurs_zero[$i] = $result_zero[0];	
		}
		
		// On insert dans la BDD
		$req_insertion = 'INSERT INTO moyennes_toutes_regions SET id_division_naf = ' . $division_tarif[0] . ', annee = '.$annee_courrant.', nom_tarif = "' . $division_tarif[1] . '", somme = ' . $result[0] . 
		', avg_pte = ' . (int)$result[1] . ', avg_hph = ' . (int)$result[2] . ', avg_hch = ' . (int)$result[3] . ', avg_hpe = ' . (int)$result[4] . ', avg_hce = ' . (int)$result[5] . 
		', avg_hpd = ' . (int)$result[6] . ', avg_hcd = ' . (int)$result[7] . ', avg_ja = ' . (int)$result[8] . ', stddev_pte = ' . (int)$result[9] . ', stddev_hph = ' . (int)$result[10] . 
		', stddev_hch = ' . (int)$result[11] . ', stddev_hpe = ' . (int)$result[12] . ', stddev_hce = ' . (int)$result[13] . ', stddev_hpd = ' . (int)$result[14] . 
		', stddev_hcd = ' . (int)$result[15] . ', stddev_ja = ' . (int)$result[16] . ', ' . $periode[1] . '_zero = ' . $valeurs_zero[1] . 
		', ' . $periode[2] . '_zero = ' . $valeurs_zero[2] . ', ' . $periode[3] . '_zero = ' . $valeurs_zero[3] . 
		', ' . $periode[4] . '_zero = ' . $valeurs_zero[4] . ', ' . $periode[5] . '_zero = ' . $valeurs_zero[5] . 
		', ' . $periode[6] . '_zero = ' . $valeurs_zero[6] . ', ' . $periode[7] . '_zero = ' . $valeurs_zero[7] . 
		', ' . $periode[8] . '_zero = ' . $valeurs_zero[8];
		mysql_query($req_insertion) or die('Requête invalide : ' . mysql_error() . "\n" . 'Requête complète : ' . $req_insertion);
	}
	
	mysql_query('UPDATE version SET date = CURRENT_DATE WHERE id_version = 1');
	
	// On ferme la transaction
	mysql_query('COMMIT');

include('../include/footer.php');
?>

Eléphant du PHP | 209 Messages

04 janv. 2012, 15:25

Tu essayes d'accéder à une case non définie de ton tableau à savoir $tableau[$i][14]

Eléphant du PHP | 97 Messages

04 janv. 2012, 15:33

Est ce que le fait de modifier

for ($i = 1 ; $i < $nblignes ; $i++)

en

for ($i = 1 ; $i <= $nblignes ; $i++)

pourrait être correct ?

Parce que l'erreur provient du [14] pas du [$i], non ? mais dans mon tableau excel, j'ai bien 15colonnes (de A jusqu'à O) et chaque colonne correspond bien aux variables écrites..

Eléphant du PHP | 97 Messages

04 janv. 2012, 15:35

Et si j'ai un problème avec $i, je n'aurai pas juste un problème pour la case 14, mais sur toutes les lignes $i=nblignes

ViPHP
ViPHP | 2577 Messages

04 janv. 2012, 15:37

A priori, c'est l'index 14 qui merde dans $PTE_SOUSCRITE = (int) $tableau[$i][14];

Celà signifie que la ligne ne compte pas 15 colonnes (de 0 à 14 ?). Tu devrais vérifier le nombre de colonnes lors de chaque explode à la lecture.

Eventuellement, tu peux lire le fichier avec la fonction fgetcsv (http://php.net/manual/fr/function.fgetcsv.php) ca doit mieux marcher que le fget+explode. fgetcsv prend en charge les " pour les champs texte et les \ pour les " dans les textes. Tu peux choisir le séparateur de colonnes.

Une ligne avec la colonne O non renseigné peux faire que la ligne à 14 colonne au lieux de 15 (ca commence à 0 ou 1 ?)

Edit : if(!isset($tableau[1][14]) or isset($tableau[1][15])), c'est ce test qui doit être fait pour chaque ligne. Tu pourrait également faire un test sur les valeurs de chaque colonne pour vérifier qu'il n'y a pas d'erreur. Les utilisateurs font des conneries en grand nombre lors de la constitution de fichiers de ce genre. Entre autre il y a souvent des problèmes avec les dernières lignes du fichier (lignes vides).

Eléphant du PHP | 97 Messages

04 janv. 2012, 15:55

Oui, des fois il y a des lignes de la colonne O qui ne sont pas renseignées, mais il n'y a pas que la case dans O qui n'est pas renseignée. certaines lignes ne sont qu'à moitié remplies.
Chaque fichier csv comprend bien 15colonnes.
Après, je vais essayer avc fgetcsv mais je ne pense pas que cela change grand chose.. L'utilisation de fget+explode fonctionne tout aussi bien non ? D'autant que je n'utilise aucune fois ' ou " ou autre. Je n'utilise que des é ou _

ViPHP
ViPHP | 2577 Messages

04 janv. 2012, 16:47

Je te conseille d'ajouter :
if (count($tableau[$i]) <> 15) echo 'ligne ',$i,'nb col ',count($tableau[$i]);

Et tu vérifieras ensuite ce qu'il y a dans la ligne du fichier csv (pas avec excel !) en vérifiant qu'il y a moins de 500 caractères et que la ligne n'est pas coupée par un retour à la ligne dans le texte.

Eléphant du PHP | 97 Messages

04 janv. 2012, 17:25

je dois attendre un peu car le chargement est encore en cours. En ce qui concerne la ligne que tu m'invites à écrire, où faut-il la placer ?
entre $tableau[$i] = explode($separateur, fgets($fichier,500));
et
$i++;

? c'est ca ? (désolé de poser des questions qui peuvent sembler stupides, c'est juste que je touche aux langages internet depuis à peine 1 mois..)

Eléphant du PHP | 97 Messages

05 janv. 2012, 10:11

Ma base de données est bien remplie (je retrouve bien 349504 clients) et malgré tout cette erreur persiste. Est-ce que cette erreur pourra avoir une influence par la suite ?

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

05 janv. 2012, 10:34

salut,

gênant oui, il est préférable de savoir pourquoi il y a cette erreur, car si ce champ n'existe pas, la valeur associée en base ne sera pas bonne et dans ce cas inexploitable.

utiliser fgetcsv, parce que c'est fait pour ? :mrgreen: (code un poil plus compréhensible, p'tet plus rapide, quoi que ;) ).

je te conseil de :
- tester avec un fichier minimal dans un 1er temps (4 -5 lignes suffise 350k c'est trop et totalement inutile en test, sachant qu'en plus tu va fait des delete / truncate a tour de bras autant faire simple et rapide ;) ).

cela te permet aussi de pouvoir affiche le contenu de $tableau sans être noyer dans la masse des 350000 lignes de ton fichier (ce qui est simplement pas exploitable).
- un var_dump($tableau) en fin de traitement pourra t'aider à vérifier le contenu de ce que te retourne ton traitement.
- a tu vérifier la longueur maximal de chaque ligne ?, le délimiteur est bon ?

avec fgetcsv tu peux simplement éviter les problèmes de taille de ligne.
est tu certain qu'il faille supprimer la 1ère ligne ? (et que cette ligne ne contient que 500 caractères ?)
à la limite utilise ftgets pour lire ligne par ligne afin d'être certain de tout avoir.

tu peux teste avec la fonction file mais bon manipuler un tableau de 350000 lignes me semble un peu lourd en mémoire je sais pas ce que ce cela peux donner :) (mais pareil tu es certain d'avoir une ligne complète par "case" du tableau).

a tu essayer le LOAD DATA INFILE de mysql (qui a mon avis semble plus indiqué que le parse avec php, parce que ben c'est fait pour la encore ;) ).

@+
Il en faut peu pour être heureux ......