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 :

Stdout stdin et exit code entre programmes php


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2014
    Messages
    266
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2014
    Messages : 266
    Par défaut Stdout stdin et exit code entre programmes php
    Bonjour,
    J'utilise un programme principal en ligne de commande :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    php principal_programme.php args1 args2 ...
    ce programme php fait appel à plusieurs reprises à des exécutables appelés à l'aide de passthru(), au moins une dizaine de fois. Ce programme tourne normalement et sans bugs jusqu'à la fin.

    Dans un deuxième temps , afin d'analyser l'exécution complète de celui-ci j'envoie la sortie de script vers un autre programme php qui va simplement parser le texte en sortie de cette façon :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    php principal_programme.php args1 args2 ... | php programme_analyse.php args1 args2
    Lorsque j'exécute cette dernière ligne de commande, principal_programme.php s'interrompt visiblement juste après le 4 eme appel de la fonction passthru() et passe la main à programme_analyse.php alors qu'il est loin d'être terminé. Du coup je n'arrive pas à faire exécuter cette ligne de commande jusqu'à son terme.
    Qu'est ce qui provoque cette interruption ? Y a t il une solution ?

    Merci d'avance.

  2. #2
    Membre éprouvé
    Homme Profil pro
    Webmaster - Développeur/intégrateur web
    Inscrit en
    Septembre 2011
    Messages
    210
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Jura (Franche Comté)

    Informations professionnelles :
    Activité : Webmaster - Développeur/intégrateur web
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2011
    Messages : 210
    Par défaut
    Bonjour,

    Sans avoir vu le code des programmes, voici une solution à prendre en à laisser :

    Plutôt que de passer par un pipe, j'executerais les 2 programmes PHP l'un après l'autre, en sauvegardant le contenu de la sortie du premier programme dans une fichier, puis en analysant le contenu du fichier avec le 2eme programme.

    Voilà mon idée...

  3. #3
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2014
    Messages
    266
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2014
    Messages : 266
    Par défaut
    Merci pour cette idée. C'est une solution qui devrait marcher dans tous les cas effectivement en utilisant une commande complétée par :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    php principal_programme.php args1 args2 > sortie_pr.txt
    une tâche parallèle surveille le fichier sortie_pr et lit le contenu lorsque celui-ci est créé et non nul.

    Mais je cherche à éviter les fichiers c'est mieux, ensuite cela nécessiterait de gérer autant de fichier que d'exécution du programme simultanée et je préfère m'en passer. en fait la difficulté de base est que l'exécution d'une commande dos par php est difficile à contrôler lorsque lancée en tant que processus, ce qui est mon cas c'est pourquoi je fais un pipe qui simplifie les choses.
    Je pense à un problème de taille du buffer php pour le stdout, peut être qu'après plusieurs appel de fonction passthru(), php estime qu'il faut arrêter le processus en cours et envoyer les données vers stdout ? y t il un timeout ?

    Je ne peux pas transmettre le code c'est trop long... mais visiblement c'est passthru() qui arrête le processus, la commande exécutée étant en train d'écrire un fichier, mais une fois cela terminé, php envoie le buffer sur le stdout alors que le programme n'a pas exécuter les instructions qui suivent.

    Voici les dernières lignes qui provoquent l'arrêt :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    	ob_start();
    		$codage_fonc_fic="CP1252";
     
    		$commande=mb_convert_encoding($commande,$codage_fonc_fic,"UTF-8" ); //ajouté car la nom de certains fichiers ne pouvait pas être transmis en ligne de commande
    		passthru($commande,$retour_statut); 
    		$retour_statut=mb_convert_encoding($retour_statut,"UTF-8", "ISO-8859-1");
     
    		$valeur_retour= ob_get_contents();
     
     
    				ob_end_clean();

  4. #4
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2014
    Messages
    266
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2014
    Messages : 266
    Par défaut
    Bonjour,
    Après quelques tests je viens de m'apercevoir en fait que cette commande :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    php principal_programme.php args1 args2 ... | php programme_analyse.php args1 args2
    démarre en premier programme_analyse.php avant principal_programme.php, or je souhaite que programme_analyse.php démarre uniquement lorsque principal_programme.php a terminé son exécution, y a t il une option pour cela ?

    Sinon l'interruption proviendrait en fait des données lues sur le stdin par programme_analyse.php. J'utilise normalement le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $fp=fopen("php://stdin","r");
    $donnees_filtrees=stream_get_contents($fp);
    Mais visiblement si le temps d'exécution est trop long et qu'aucune donnée n'est lue stream_get_contents() se termine au bout d'une 40 aine de secondes.

    En utilisant une boucle :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    				while((microtime(true)-$temps_initial)*1000000<$time_out_usec && !feof($fp)){
    					$donnees_filtrees=$donnees_filtrees.stream_get_line(STDIN,8192,PHP_EOL);			
    				}
    Cette fois c'est l'exécution de programme_analyse.php qui bloque même si principal_programme.php se termine normalement...

  5. #5
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2014
    Messages
    266
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2014
    Messages : 266
    Par défaut
    Après pas mal d'essai de différentes fonctions j'ai réussi à trouver une solution qui marche parfaitement à insérer bien sûr dans le programme_analyse.php

    pour lire les données STDIN sans blocage grâce notamment à l'stream_get_line() et l'utilisation de is_resource() qui ont débloqué le code :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    $donnees_filtrees="";
    $fp=fopen("php://stdin","rb");
    stream_set_read_buffer($fp,0);		 //peut être inutile ?
    stream_set_timeout($fp,5000); // peut être inutile ?
    $time_out_usec=1000000000;
    $lecture=stream_get_line($fp,8192);
    while((microtime(true)-$temps_initial)*1000000<$time_out_usec && $lecture!==FALSE && is_resource($fp)){
    		$donnees_filtrees=$donnees_filtrees.$lecture;		
    		echo $lecture;
    		$lecture=stream_get_line($fp,8192);	
    }

    [EDIT]
    A préciser :
    J'ai ajouté à la ligne de commande la commande exit comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    php principal_programme.php args1 args2 && EXIT | php programme_analyse.php args1 args2

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

Discussions similaires

  1. Protection du code source - Programme PHP
    Par safener dans le forum Cloud Computing
    Réponses: 0
    Dernier message: 01/08/2014, 19h29
  2. Communication entre programme c et php
    Par dashed dans le forum C
    Réponses: 2
    Dernier message: 10/06/2013, 18h40
  3. ffmpeg-php exit code 255
    Par italya dans le forum Bibliothèques et frameworks
    Réponses: 0
    Dernier message: 18/10/2012, 13h58
  4. [MySQL] Problème dans mon code entre une recherche mysql et en php
    Par pasbonte dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 27/12/2008, 14h04
  5. communication entre programmes
    Par jérôme dans le forum C
    Réponses: 12
    Dernier message: 16/04/2002, 08h05

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