Question

J'ai un script PHP qui doit invoquer un script shell mais ne se soucie pas du tout de la sortie. Le script shell effectue un certain nombre d'appels SOAP et sa mise au point est lente. Je ne souhaite donc pas ralentir la demande PHP pendant l'attente d'une réponse. En fait, la requête PHP devrait pouvoir quitter sans mettre fin au processus du shell.

J'ai examiné les différentes fonctions exec () , shell_exec () , pcntl_fork () , etc., mais aucune ils semblent offrir exactement ce que je veux. (Ou, s’ils le font, je ne vois pas comment.) Des suggestions?

Était-ce utile?

La solution

S'il ne se soucie pas de la sortie ", l'exécutable du script ne peut-il pas être appelé avec le & amp; pour mettre en arrière-plan le processus?

MODIFIER - en intégrant les commentaires de @ AdamTheHut , vous pouvez les ajouter à un appel à exec :

" > /dev/null 2>/dev/null &"

Cela redirigera stdio (premier > ) et stderr ( 2 > ) vers / dev / null et exécuté en arrière-plan.

Il existe d'autres moyens de faire la même chose, mais c'est la plus simple à lire.

Une alternative à la double redirection ci-dessus:

" &> /dev/null &"

Autres conseils

J'ai utilisé à pour cela, car il s'agit vraiment d'un processus indépendant.

<?php
    `echo "the command"|at now`;
?>

À tous les utilisateurs de Windows: j'ai trouvé un bon moyen d'exécuter un script PHP asynchrone (en réalité, il fonctionne avec presque tout).

Il est basé sur les commandes popen () et pclose (). Et fonctionne aussi bien sous Windows que sous Unix.

function execInBackground($cmd) {
    if (substr(php_uname(), 0, 7) == "Windows"){
        pclose(popen("start /B ". $cmd, "r")); 
    }
    else {
        exec($cmd . " > /dev/null &");  
    }
} 

Code original de: http://php.net/manual/fr/function.exec.php # 86329

Sous Linux, vous pouvez effectuer les opérations suivantes:

$cmd = 'nohup nice -n 10 php -f php/file.php > log/file.log & printf "%u" $!';
$pid = shell_exec($cmd);

Ceci exécutera la commande à l'invite de commande, puis renverra simplement le PID, que vous pouvez vérifier pour > 0 pour que cela fonctionne.

Cette question est similaire: PHP a-t-il des threads?

Le

processus php-execute-a-background- a de bonnes suggestions . Je pense que le mien est très bon, mais je suis partial:)

Sous Linux, vous pouvez démarrer un processus dans un nouveau thread indépendant en ajoutant une esperluette à la fin de la commande

mycommand -someparam somevalue &

Sous Windows, vous pouvez utiliser l’option " start " Commande DOS

start mycommand -someparam somevalue

la bonne façon (!) de le faire est de

  1. fork ()
  2. setsid ()
  3. execve ()

fork forks, setsid indique au processus en cours de devenir maître (pas de parent), execve indique au processus appelant d'être remplacé par le processus appelé. afin que le parent puisse quitter sans affecter l'enfant.

 $pid=pcntl_fork();
 if($pid==0)
 {
   posix_setsid();
   pcntl_exec($cmd,$args,

la bonne façon (!) de le faire est de

  1. fork ()
  2. setsid ()
  3. execve ()

fork forks, setsid indique au processus en cours de devenir maître (pas de parent), execve indique au processus appelant d'être remplacé par le processus appelé. afin que le parent puisse quitter sans affecter l'enfant.

<*>ENV); // child becomes the standalone detached process } // parent's stuff exit();

J'ai utilisé ça ...

/** 
 * Asynchronously execute/include a PHP file. Does not record the output of the file anywhere.  
 * Relies on the PHP_PATH config constant.
 *
 * @param string $filename  file to execute
 * @param string $options   (optional) arguments to pass to file via the command line
 */ 
function asyncInclude($filename, $options = '') {
    exec(PHP_PATH . " -f {$filename} {$options} >> /dev/null &");
}

(où PHP_PATH est un const défini comme define ('PHP_PATH', '/ opt / bin / php5') ou similaire)

Il passe en arguments via la ligne de commande. Pour les lire en PHP, voir argv .

La seule façon pour moi qui a vraiment fonctionné pour moi était:

shell_exec('./myscript.php | at now & disown')

J'ai également trouvé composant de processus Symfony utile. pour cela.

use Symfony\Component\Process\Process;

$process = new Process('ls -lsa');
// ... run process in background
$process->start();

// ... do other things

// ... if you need to wait
$process->wait();

// ... do things after the process has finished

Découvrez son fonctionnement dans son GitHuber repo .

Utilisez un fifo nommé.

#!/bin/sh
mkfifo trigger
while true; do
    read < trigger
    long_running_task
done

Ensuite, chaque fois que vous souhaitez démarrer la tâche longue, il vous suffit d'écrire une nouvelle ligne (non bloquante dans le fichier de déclencheur.

Tant que votre entrée est inférieure à PIPE_BUF et qu'il s'agisse d'une seule opération write () , vous pouvez écrire des arguments dans le fifo et les afficher en tant que $ REPLY dans le script.

Vous pouvez également exécuter le script PHP en tant que démon ou travail cron : #! / usr / bin / php -q

.

sans utiliser la file d'attente, vous pouvez utiliser le proc_open () comme ceci:

    $descriptorspec = array(
        0 => array("pipe", "r"),
        1 => array("pipe", "w"),
        2 => array("pipe", "w")    //here curaengine log all the info into stderror
    );
    $command = 'ping stackoverflow.com';
    $process = proc_open($command, $descriptorspec, $pipes);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top