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 :

SplFileObject et fgets [PHP 5.3]


Sujet :

Langage PHP

  1. #1
    Membre éclairé
    Avatar de ArKam
    Inscrit en
    Mars 2007
    Messages
    528
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations forums :
    Inscription : Mars 2007
    Messages : 528
    Points : 679
    Points
    679
    Par défaut SplFileObject et fgets
    Bien le bonjour,

    décidément aujourd'hui je ne rencontre que des soucis avec php

    En effet, j'essaye d’éditer un fichier grâce à une boucle foreach un objet SplFileObject.

    Le hic c'est que cette boucle me lit qu'une ligne sur deux au lieu de lire toutes les lignes.

    Je me suis dit que c’était mon fichier qui était mal formaté, j'ai donc décider de faire un script qui vas écrire puis lire le dit fichier et là oh magie, j'ai le même souci.

    En effet, bien que le fichier soit écrit correctement, je ne parviens à lire qu'une ligne sur deux, et encore, quand je met le flag setFlags(SplFileObject::SKIP_EMPTY);

    sinon j'ai mes lignes (toujours une sur deux) et un beau runtime exception qui me remonte seulement le fait que php ne parvient pas à lire le fichier alors qu'il m'écrit bien mes lignes précédentes

    Bref, si vous avez une idée, voici le code (on sait jamais).

    Lecture du fichier:
    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
     
    <?php
    //		-		READ_TEMPLATE_USER_CONFIG		-		//
     
    $user_config_template = '/home/users_config/template';
     
    function template($user_config_template){
     
    $user_config = '/home/users_config/';
    $login = 'template';
    switch (is_readable($user_config_template)) {
     
    	case true:
    			try{
    			$user_config_file = new SplFileObject($user_config.$login,"r");
    			$user_config_file->setFlags(SplFileObject::SKIP_EMPTY);
    			}catch(RuntimeException $error){
    			echo 'Exception Runtime Reçue: ', $error->getCode(), "\n";
    			}
     
    			foreach($user_config_file as $line){
    				$current_line = $user_config_file->fgets();
    				echo("$current_line"."<br />");
    			}
    			break;
     
    	case false:
    			echo "this file is not readable: $user_config_template"."<br />";
    			break;
    }
     
    }
     
    template($user_config_template);
    ?>
    Ecriture du fichier:
    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
     
    <?php
    //		-		WRITE_TEMPLATE_USER_CONFIG		-		//
     
    $user_config_template = '/home/users_config/template';
     
    function template($user_config_template){
     
    $config_template = 'anonymous_enable=NO'."\n";
    $config_template .= 'anon_mkdir_write_enable=NO'."\n";
    $config_template .= 'anon_other_write_enable=NO'."\n";
    $config_template .= 'anon_upload_enable=NO'."\n";
    $config_template .= 'write_enable=NO'."\n";
    $config_template .= 'dirlist_enable=YES'."\n";
    $config_template .= 'download_enable=YES'."\n";
    $config_template .= 'local_root=/home/users_home'."\n";
    $config_template .= 'virtual_use_local_privs=YES'."\n";
    $config_template .= 'local_umask=022'."\n";
     
    $user_config = '/home/users_config/';
    $login = 'template';
     
    try{
    	$user_config_file = new SplFileObject($user_config.$login,"c");
    	$user_config_file->setFlags(SplFileObject::SKIP_EMPTY);
    	$user_config_file->fwrite($config_template);
    	}catch(RuntimeException $error){
    	echo 'Exception Runtime Reçue: ', $error->getCode(), "\n";
    	}
     
    }
     
    template($user_config_template);
    ?>

  2. #2
    Membre actif Avatar de Korri
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2008
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2008
    Messages : 158
    Points : 232
    Points
    232
    Par défaut
    Citation Envoyé par ArKam Voir le message
    Bien le bonjour,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    foreach($user_config_file as $line){
    	$current_line = $user_config_file->fgets();
    	echo("$current_line"."<br />");
    }

    Je ne connais pas SplFileObject, mais ce que tu fait la me semble faux.

    Tu parcourt déjà les lignes avec ton foreach, pourquoi re-récupérer la ligne avec fgets ?

    Essaye donc ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    foreach($user_config_file as $current_line) {
    	echo("$current_line"."<br />");
    }
    Au plaisir

  3. #3
    Membre éclairé
    Avatar de ArKam
    Inscrit en
    Mars 2007
    Messages
    528
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations forums :
    Inscription : Mars 2007
    Messages : 528
    Points : 679
    Points
    679
    Par défaut
    Effectivement, je me suis fait la même réflexion étant donné que SplFileObject est un objet itéré.

    Je vais tester sans cet appel à fgets.

    Edit:

    Bon je viens de tester ça fonctionne.
    Je ne sais pas pourquoi le fgets à ce comportement par contre vue que lui ce qu'il fait c'est lire le contenu de son pointeur courant, donc en théorie on est dans une boucle, il devrait être capable de lire toutes les lignes et pas une sur deux.

    PS: Si je me fourvoie, n'hésitez pas à me renseigner

  4. #4
    Membre éclairé
    Avatar de ArKam
    Inscrit en
    Mars 2007
    Messages
    528
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations forums :
    Inscription : Mars 2007
    Messages : 528
    Points : 679
    Points
    679
    Par défaut
    Bien, j'ai bien résolu le souci de lecture de mon foreach, malheureusement, j'ai maintenant un souci avec une comparaison puis modification de string à l'intérieur de cette boucle.

    En effet, j'ai une string A qui doit être comparé à la ligne courante afin de savoir si elles sont identique et le cas échéant modifier la ligne courante pour lui ajouter un morceau en plus.

    Le hic c'est que le script coupe après 30 sec d'activité, ce qui pour moi est normal car la comparaison ne devrait pas être aussi longue.

    Voici mon code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    $user_config_regex = array('local_root' => "{local_root=/home/users_home}", 'rights' => 'write_enable=YES');
     
    foreach($user_config_file as $current_line){
    				if(preg_match($user_config_regex['local_root'],$current_line)){
    					header("location:../pages/okconfig.php");
    					exit;
    				}else{
    					header("location:../pages/noconfig.php");
    					exit;
    				}
    			}
    PS: Les accolades ici sont là pour délimiter le motif à trouver par preg_match.

    J'ai essayer avec un preg_match_all, avec un strpos ou simplement avec $var1 === $var2 mais j'ai toujours le même souci, je ne comprend pas pourquoi le preg_match prend autant de temps alors que je lui demande simplement de comparait le motif de la ligne courante avec le motif patron.

    Sachant que le fichier parsé ne fait que 6 lignes au maximum, ce comportement me parait un peu étrange.

    J'ai surement du encore oublier quelque chose, mais je ne vois pas trop quoi.

  5. #5
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 727
    Points
    10 727
    Par défaut
    fait un preg_replace plutot voir utilise le regexiterator, si tu veux lire un fichier ini utilise le parse_ini_file

  6. #6
    Membre éclairé
    Avatar de ArKam
    Inscrit en
    Mars 2007
    Messages
    528
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations forums :
    Inscription : Mars 2007
    Messages : 528
    Points : 679
    Points
    679
    Par défaut
    Je vais tester le preg_replace, par contre, je pense avoir trouvé mon souci.

    En effet je suis dans une boucle foreach, dans laquelle je test si la ligne courante est correspondante, malheureusement, si elle ne l'est pas, le if vas etre faux et passer la main au else, qui lui, se charge de rediriger l'utilisateur.

    Hors, comme le if est faux des le premier test, on sort du script directement, sans parcourir les lignes suivantes.

    Donc j'ai testé avec le script suivant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    foreach($user_config_file as $current_line){
     
    	if(preg_replace($user_config_regex['local_root'],"$user_config_regex['local_root'].'/'.$login",$current_line){
     
    		header("location:../pages/okconfig.php");
    		exit;
    	}
    }
     
    header("location:../pages/noconfig.php");
    exit;
    et ça fonctionne, même si c'est pas très jolie et que des situations spécials intermédiaires peuvent s’immiscer, le principe est là.

  7. #7
    Membre actif Avatar de Korri
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2008
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2008
    Messages : 158
    Points : 232
    Points
    232
    Par défaut
    Citation Envoyé par ArKam Voir le message
    Effectivement, je me suis fait la même réflexion étant donné que SplFileObject est un objet itéré.

    Je vais tester sans cet appel à fgets.

    Edit:

    Bon je viens de tester ça fonctionne.
    Je ne sais pas pourquoi le fgets à ce comportement par contre vue que lui ce qu'il fait c'est lire le contenu de son pointeur courant, donc en théorie on est dans une boucle, il devrait être capable de lire toutes les lignes et pas une sur deux.

    PS: Si je me fourvoie, n'hésitez pas à me renseigner
    Le foreach se charge déjà de lire les lignes (et d'avancer le pointeur à la suivante)

    donc quand tu fait le fgets tu lie la ligne suivante et tu perd celle lue par le foeach (qui doit surement faire appel à fgets en interne).

  8. #8
    Membre éclairé
    Avatar de ArKam
    Inscrit en
    Mars 2007
    Messages
    528
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations forums :
    Inscription : Mars 2007
    Messages : 528
    Points : 679
    Points
    679
    Par défaut
    Citation Envoyé par Korri Voir le message
    Le foreach se charge déjà de lire les lignes (et d'avancer le pointeur à la suivante)

    donc quand tu fait le fgets tu lie la ligne suivante et tu perd celle lue par le foeach (qui doit surement faire appel à fgets en interne).
    Yep, j'ai vue ça en regardant plus en avant le mode de fonctionnement de SplFileObject et SplFileInfo.

    Problème résolu.

    Merci bien

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Dates] fgets(STDIN) timeout ?
    Par FFF dans le forum Langage
    Réponses: 1
    Dernier message: 04/10/2005, 10h58
  2. utilisation de fgets: une question
    Par artatum dans le forum C
    Réponses: 5
    Dernier message: 27/09/2005, 17h27
  3. Réponses: 20
    Dernier message: 25/09/2005, 15h07
  4. gets ,fgets
    Par Zazeglu dans le forum C
    Réponses: 2
    Dernier message: 19/09/2003, 18h24
  5. Problème avec fgets et tube...
    Par tchingoo dans le forum POSIX
    Réponses: 5
    Dernier message: 22/08/2003, 17h03

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