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 :

Éviter le max_execution_time avec un timeout?


Sujet :

Langage PHP

  1. #1
    Membre éclairé Avatar de FrankOVD
    Homme Profil pro
    Directeur des systèmes d'information
    Inscrit en
    Juin 2005
    Messages
    438
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Directeur des systèmes d'information
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Juin 2005
    Messages : 438
    Par défaut Éviter le max_execution_time avec un timeout?
    Bonjour,

    J'ai développé une classe qui dialogue via un socket avec un système comptable et il arrive quelquefois que j'atteigne le max_execution_time de PHP qui est par défaut de 30 secondes. Je pourrais bien sûr augmenter cette valeur avec set_time_limit() ce que j'ai fait temporairement mais je cherche à savoir si il est possible de spécifier un limite de temps à l'exécution d'une ligne de code après quoi il serait possible de gérer l'erreur plutôt que de laisser PHP tout arrêter et afficher son message d'erreur. Voici la fonction en question :

    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
     
      function lire($keys = "") {
        set_time_limit(60);
        $info = stream_get_meta_data($this->handle);
        $buffer = "";
        $output = array();
        stream_set_timeout($this->handle, 15);
        do {
          $lu = fgets($this->handle); //Ligne où le script s'arrête généralement
          $verif = explode(",", $lu);
          if((isset($verif[2]))&&($verif[2] == "ERR")) $this->error($verif[3]);
          $info = stream_get_meta_data($this->handle);
        }
        while((strpos($lu, "Avantage - ") === false)&&(strpos($lu, "LOGIN,OK,") === false)&&(strpos($lu, "OK,END") === false)&&(strpos($lu, "OK,\"") === false)&&($buffer .= $lu));
        $buffer .= $lu;
     
        [...]  
      }
    Il arrive donc que l'exécution de la commande fgets() semble causer le problème. Comme si elle n'arrivait pas à lire la ressource ou si elle ne recevait pas ce qu'elle recherche. Le problème c'est que, comme je ne peut pas gérer l'erreur afin de permettre à mon script de revenir en arrière sur les actions exécutées avant l'échec de la requête, l'erreur laisse un travail à moitié accompli derrière elle.

    Je recherche deux pistes de solution :

    1 - Une meilleure façon de lire les plusieurs lignes renvoyées via le socket où je suis connectée.

    OU

    2 - Une façon de pouvoir gérer le délais d'exécution de fgets()

    Quelqu'un peut m'aider?

  2. #2
    Membre Expert Avatar de Djakisback
    Profil pro
    Inscrit en
    Février 2005
    Messages
    2 023
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 2 023
    Par défaut
    Salut,
    tu es sûr que c'est pas ta boucle qui tourne à l'infini plutôt que l'exécution du fgets() qui plante ?
    Sinon a priori il faudrait que tu testes le retour de stream_get_meta_data().
    Genre ajouter dans ton while :

    Sinon tu dois pouvoir capturer l'erreur de time out en définissant un gestionnaire avec set_error_handler().

  3. #3
    Membre Expert
    Avatar de Seb33300
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2007
    Messages
    1 564
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Thaïlande

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 564
    Par défaut
    A mon avi tu dois pouvoir faire :

    En tout début de script tu enregistre dans une variable le timestamp
    Et ensuite dans ta boucle tu fais un test pour savoir à combien de temps tu es :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if((time()-$debuttime) < XXX){ // XXX à remplacer par le nombre de secondes à ne pas dépasser
    //.. ton code
    }else{
    break;
    }

  4. #4
    Membre éclairé Avatar de FrankOVD
    Homme Profil pro
    Directeur des systèmes d'information
    Inscrit en
    Juin 2005
    Messages
    438
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Directeur des systèmes d'information
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Juin 2005
    Messages : 438
    Par défaut
    Merci pour votre aide.

    Comme le problème n'est survenu à ma connaissance qu'une seule fois au cours des 6 mois de fonctionnement du logiciel, je suppose qu'il me sera plutôt difficile de recréer la situation qui a causé le problème, je vais donc appliquer les validations que vous me proposez et me préparer un moyen de connaître les dernières données envoyées sur le socket en cas d'erreur.

    Merci encore!

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 28/06/2009, 10h03
  2. Réponses: 3
    Dernier message: 13/03/2009, 13h23
  3. Créer une méthode avec un timeout
    Par damien77 dans le forum Débuter avec Java
    Réponses: 35
    Dernier message: 20/02/2009, 16h05
  4. Réponses: 7
    Dernier message: 13/01/2009, 16h59
  5. Réponses: 3
    Dernier message: 07/07/2008, 11h46

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