Vérification doublon dans import CSV

Résolu
roms75001 Messages postés 395 Date d'inscription   Statut Membre Dernière intervention   -  
 Utilisateur anonyme -
Bonjour,

J'ai fais un code afin d'insérer en base de données un fichier CSV, celui ci fonctionne très bien mais j'aimerais ajouté quelque chose :

Si le champs "E" est un doublon alors on retourne "doublon = 1" (je dois par la suite stocker le resultat en BDD)

J'ai donc fais le code suivant :


   $fp = fopen($fichier_dest, "r");
   //Lecture du fichier CSV
   if($fp){

    $ligne=0;

     while (($liste = fgetcsv($fp, 4096, ";")) !== FALSE)
     {

      $liste[0] = ( isset($liste[0]) ) ? $liste[0] : Null;
      $champsA = mysql_real_escape_string(implode('-', array_reverse(explode('/', $liste[0])))); 
      $champsE = mysql_real_escape_string (( isset($liste[4]) ) ? $liste[4] : Null); //ND
      $champsF = mysql_real_escape_string(( isset($liste[5]) ) ? $liste[5] : Null);
      $champsG = mysql_real_escape_string(( isset($liste[6]) ) ? $liste[6] : Null);
      $champsH = mysql_real_escape_string(( isset($liste[7]) ) ? $liste[7] : Null);
      $champsI = mysql_real_escape_string(( isset($liste[8]) ) ? $liste[8] : Null);
      $champsJ = mysql_real_escape_string(( isset($liste[9]) ) ? $liste[9] : Null);
      $champsK = mysql_real_escape_string(( isset($liste[10]) ) ? $liste[10] : Null);
      $champsL = mysql_real_escape_string(( isset($liste[11]) ) ? $liste[11] : Null);
      $champsM = mysql_real_escape_string(( isset($liste[12]) ) ? $liste[12] : Null);
      $champsO = mysql_real_escape_string(( isset($liste[14]) ) ? $liste[14] : Null);
      $champsP = mysql_real_escape_string(( isset($liste[15]) ) ? $liste[15] : Null);
      $liste[16] = ( isset($liste[16]) ) ? $liste[16] : Null;
      $champsQ = mysql_real_escape_string(implode('-', array_reverse(explode('/', $liste[16]))));  
      $nom_fichier = mysql_real_escape_string($_FILES['fichier']['name']);
      $cuid =  mysql_real_escape_string($_SESSION[_SESSION_IDENTIFIANT]);

      $indexAgent=selectionnerAgent($tbAgentsRef,$indexAgent);
      $tbAgentsRef[$indexAgent]['new']=$tbAgentsRef[$indexAgent]['new']-1;


      if (in_array($champsE, $liste)) {

       echo "<br />";
       echo"doublon = 1 ";
       echo $champsE;
       echo "<br/>";
       
      }

      else {
       echo "<br />";
       echo "doublon = 0 ";
       echo $champsE;
       echo "<br/>";
      }


      $ligne++; 
     }

   echo"<p>Importation Réussie</p>";

    fclose($fp);
   }


Mais ca me retourne toujours 1.

Savez vous m'aider ??

Merci d'avance

2 réponses

  1. Utilisateur anonyme
     
    Il y a quelques soucis avec ton code, car déjà
    in_array
    c'est juste pour savoir si une valeur se trouve dans un tableau, et non le nombre de fois, enfin je tiens à préciser à cause du message "doublon = 1".

    Ensuite chercher le $champE dans la $liste, alors que le $champE est un élément de la liste,
    in_array
    va donc toujours retourner
    true
    .

    Le mieux est d'utiliser
    array_keys
    , avec comme second paramètre le $champsE, et de compter le nombre d'élément retourné avec
    count
    , mais il faut aussi vérifier que le champ n'est pas vide ça donne:
    if(!empty($champsE) && count(array_keys($liste, $champsE)) > 1) {echo "Doublon du champ E"}

    Après les
    isset
    sont inutile car il retourne
    true
    dans tout les cas vu que si un champ n'est pas rempli dans le CSV la fonction
    fgetcsv
    remplacera par un champ vide jusqu'au dernier champ.

    Enfin là j'ai du mal à m'expliquer avec un exemple ça sera mieux.

    Si par exemple le champ P est rempli mais pas le B, comme P a un index plus grand que B, alors B existera (donc le
    isset
    retournera
    true
    ) mais ça sera juste un champ vide (une chaîne vide
    ''
    )

    Mais si un coup sur deux (ou plus) le champ Q est rempli alors là le
    isset
    est utile car si c'est le dernier champ à être rempli, l'index n'est présent dans le tableau que si ce champ est rempli.

    Puis pour tes conditions, il ne faut pas mettre le
    null
    dans la fonction
    mysql_real_escape_string
    car même si
    mysql_real_escape_string(null)
    vaut
    null
    si on fait une condition basique du genre
    mysql_real_escape_string(null) == null
    , ça te retourne
    false
    si tu fais
    mysql_real_escape_string(null) === null
    , car
    mysql_real_escape_string(null)
    équivaut à
    ''
    (une chaîne vide).

    if (($fp = fopen($fichier_dest, "r")) !== false) {
    	$ligne=0;
    	while (($liste = fgetcsv($fp, 4096, ";")) !== false) {
    		//array_fill permet de remplir un tableau à partir d'un index de début (ici 0), avec le nombre d'éléments à ajouter (ici 17 [lettre Q]) avec une valeur (ici 'null')
    		//Faire $array1 + $array2 permet de remplir les index manquant (isset = false) avec ceux de $array2.
    		$liste = $liste + array_fill(0, 17, null);
    		//range permet de créer un tableau partant d'un élément de début (A) faire un élément de fin (Q), ça peut être autre chose (comme 1,100)
    		$lettres = range('A', 'Q');
    		//On parcourt la liste
    		foreach ($liste as $key => $value) {
    			//trim permet de supprimer les espaces en début et fin de cĥaîne
    			$value = trim($value);
    			//Si l'index vaut 0 ou 16 alors on applique la modification
    			//Même si je pense que c'est pour une date dans ce cas je préfère un preg_replace ou utiliser la fonction date pour avoir quelque chose de correct même si c'est identique au final.
    			if ($key === 0 || $key === 16) {
    				$value = implode('-', array_reverse(explode('/', $value)));
    			}
    			//Si la variable n'est pas vide on applique mysql_real_escape_string sinon null
    			$liste[$key] = (!empty($value)) ? mysql_real_escape_string($value) : null;
    			//Création des variables $champs dynamiquement donc on aura $champsA à $champsQ avec les éléments de la liste modifié.
    			//Après je ne vois pas pourquoi créer des varibles alors que c'est identique à la $liste
    			${'champs'.$lettres[$key]} = $value;
    		}
    
    		$nom_fichier = mysql_real_escape_string($_FILES['fichier']['name']);
    		$cuid = mysql_real_escape_string($_SESSION[_SESSION_IDENTIFIANT]);
    
    		$indexAgent = selectionnerAgent($tbAgentsRef,$indexAgent);
    		//$tbAgentsRef[$indexAgent]['new']-- revient à faire $tbAgentsRef[$indexAgent]['new']=$tbAgentsRef[$indexAgent]['new']-1;
    		$tbAgentsRef[$indexAgent]['new']--
    
    		//Version simplifiée de la condition pour les doublons
    		$condChampsE = (!empty($champsE) && count(array_keys($liste, $champsE)) > 1) ? 'true' : 'false';
    		echo "<br>Doublon du \$champsE ($condChampsE), qui contient '$champsE'<br>";
    
    		//Version détaillée
    		if (!empty($champsE)) {
    			$listDoublon = array_keys($liste, $champsE);
    			if (count($listDoublon) > 1) {
    				echo "<p>La variable \$champsE ('<b>$champsE</b>') est identique à d'autres variables qui sont:<ul>";
    				//La condition évite d'avoir $champsE d'affiché
    				foreach ($listDoublon as $key) if($key !== 4) echo '<li>$champs'.$lettres[$key]." / \$liste[$key]</li>";
    				echo '</ul></p>';
    			} else echo "<p>La variable \$champsE ('$champsE') est unique.</p>";
    		} else echo '<p>La variable $champsE est vide.</p>';
    
    		$ligne++; 
    	}
    	echo"<p>Importation Réussie</p>";
    
        fclose($fp);
    }
    


    Voilà le code optimisé.
    1
    1. roms75001 Messages postés 395 Date d'inscription   Statut Membre Dernière intervention   7
       
      Wahouu, tout d’abord merci d'avoir pris le temps d'écrire ce beau code bien commenté.

      Je l'ai testé, il manque juste un point virgule après $tbAgentsRef[$indexAgent]['new']-- (mais je t'en veux pas :p) par contre j'ai toujours le même problème, ça me retourne false sur toutes les lignes alors que dans mon jeux de données j'ai un doublons sur la colonne E

      Petite préposition, j'ai vraiment besoin que ca me retourne 0 ou 1 car c'est ce qui est attendu par ma base de données :$
      0
    2. Utilisateur anonyme
       
      Après j'ai testé vite fait sur un fichier CSV, en mettant la même chose dans plusieurs cellules et dont la E, mais il me faudrait un exemple de tes données où il y a un doublon et que le script doit retourné ce qu'il faut.
      0
  2. roms75001 Messages postés 395 Date d'inscription   Statut Membre Dernière intervention   7
     
    Merci ZeNairolf pour ton aide !

    Pour ceux que ca intéresse voici la modification qu'il faut faire afin d'avoir le résultat attendu :

    
    if (($fp = fopen($fichier_dest, "r")) !== false) {
    	$doublons = array();
    	$ligne=0;
    
    ...
    
    		$condChampsE = (!empty($champsE) && in_array($champsE, $doublons)) ? '1' : '0';
    		echo "<br>Doublon du \$champsE ($condChampsE), qui contient '$champsE'<br>";
    
    ...
    
    		$doublons[] = $champsE;
    		$ligne++; 
    	}
    	echo"<p>Importation Réussie</p>";
    
        fclose($fp);
    }
    
    0
    1. Utilisateur anonyme
       
      Petite précision, ça permet de vérifier les doublons dans une colonne, et dans une ligne.
      0