IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

double boucle fopen() sur même fichier ?


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Avril 2010
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 35
    Par défaut double boucle fopen() sur même fichier ?
    Bonjour à tous !

    Voilà, je poste pour une petite question, qui est à l'origine un problème que j'essaie de résoudre.
    J'ai un script qui lit un fichier .txt afin d'en extraire des informations et de modifier une base de données : ajouter ou mettre à jour des entrées.

    Le fichier, globalement, ce sont des données ligne par ligne, séparées par un point-virgule. Il fait 70Mo, mais je ne pense pas que ce soit le problème.
    Pour certaines raisons, je dois faire une double boucle sur le même fichier.
    Je me demandais donc si faire deux fopen() sur le même fichier à la suite, sans fclose entre deux, avec deux variables différentes pour le $handle, pouvait faire planter le script, à cause de permissions ou de choses comme ça par exemple.

    Car mon script se termine, je ne sais même pas pourquoi, et pour couronner le tout je n'ai pas accès aux logs PHP (hébergement OVH mutualisé) et l'affichage des erreurs PHP sur la page (E_ALL) ne donne rien.

    Bref, est-ce que le script se termine à cause de ces permissions, ou est-ce un autre problème ?

    Voici le script, au cas où :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
     
     
    <?PHP
    include("../inc/header_admin.php");
     
    // Activer le rapport d'erreurs PHP
    if ($_SERVER['SERVER_NAME'] == "localhost" )  error_reporting(E_ALL);
     
    $fichier = fopen("../maj_dossier/EXPARTHQ.txt", "r");
     
    while (($tableau_chaine = fgetcsv($fichier,1024,";")) !== FALSE)
    {
    	echo "Première boucle : OK.";
    	//$tableau_chaine = fgetcsv($fichier,1024,";");
     
    	if ($tableau_chaine[0]=="ARTMAG" && $tableau_chaine[4]=="10")
    	{
    		echo "Produit du magasin 10 !";
    		$code_article=sprintf("%s %s %s",$tableau_chaine[1],$tableau_chaine[2],$tableau_chaine[3]);
    		//$quantite=$tableau_chaine[5];
    /***********************************************************************************/
     
    		fclose($fichier);
    		$fichier2 = fopen("../maj_dossier/EXPARTHQ.txt", "r");
     
    		while (($tableau_chaine2 = fgetcsv($fichier2,1024,";")) !== FALSE)
    		{
    			echo "Deuxième boucle : OK.";
    			//$tableau_chaine2 = fgetcsv($fichier2,1024,";");
     
    			if ($tableau_chaine2[0]=="ARTICLE" && $tableau_chaine2[1]==$tableau_chaine[1] && $tableau_chaine2[2]==$tableau_chaine[2] && $tableau_chaine2[3]==$tableau_chaine[3])
    			{	
    				$prix=$tableau_chaine2[17];
    				$description=addslashes($tableau_chaine2[5]);
    				$description2=addslashes($tableau_chaine2[6]);
     
    				echo "Code article : ".$code_article."<br />";
    				//echo "Quantite : ".$quantite."<br />";
    				echo "Description : ".$description."<br />";
    				echo "Description 2 : ".$description2."<br />";
    				echo "Prix : ".$prix."<br />";
     
    				$sql_compte = sprintf("SELECT COUNT(*) FROM types_produits WHERE ref_produit='%s'",$code_article);
    				$requete_compte = mysql_query($sql_compte);
    				if (!$requete_compte)
    				{
    					die('Requete invalide : ' . mysql_error());
    				}
    				if ($donnees_compte = mysql_fetch_array($requete_compte))
    				{
    					$nombre_enregistrement = $donnees_compte['COUNT(*)'];
    					//$selection = $donnees_compte['selection'];
    					echo "Nombre enregistrement : ".$nombre_enregistrement."<br />";
    					//echo "Selection : ".$selection."<br />";				
     
     
    					//$nouvelle_quantite=$selection+$quantite;
     
    					if ($nombre_enregistrement==0)
    					{
    						$requete="INSERT INTO types_produits (ref_produit, marque, sous_marque, prix_u) VALUES ('$code_article','$description','$description2','$prix')";
    						$execution = mysql_query($requete);
    						if (!$execution) {
    							die("Erreur d execution :".mysql_error());
    						}
    					}
    					else
    					{
    						$requete="UPDATE types_produits SET prix_u='$prix' WHERE ref_produit='$code_article'";
    						$execution = mysql_query($requete); 
    						if (!$execution) {
    							die("Erreur d execution :".mysql_error());
    						}
    					}
    				}
    			}
    		}
    		echo "Fin du fichier ARTICLE <br />";
    		echo "**************************<br />";
    		fclose($fichier2);
    /***********************************************************************************/
    	}
    }
    echo "Fin du fichier ARTMAG <br />";
    fclose($fichier);
    /**************************************/
    echo "<center><br /><a href='../administration/accueil_admin.php'>Retour</a></center>";
     
    include("../inc/footer_admin.php");
    ?>
    En gros quand je dis que le script ne se termine pas, je veux dire que la phrase "Fin du fichier ARTMAG", à la fin, ne s'affiche pas.

    Merci d'avance !

  2. #2
    Modérateur

    Avatar de MaitrePylos
    Homme Profil pro
    DBA
    Inscrit en
    Juin 2005
    Messages
    5 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : DBA
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 506
    Par défaut
    Cela ne serais pas plus en cause la durèe du script qui dépasse 30 secondes ?

  3. #3
    Membre Expert
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    1 349
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 349
    Par défaut
    +1 Maitre pylos.

    Ça ne serait pas possible de procéder autrement plutôt que d'ouvrir plusieurs fois le même fichier?

  4. #4
    Membre averti
    Inscrit en
    Avril 2010
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 35
    Par défaut
    Merci pour votre réponses !

    Si, je l'ai compris après, c'est pourquoi je venais répondre à mon post
    Le script est arrêté par OVH car justement c'est un hébergement mutualisé.

    Je suis en train de reformer le script afin de n'effectuer qu'une seule boucle, mais pas facile. Pour l'instant ça marche... avec une ligne sur deux. Je sais pourquoi mais pas comment le résoudre pour le moment.

    Le problème est que je teste si on arrive à telle ligne (en l'occurence une ligne qui commence par ARTICLE) afin de sortir de ma boucle, mais j'ai besoin de lire cette ligne ensuite dans ma la boucle de plus haut niveau. Donc je saute une ligne sur deux.

    En gros il me faudrait un truc qui me permettre de remonter le pointeur de fichier d'une ligne, mais ça ne doit pas être possible de procéder ainsi...

    Voici le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
     
    <?PHP
    include("../inc/header_admin.php");
     
    echo "Mise à jour numero 1.<br />";
     
    // Activer le rapport d'erreurs PHP
    if ($_SERVER['SERVER_NAME'] == "localhost" )  error_reporting(E_ALL);
     
    $fichier = fopen("../maj_dossier/EXPARTHQ2.txt", "r");
     
    while (($tableau_chaine = fgetcsv($fichier,1024,";")) !== FALSE)
    {
    	//echo "Première boucle : OK.";
    	//$tableau_chaine = fgetcsv($fichier,1024,";");
     
    	if ($tableau_chaine[0]=="ARTICLE")
    	{
    		//$tableau_chaine2[0] = "";
    		$flag_eof = ($tableau_chaine2 = fgetcsv($fichier,1024,";"));
    		while($tableau_chaine2[0] != "ARTICLE" && $flag_eof !== FALSE) {
    			if($tableau_chaine2[0] == "ARTMAG" && $tableau_chaine2[4] == "10") {
    				if($tableau_chaine2[1]==$tableau_chaine[1] && $tableau_chaine2[2]==$tableau_chaine[2] && $tableau_chaine2[3]==$tableau_chaine[3]) {
    					$code_article = sprintf("%s %s %s",$tableau_chaine2[1],$tableau_chaine2[2],$tableau_chaine2[3]);
     
    					$prix=$tableau_chaine[17];
    					$description=addslashes($tableau_chaine[5]);
    					$description2=addslashes($tableau_chaine[6]);
     
    					echo "Code article : ".$code_article."<br />";
    					//echo "Quantite : ".$quantite."<br />";
    					echo "Description : ".$description."<br />";
    					echo "Description 2 : ".$description2."<br />";
    					echo "Prix : ".$prix."<br />";
     
    					$sql_compte = sprintf("SELECT COUNT(*) FROM types_produits WHERE ref_produit='%s'",$code_article);
    					$requete_compte = mysql_query($sql_compte);
    					if (!$requete_compte)
    					{
    						die('Requete invalide : ' . mysql_error());
    					}
    					if ($donnees_compte = mysql_fetch_array($requete_compte))
    					{
    						$nombre_enregistrement = $donnees_compte['COUNT(*)'];
    						//$selection = $donnees_compte['selection'];
    						echo "Nombre enregistrement : ".$nombre_enregistrement."<br />";
    						//echo "Selection : ".$selection."<br />";				
     
     
    						//$nouvelle_quantite=$selection+$quantite;
     
    						if ($nombre_enregistrement==0)
    						{
    							$requete="INSERT INTO types_produits (ref_produit, marque, sous_marque, prix_u) VALUES ('$code_article','$description','$description2','$prix')";
    							$execution = mysql_query($requete);
    							if (!$execution) {
    								die("Erreur d execution :".mysql_error());
    							}
    						}
    						else
    						{
    							$requete="UPDATE types_produits SET prix_u='$prix' WHERE ref_produit='$code_article'";
    							$execution = mysql_query($requete); 
    							if (!$execution) {
    								die("Erreur d execution :".mysql_error());
    							}
    						}
    					}
    					echo "Fin de l'ARTICLE <br />";
    					echo "**************************<br />";
    				}
    			}
    		}
    	}
    }
    echo "Fin du fichier ARTMAG <br />";
    fclose($fichier);
     
     
    echo "<center><br /><a href='../administration/accueil_admin.php'>Retour</a></center>";
     
    include("../inc/footer_admin.php");
    ?>
    Le code est déjà un peu plus simple, je sens que je suis près du but !

    Merci à vous en tout cas, si j'ai la solution je la posterai.

  5. #5
    Membre Expert
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    1 349
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 349
    Par défaut
    Si tu precise plus le besoin général on pourra peut-être mieu t'aider.

    le bout de code est une xtrait ou tu n'as besoin de récuperer que des éléments ARTMAG:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if($tableau_chaine2[0] == "ARTMAG" && $tableau_chaine2[4] == "10"

  6. #6
    Membre Expert
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    1 349
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 349
    Par défaut
    Sinon un script plus simplifié :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    $fichier = fopen("../maj_dossier/EXPARTHQ2.txt", "r");
    $IsArticle = false;
    $nombre_enregistrement;
    $code_article = null;
    while (($tableau_chaine = fgetcsv($fichier,1024,";")) !== FALSE){
    	//nouvelle article
    	if ($tableau_chaine[0]=="ARTICLE"){
    		$code_article = sprintf("%s %s %s",$tableau_chaine2[1],$tableau_chaine2[2],$tableau_chaine2[3]);
    		$sql_compte = sprintf("SELECT COUNT(*) FROM types_produits WHERE ref_produit='%s'",$code_article);
    		$requete_compte = mysql_query($sql_compte) or die('Requete invalide : ' . mysql_error());
    		$donnees_compte = mysql_fetch_row($requete_compte);
    		$nombre_enregistrement = $donnees_compte[0];
    	}
    	else if($code_article != null && $tableau_chaine[0] == "ARTMAG" && $tableau_chaine[1].$tableau_chaine[2].$tableau_chaine[3] == $code_article && $tableau_chaine[4] == "10") {
     
    		$prix=$tableau_chaine[17];
    		$description=addslashes($tableau_chaine[5]);
    		$description2=addslashes($tableau_chaine[6]);
     
    		echo "Code article : ".$code_article."<br />";
    		//echo "Quantite : ".$quantite."<br />";
    		echo "Description : ".$description."<br />";
    		echo "Description 2 : ".$description2."<br />";
    		echo "Prix : ".$prix."<br />";
    		if ($nombre_enregistrement==0)
    		{
    			$requete="INSERT INTO types_produits (ref_produit, marque, sous_marque, prix_u) VALUES ('$code_article','$description','$description2','$prix')";
    		}
    		else
    		{
    			$requete="UPDATE types_produits SET prix_u='$prix' WHERE ref_produit='$code_article'";
    		}
    		$execution = mysql_query($requete) or die("Erreur d execution :".mysql_error());
    	}
    }
    ce qui me dérange c'est que avec un même fichier d'import tu vas update plusieurs fois type_produits pr le même code produit non?

  7. #7
    Modérateur

    Avatar de MaitrePylos
    Homme Profil pro
    DBA
    Inscrit en
    Juin 2005
    Messages
    5 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : DBA
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 506
    Par défaut
    Et dans un premier temps si tu augmentais le temps d'attente d'un script

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    //a mettre au début du script
    ini_set('max_execution_time',300 ); //5 minutes

  8. #8
    Membre Expert
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    1 349
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 349
    Par défaut
    Citation Envoyé par MaitrePylos Voir le message
    Et dans un premier temps si tu augmentais le temps d'attente d'un script

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    //a mettre au début du script
    ini_set('max_execution_time',300 ); //5 minutes
    sinon :
    http://travaux.ovh.net/?do=details&id=5332

  9. #9
    Membre averti
    Inscrit en
    Avril 2010
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 35
    Par défaut
    En gros le fichier se présente comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    ARTICLE;XXX;XX;XX;...;...;...;...;...;...;...;...;
    ARTMAG;XXX;XX;XXX;01;...;...;...;...;...;...;...;...;
    ARTMAG;XXX;XX;XXX;02;...;...;...;...;...;...;...;...;
    ARTMAG;XXX;XX;XXX;03;...;...;...;...;...;...;...;...;
    ARTMAG;XXX;XX;XXX;04;...;...;...;...;...;...;...;...;
    ARTMAG;XXX;XX;XXX;05;...;...;...;...;...;...;...;...;
    ARTMAG;XXX;XX;XXX;06;...;...;...;...;...;...;...;...;
    ARTMAG;XXX;XX;XXX;07;...;...;...;...;...;...;...;...;
    ARTMAG;XXX;XX;XXX;08;...;...;...;...;...;...;...;...;
    ARTMAG;XXX;XX;XXX;09;...;...;...;...;...;...;...;...;
    ARTMAG;XXX;XX;XXX;10;...;...;...;...;...;...;...;...;
    Il y a un article, vendu dans plusieurs magasins (mais pas toujours tous).
    Je ne m'intéresse qu'au magasin 10.
    Avant la moulinette cherchait une ligne ARTMAG donc le code magasin était 10, et refaisait une boucle pour trouver la ligne ARTICLE identifiée par son code article (les données marquées par des XXX;XX;XXX).

    J'ai modifié ce script pour permettre de ne faire qu'une seule boucle, donc maintenant je recherche d'abord la ligne ARTICLE, et j'exécute le code seulement si la ligne ARTMAG avec le numéro 10 suit (comme dans l'exemple ci-dessus).

    Le problème est que ma boucle permettant de rechercher cette ligne ARTMAG s'arrête quand elle trouve une ligne ARTICLE (l'article suivant). Donc je reviens dans une boucle de plus haut niveau (celle qui cherche les lignes ARTICLE). Le truc c'est que comme le pointeur a déjà passé la ligne article (à cause du while de plus bas niveau), je loupe un article sur deux.

    Voilà pour les explications :p
    J'ai volontairement mis les données en "XXX" ou "..." car je ne sais pas si j'ai le droit de divulguer ça. Bref, ça ne pose pas de problème de toute manière.

    Merci !


    Edit : bon j'ai l'air d'avoir trouvé. Sauf qu'apparemment le script est toujours trop long et dépasse les 30 secondes. 70Mo le fichier texte quand même ! Je dois lire toutes les lignes.
    Je ne sais pas trop comment faire...

    Je pense qu'en attendant je vais rapatrier la base de données sur mon ordinateur, la mettre à jour et réimporter la base, je ne vois que ça.

  10. #10
    Membre Expert
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    1 349
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 349
    Par défaut
    donc mon code devrais te convenir

Discussions similaires

  1. Plusieurs vues sur un même fichier
    Par minicat dans le forum Eclipse Java
    Réponses: 4
    Dernier message: 05/05/2014, 22h53
  2. [Toutes versions] Boucle rechercheV sur plusieurs fichiers
    Par legenuis dans le forum Macros et VBA Excel
    Réponses: 19
    Dernier message: 22/11/2011, 22h27
  3. [BASH] boucle for sur des fichiers, recuperation du chemin ?
    Par zevince dans le forum Shell et commandes GNU
    Réponses: 13
    Dernier message: 13/11/2007, 11h47
  4. ouverture d'un programme par double clic sur un fichier
    Par zieg18 dans le forum Visual C++
    Réponses: 6
    Dernier message: 12/07/2006, 11h02
  5. fopen sur un fichier en réseau local
    Par Invité dans le forum Langage
    Réponses: 6
    Dernier message: 12/01/2006, 18h32

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo