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

Symfony PHP Discussion :

Le Composant « Process » [2.x]


Sujet :

Symfony PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Inscrit en
    Septembre 2012
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2012
    Messages : 44
    Par défaut Le Composant « Process »
    Bonjour,

    Je recherche un moyen d'exécuter une commande en arrière plan.

    Je veux pouvoir avec un lien, démarrer une comparaison entre le contenu d'un dossier de photos et les photos déjà enregistrée en BDD. Puis récupérer les infos des nouvelles photos ou de celle qui auraient été modifiée pour mettre à jour la BDD.

    Ceci peut prendre du temps, et je souhaite que celà se fasse en arrière plan sur le serveur afin que je puisse continuer de naviguer sur le site ou même fermer ma fenêtre de navigation.

    J'ai commencé par utiliser un exec() avec une sortie sur un fichier txt mais je me heurte vite à un soucis: la page php que j’exécute dans ma commande est indépendante de symfony, et il me faudrait revenir à un codage classique pour me connecter à ma base de données... Je crois pas être sur la bonne piste...

    En fouinant, je croise le composant "Process" puis "PhpProcess"... Ils semble pouvoir m'aider à faire ce que je veux, mais je trouve pas suffisamment de documentation à ce sujet et je comprend pas bien comment l'utiliser...

    Un peu de code provenant de http://symfony.com/fr/doc/2.3/components/process.html modifié pour mon objectif

    Dans mon controller:

    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
    use Symfony\Component\Process\Process;
     
    public function admin_majAction()
        {
        $chemin=dirname($_SERVER['SCRIPT_FILENAME']).'/img/galerie/script/';
        $process = new Process('php'.$chemin.'maj.php');
        $process->run(function ($type, $buffer) {
            if ('err' === $type) {
                echo 'ERR > '.$buffer;
            } else {
                echo 'OUT > '.$buffer;
            }
        });
        $this->get('session')->getFlashBag()->add('maj', ' => Mise à jour en cours... ');
        return $this->redirect($this->generateUrl('gg_site_admin') );
    }
    Ce que je comprends (ou crois comprendre, vous me corrigerez ) de ce code, c'est que je démarre mon script maj.php grâce à la méthode run. Ce que je saisi pas, c'est cette fonction avec $type et $buffer. C'est elle qui doit pouvoir me permettre d'avoir des retours? Mais où est ce que je peux les récupérer? $type et $buffer, c'est quoi? où et comment dois je les déclarer?

    Dans la doc, ils disent: "Si vous voulez exécuter du code PHP de manière isolée, utilisez plutôt le PhpProcess à la place:"

    Dans ce cas, j'utiliserais plutôt:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    use Symfony\Component\Process\PhpProcess;
     
    public function admin_majAction()
        {
        $chemin=dirname($_SERVER['SCRIPT_FILENAME']).'/img/galerie/script/';
        $process = new PhpProcess(<?php include('$chemin.'maj.php'); ?>);
        $process->run();
    Je suis un peu beaucoup passionnément largué! :/

  2. #2
    Membre expérimenté
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2010
    Messages : 168
    Par défaut
    Essayes avec ce bout de code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    use Symfony\Component\Process\Process;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
                    $process = new Process('ping -c15 127.0.0.1');
                    $t = array();
                    $process->run(function ($type, $buffer) {
                        if ('err' === $type) {
                            echo 'ERR > '.$buffer;
                        } else {
                           echo 'OUT > '.$buffer;
                        }
                    });
    Normalement t'as pas besoin de définir les variables.

    t'as pas oublié un espace après php ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
        $process = new Process('php '.$chemin.'maj.php');

  3. #3
    Membre averti
    Homme Profil pro
    Inscrit en
    Septembre 2012
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2012
    Messages : 44
    Par défaut
    Salut Goabonga,

    Merci pour ton aide!
    En effet, il manquait un espace!

    je vais regarder ton code, mais d'entrée, je me demande ce qu'il va changer? et c quoi le tableau $t?

  4. #4
    Membre émérite
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    725
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2011
    Messages : 725
    Par défaut
    Bonjour,

    Ce lien pourrait t'intéresser
    http://techportal.inviqa.com/2013/11...2-application/

    Pour reprendre sur ta solution initiale:
    $process = new Process('php'.$chemin.'maj.php');
    $process->run(function ($type, $buffer) {
    if ('err' === $type) {
    echo 'ERR > '.$buffer;
    } else {
    echo 'OUT > '.$buffer;
    }
    });
    Tel qu'il est ton code ne vas pas lancer le process en arrière plan, le controlleur va faire des echo de ta commande puis reprendre là oû il en était dans le controlleur (pendant ce temps l'utilisateur attend que sa page se charge), il faut plutôt faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    $cmd='php'.$chemin.'maj.php';
    $process = new Process($cmd);
    $process->start();
    return new Response('le process est lancée');
    D'autre part, ton process aura sans doute besoin de paramétre et service défini dans symfony.
    Plutot que de coder ces traitements dans ton fichier 'maj.php', crée plutôt une commande personalisée:
    http://symfony.com/fr/doc/current/co...e_command.html

    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
     
    namespace My/Bundle/Command;
     
    use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
     
    Class MyCommand extends ContainerAwareCommand{
     
        protected function configure()
        {
            $this
                ->setName('my:command')
                ->setDescription('comparer des répertoires de photo');
        }
     
        protected function execute(InputInterface $input, OutputInterface $output)
        {
            $logger=$this->getContainer()->get('logger');
            $logger->info('début de l execution de  la commande');
            //mon traitement trés long...
            sleep(10);
            $logger->info('fin de l execution de  la commande');
        }
    }
    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
    namespace My/Bundle/Controller;
     
    class MyController{
     
       public function comparaisonAction(){
     
               $logger=$this->get('logger');
               $logger->info('lancement du process depuis le controller');
               $cmd='app/console my:command';//la commande créé ci-dessous
               $process=new Process($cmd);
               $process->start();
               $logger->info('le process a été lancée depuis le controller');
               return new Response('process en cours');
       }
     
    }
    Le service logger va écrire les logs dans app/logs/dev.log,
    consultes ce fichier pour voir la chronologie de l'execution du programme.

  5. #5
    Membre averti
    Homme Profil pro
    Inscrit en
    Septembre 2012
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2012
    Messages : 44
    Par défaut
    Super! Merci Arnooo pour cette piste prometteuse!

    Mais je n'arrive pas a voir s'il se passe quelque chose. Au niveau de ma commande, je n'ai aucun retour dans les logs! :/

    Seul ceux de mon controller apparaissent.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    [2013-12-07 20:08:26] app.INFO: lancement du process depuis le controller [] []
    [2013-12-07 20:08:26] app.INFO: le process a été lancée depuis le controller [] []
    Mon contrôleur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public function admin_majAction()
        {
            //...
     
            $logger=$this->get('logger');
            $logger->info('lancement du process depuis le controller');
            $cmd='app/console photo:maj';//la commande créé ci-dessous
            $process=new Process($cmd);
            $process->start();
            $logger->info('le process a été lancée depuis le controller');
            //return new Response('process en cours');
            $this->get('session')->getFlashBag()->add('maj', ' => Mise à jour en cours... ');
            return $this->redirect($this->generateUrl('gg_site_admin') );
        }
    Et ma command:
    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
    <?php
     
    namespace Gg\SiteBundle\Command;
     
    use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
    use Symfony\Component\Console\Input\InputArgument;
    use Symfony\Component\Console\Input\InputInterface;
    use Symfony\Component\Console\Input\InputOption;
    use Symfony\Component\Console\Output\OutputInterface;
     
     
    Class MajCommand extends ContainerAwareCommand{
     
     
        protected function configure()
        {
            $this
                ->setName('photo:maj')
                ->setDescription('Mise à jour de la base de données de photos');
        }
     
        protected function execute(InputInterface $input, OutputInterface $output)
        {
            $logger=$this->getContainer()->get('logger');
            $logger->info('début de l execution de  la commande');
            //mon traitement trés long...
            sleep(10);
            $logger->info('fin de l execution de  la commande');
        }
    }

  6. #6
    Membre émérite
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    725
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2011
    Messages : 725
    Par défaut
    la commande en elle-même fonctionne t'elle en lançant manuellement app/console photo:maj (précédé de php si tu es sur windows)?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    protected function execute(InputInterface $input, OutputInterface $output)
        {
            $output->writeln('debut de ma commande');
            $logger=$this->getContainer()->get('logger');
            $logger->info('début de l execution de  la commande');
            //mon traitement trés long...
            sleep(10);
            $logger->info('fin de l execution de  la commande');
            $output->writeln('fin de ma commande');
        }
    Ensuite lance-la depuis le controller avec ton premier code pour mieux voir ce qui se passe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    $process->run(function(error,$buffer){
    ...
    });

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 01/09/2009, 10h17
  2. Eclipse Process Framework Composer
    Par Hotchotte dans le forum Eclipse
    Réponses: 0
    Dernier message: 10/06/2009, 15h34
  3. [C#] Anomalie du Composant Process
    Par heavydrinker dans le forum Windows Forms
    Réponses: 6
    Dernier message: 18/08/2006, 10h22
  4. Installer ses composants
    Par Geronimo dans le forum C++Builder
    Réponses: 14
    Dernier message: 18/06/2002, 14h51
  5. Re-dimensionnement automatique de composants
    Par ludo_7 dans le forum C++Builder
    Réponses: 10
    Dernier message: 16/05/2002, 16h35

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