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 :

Exécuter un script php en background ou en parallèle


Sujet :

Langage PHP

  1. #1
    Membre expérimenté
    Avatar de randriano
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 218
    Points : 1 437
    Points
    1 437
    Par défaut Exécuter un script php en background ou en parallèle
    Bonjour,

    J'ai développé une application web qui traite de gros fichiers Excel. Le terme que l'on utiliser c'est "ventiler", "ventilation" fichier Excel.
    Le souci c'est qu'une opération de ventilation prenne des heures (de 30 mn à 3 heures), c'est possible en utilisant set_time_limit(0) dans le script.

    Le but c'est que le lancement de ce script ne bloque pas l'utilisation de l'interface graphique de l'application, ce qui est le cas actuellement car il faut attendre que le fichier php soit totalement exécuté avant que le site soit utilisable. Le but est donc: quand on clique sur le bouton "ventiler", le script correspondant soit exécuté séparément et l'interface graphique demeure utilisable pour d'autres taches.

    Oui, je sais, multithread sous PHP, ça n'existe pas. Mais quelle serait la solution équivalente?

    merci d'avance!
    randriano.dvp.com
    Développeur. Product Owner [Agile]. Sites web, mobile apps, système d'information (SI).

  2. #2
    Membre éprouvé Avatar de tdutrion
    Homme Profil pro
    Architecte technique
    Inscrit en
    Février 2009
    Messages
    561
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 561
    Points : 1 105
    Points
    1 105
    Par défaut
    Bonjour,

    Personnellement dans un cas comme ça j'aurais tendance à utiliser un script PHP en console (cli) en utilisant exec ou system.

  3. #3
    Membre expérimenté
    Avatar de randriano
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 218
    Points : 1 437
    Points
    1 437
    Par défaut
    Merci pour ces fonctions
    mais ma question c'est est-ce que ces fonctions laissent la commande s'exécuter en arrière-plan ou bien il faut attendre que la commande finisse pour passer à l'instruction suivante?

    J'ai lu une note du manuel PHP:
    Note:

    Si vous démarrez un programme en utilisant cette fonction et que vous voulez le laisser tourner en arrière plan, vous devez vous assurer que la sortie du programme est redirigée vers un fichier, ou un autre flux de sortie, sinon PHP attendra jusqu'à la fin de l'exécution du programme
    Comment mettre un flux de sortie?
    randriano.dvp.com
    Développeur. Product Owner [Agile]. Sites web, mobile apps, système d'information (SI).

  4. #4
    Membre actif
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2012
    Messages
    131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2012
    Messages : 131
    Points : 242
    Points
    242
    Par défaut
    Bonjour,

    essaye de declancher le traitement via Ajax
    +
    http://php.net/manual/en/function.ignore-user-abort.php

  5. #5
    Membre expérimenté
    Avatar de randriano
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 218
    Points : 1 437
    Points
    1 437
    Par défaut
    Ajax ou pas, cela ne fera-t-il pas planter le navigateur si l'ajax ne se terminera qu'au bout de 30 mn à 3h la durée d'exécution du script php.

    La fonction ignore_user_abort() est intéressant mais je ne crois pas que c'est ce qui me convient dans mon problème non?
    randriano.dvp.com
    Développeur. Product Owner [Agile]. Sites web, mobile apps, système d'information (SI).

  6. #6
    Expert éminent
    Avatar de transgohan
    Homme Profil pro
    Développeur Temps réel Embarqué
    Inscrit en
    Janvier 2011
    Messages
    3 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Temps réel Embarqué

    Informations forums :
    Inscription : Janvier 2011
    Messages : 3 146
    Points : 9 386
    Points
    9 386
    Par défaut
    Un flux de sortie pour une commande linux c'est ainsi :
    Tu rediriges ainsi le flux vers un fichier qui ne conserve rien en mémoire (mais prévu pour).

    Le plus simple reste d'effectuer une requête Ajax pour lancer le script sans attendre de retour.
    Dans ton script tu peux utiliser une variable de session pour indiquer l'avancement.
    Et tu peux donc faire un second script renvoyant la valeur de cette variable appelé via une requête Ajax périodique.

    Ainsi pas de souci.

    « Toujours se souvenir que la majorité des ennuis viennent de l'espace occupé entre la chaise et l'écran de l'ordinateur. »
    « Le watchdog aboie, les tests passent »

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

    Informations forums :
    Inscription : Février 2005
    Messages : 2 021
    Points : 2 278
    Points
    2 278
    Par défaut
    Juste pour attirer l'attention sur le fait qu'Ajax en asynchrone fera bosser le même processus que celui qui sert toutes les pages, ce qui peut tendre vers un goulot d'étranglement dans le cas de multiples traitements lourds simultanés, contrairement à l'exécution via ligne de commande. Dans le cas où un seul traitement à la fois est permis, il semblerait judicieux d'utiliser un flag commun à tous les utilisateurs.
    Vive les roues en pierre

  8. #8
    Membre éprouvé Avatar de tdutrion
    Homme Profil pro
    Architecte technique
    Inscrit en
    Février 2009
    Messages
    561
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 561
    Points : 1 105
    Points
    1 105
    Par défaut
    En gros pour appeler en console sans bloquer le processus courant, j'ai utilisé la syntaxe suivante la dernière fois:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    $cmd = escapeshellcmd('exec /usr/bin/php script.php');
    $dest = '/out.txt';
    popen("$cmd > $dest 2>&1 &", 'r');
    Par contre ça marche que sur Linux, et pas sur tous les hébergements... Mais sinon c'est une bonne solution.

  9. #9
    Membre expérimenté
    Avatar de randriano
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 218
    Points : 1 437
    Points
    1 437
    Par défaut
    Citation Envoyé par transgohan Voir le message
    Le plus simple reste d'effectuer une requête Ajax pour lancer le script sans attendre de retour.
    Dans ton script tu peux utiliser une variable de session pour indiquer l'avancement.
    Et tu peux donc faire un second script renvoyant la valeur de cette variable appelé via une requête Ajax périodique.

    Ainsi pas de souci.
    Je vais donc essayer la solution de l'Ajax "qui n'attend pas de retour".

    Djakisback > Pour l'Ajax périodique pour suivre l'avancement, je crois qu'il n'y aura pas de problème d'étranglement car c'est ce que fais les sites plein d'Ajax comme GMail, Facebook, etc. non??
    randriano.dvp.com
    Développeur. Product Owner [Agile]. Sites web, mobile apps, système d'information (SI).

  10. #10
    Expert éminent
    Avatar de transgohan
    Homme Profil pro
    Développeur Temps réel Embarqué
    Inscrit en
    Janvier 2011
    Messages
    3 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Temps réel Embarqué

    Informations forums :
    Inscription : Janvier 2011
    Messages : 3 146
    Points : 9 386
    Points
    9 386
    Par défaut
    Citation Envoyé par randriano Voir le message
    Je vais donc essayer la solution de l'Ajax "qui n'attend pas de retour".

    Djakisback > Pour l'Ajax périodique pour suivre l'avancement, je crois qu'il n'y aura pas de problème d'étranglement car c'est ce que fais les sites plein d'Ajax comme GMail, Facebook, etc. non??
    Non il a raison, ce serait mieux de lancer un exec sur PHP CLI en fait.
    Ainsi tu utiliseras un autre processus.

    « Toujours se souvenir que la majorité des ennuis viennent de l'espace occupé entre la chaise et l'écran de l'ordinateur. »
    « Le watchdog aboie, les tests passent »

  11. #11
    Membre expérimenté
    Avatar de randriano
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 218
    Points : 1 437
    Points
    1 437
    Par défaut
    Citation Envoyé par transgohan Voir le message
    Non il a raison, ce serait mieux de lancer un exec sur PHP CLI en fait.
    Ainsi tu utiliseras un autre processus.
    Ah, ok!

    Peux-tu me montrer comment faire? Un code PHP en soutien avec redirection vers un flux de sortie.
    Merci d'avance!
    randriano.dvp.com
    Développeur. Product Owner [Agile]. Sites web, mobile apps, système d'information (SI).

  12. #12
    Expert éminent
    Avatar de transgohan
    Homme Profil pro
    Développeur Temps réel Embarqué
    Inscrit en
    Janvier 2011
    Messages
    3 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Temps réel Embarqué

    Informations forums :
    Inscription : Janvier 2011
    Messages : 3 146
    Points : 9 386
    Points
    9 386
    Par défaut
    Un exemple ?
    Citation Envoyé par Théocrite Voir le message
    En gros pour appeler en console sans bloquer le processus courant, j'ai utilisé la syntaxe suivante la dernière fois:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    $cmd = escapeshellcmd('exec /usr/bin/php script.php');
    $dest = '/out.txt';
    popen("$cmd > $dest 2>&1 &", 'r');
    Par contre ça marche que sur Linux, et pas sur tous les hébergements... Mais sinon c'est une bonne solution.

    « Toujours se souvenir que la majorité des ennuis viennent de l'espace occupé entre la chaise et l'écran de l'ordinateur. »
    « Le watchdog aboie, les tests passent »

  13. #13
    Membre expérimenté
    Avatar de randriano
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 218
    Points : 1 437
    Points
    1 437
    Par défaut
    Comme l'a dit Théocrite, cela ne marche que sur Linux et de plus pas sur tous les hébergements. Je suis sous Windows!
    randriano.dvp.com
    Développeur. Product Owner [Agile]. Sites web, mobile apps, système d'information (SI).

  14. #14
    Expert éminent
    Avatar de transgohan
    Homme Profil pro
    Développeur Temps réel Embarqué
    Inscrit en
    Janvier 2011
    Messages
    3 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Temps réel Embarqué

    Informations forums :
    Inscription : Janvier 2011
    Messages : 3 146
    Points : 9 386
    Points
    9 386
    Par défaut
    exec : http://fr2.php.net/manual/fr/function.exec.php
    ou bien en plus contrôlé : http://fr2.php.net/manual/fr/function.proc-open.php
    Quand à la redirection de flux sous windows c'est comme sous unix pour la sortie normale à savoir : cmd > fichier

    Quand à ne pas fonctionner sur tous les hébergeurs je pense que c'est davantage du à un problème de droit qu'autre chose. Sur un hébergement mutualisé tu peux par exemple oublier le lancement de processus. ^^

    « Toujours se souvenir que la majorité des ennuis viennent de l'espace occupé entre la chaise et l'écran de l'ordinateur. »
    « Le watchdog aboie, les tests passent »

  15. #15
    Membre expérimenté
    Avatar de randriano
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 218
    Points : 1 437
    Points
    1 437
    Par défaut
    J'ai fait comme suit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <?php
    	$IndexPath = BASEPATH . "index.php";
    	// SOUS WINDOWS > NUL
    	$cmd = "php " . $IndexPath . " chargements runloading > NUL";
     
    	exec($cmd);
     
    	// beaucoup d'autres taches
    	// .....
    ?>
    Mais la page se recharge toujours, donc la commande ne s'exécute pas en arrière-plan comme je l’espérais. Sur le navigateur, la page a la barre de chargement qui tourne!!!
    randriano.dvp.com
    Développeur. Product Owner [Agile]. Sites web, mobile apps, système d'information (SI).

  16. #16
    Expert éminent
    Avatar de transgohan
    Homme Profil pro
    Développeur Temps réel Embarqué
    Inscrit en
    Janvier 2011
    Messages
    3 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Temps réel Embarqué

    Informations forums :
    Inscription : Janvier 2011
    Messages : 3 146
    Points : 9 386
    Points
    9 386
    Par défaut
    Et si tu enlèves tes "beaucoups d'autres tâches" ?
    De plus je reste assez sceptique concernant les arguments se trouvant après ton index.php
    Ce sont des arguments que tu souhaites passer à ton script ?
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <?php
    	$IndexPath = BASEPATH . "index.php";
    	// SOUS WINDOWS > NUL
    	$cmd = "php " . $IndexPath . "?chargements&runloading > NUL";
    Que se passe-t-il si tu appelles ton script directement (sans Ajax) ? Met-il du temps à s'exécuter ?

    « Toujours se souvenir que la majorité des ennuis viennent de l'espace occupé entre la chaise et l'écran de l'ordinateur. »
    « Le watchdog aboie, les tests passent »

  17. #17
    Membre expérimenté
    Avatar de randriano
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 218
    Points : 1 437
    Points
    1 437
    Par défaut
    Si c'est ça le but, on n'attends pas que la commande exécutée avec exec() soit finie, il faut passer tout de suite à "beaucoup d'autres tâches". La commande peut mettre 30 mn à 3 heures à s'exécuter.

    Ne t'inquiète pas, il n'y a pas de problème avec la syntaxe de la commande, c'est du CodeIgniter, ces arguments sont corrects.

    Si je lance exec() en Ajax avec la fonction post() de JQuery, bien que l'indication de chargement de l'onglet Firefox ne s'affiche pas, en regardant avec Firefox dans le console, il y a un script Ajax qui tourne sans arrêt malgré le fait que je lance bien un Ajax sans attente de retour:
    Example: Request the test.php page and send some additional data along (while still ignoring the return results).
    Code js : Sélectionner tout - Visualiser dans une fenêtre à part
    $.post("test.php", { name: "John", time: "2pm" } );
    randriano.dvp.com
    Développeur. Product Owner [Agile]. Sites web, mobile apps, système d'information (SI).

  18. #18
    Expert éminent
    Avatar de transgohan
    Homme Profil pro
    Développeur Temps réel Embarqué
    Inscrit en
    Janvier 2011
    Messages
    3 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Temps réel Embarqué

    Informations forums :
    Inscription : Janvier 2011
    Messages : 3 146
    Points : 9 386
    Points
    9 386
    Par défaut
    Cela me semblait juste bizarre de voir de la réécriture d'url à base d'espace.

    Pour vérifier que ce n'est pas le code Ajax qui est incriminé tentes de lancer le code PHP directement et ce sans ton code des autres tâches.
    Si tu te prends un timeout (si à 30sec dans ton php.ini) ou bien qu'il charge indéfiniment c'est que exec attend malgré la redirection du flux la fin de la commande.

    Mais sinon je ne comprends pas la remarque :
    Si c'est ça le but, on n'attends pas que la commande exécutée avec exec() soit finie, il faut passer tout de suite à "beaucoup d'autres tâches". La commande peut mettre 30 mn à 3 heures à s'exécuter.
    Tes beaucoup d'autres tâches s'exécutent elles aussi en 30min / 3h ? Ou bien c'est juste des scripts web qui laisserons bien la réponse HTTP revenir dans les délais vers le navigateur ?

    « Toujours se souvenir que la majorité des ennuis viennent de l'espace occupé entre la chaise et l'écran de l'ordinateur. »
    « Le watchdog aboie, les tests passent »

  19. #19
    Membre expérimenté
    Avatar de randriano
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 218
    Points : 1 437
    Points
    1 437
    Par défaut
    Non, ces autres tâches ne durent pas aussi longtemps! Pour info, mes time_out sont déjà élevés, de plus j'utilise set_limit_time(0) !

    Vu qu'utiliser Ajax ne serait pas performant car utilisant le même processus que la page en cours et que se passerait-il si on ferme la page, comment faire pour ne pas avoir la page en chargement quand on clique sur le bouton qui lancera exec() ??
    randriano.dvp.com
    Développeur. Product Owner [Agile]. Sites web, mobile apps, système d'information (SI).

  20. #20
    Expert éminent
    Avatar de transgohan
    Homme Profil pro
    Développeur Temps réel Embarqué
    Inscrit en
    Janvier 2011
    Messages
    3 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Temps réel Embarqué

    Informations forums :
    Inscription : Janvier 2011
    Messages : 3 146
    Points : 9 386
    Points
    9 386
    Par défaut
    Si ton script PHP appelé via Ajax se termine tu ne devrai pas avoir cet icone de chargement (malgré l'exécution parallèle du exec).
    C'est pour cela que je t'ai demandé si le script se terminai bien lorsque tu l'appelais dans un onglet.

    Sinon Ajax utilise bien le même processus, mais pas PHP CLI appelé via ton exec.

    « Toujours se souvenir que la majorité des ennuis viennent de l'espace occupé entre la chaise et l'écran de l'ordinateur. »
    « Le watchdog aboie, les tests passent »

Discussions similaires

  1. Exécuter un script PHP CLI en background
    Par newty dans le forum Langage
    Réponses: 1
    Dernier message: 24/05/2011, 22h08
  2. Réponses: 10
    Dernier message: 06/03/2007, 11h07
  3. Réponses: 3
    Dernier message: 26/02/2007, 19h19
  4. [AJAX] XMLHTTPRequest => impossible d'exécuter tout script php
    Par AzertyH dans le forum Général JavaScript
    Réponses: 12
    Dernier message: 24/11/2006, 19h01
  5. [FLASH MX2004] Exécution de script PHP
    Par dleu dans le forum Flash
    Réponses: 2
    Dernier message: 30/03/2005, 19h10

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