Question

J'essaie de créer un script PHP. J'ai terminé le script, mais le processus pour lequel il a été conçu prend environ 10 minutes. Ce n’est pas un problème, mais je suppose que je dois garder la page chargée tout ce temps, ce qui est agaçant. Puis-je l'avoir pour que je commence le processus, puis que je revienne 10 minutes plus tard et que je voie le fichier journal qu'il a généré?

Était-ce utile?

La solution

Vous pouvez utiliser " ignore_user_abort (true) & ";

Le script continuera donc à fonctionner (gardez un œil sur la durée du script, ajoutez peut-être & " set_time_limit (0) ")

Mais voici un avertissement: vous ne pourrez pas arrêter un script avec ces deux lignes:

ignore_user_abort(true); 
set_time_limit(0);

Sauf que vous pouvez accéder directement au serveur et y mettre fin au processus! (Été là-bas, fait une boucle sans fin, s’appelant lui-même encore et encore, faisant en sorte que le serveur s’arrête en cri, se faisant crier dessus ...)

Autres conseils

On dirait que vous devriez avoir une file d'attente et un script externe pour le traitement de la file d'attente.

Par exemple, votre script PHP doit insérer une entrée dans une table de base de données et y revenir immédiatement. Ensuite, un cron lancé toutes les minutes vérifie la file d'attente et lance un processus pour chaque travail.

L’avantage ici est que vous ne verrouillez pas un thread Apache pendant 10 minutes.

J'ai eu beaucoup de problèmes avec ce genre de processus sous Windows; Ma situation était un peu différente dans la mesure où je me fichais de la réponse du & Quotient & Quot; - je voulais que le script démarre et autorise d'autres requêtes de page à passer alors qu'il était occupé à travailler .

Pour une raison quelconque; J'ai eu des problèmes avec soit suspendre d'autres demandes ou de délai d'attente après environ 60 secondes (Apache et PHP ont été définies pour expirer après environ 20 minutes); Il s'avère également que firefox expire au bout de 5 minutes (par défaut), de sorte que vous ne pourrez plus savoir ce qui se passe dans le navigateur sans modifier les paramètres de firefox.

J'ai fini par utiliser les méthodes open et process close pour ouvrir un php en mode CLI comme suit:

pclose(popen("start php myscript.php", "r"));

Ceci (avec start) ouvrirait le processus php, puis tuerait le processus de démarrage en laissant php fonctionner aussi longtemps que nécessaire - encore une fois, il faudrait tuer le processus pour le fermer manuellement. Il n'était pas nécessaire que vous définissiez des délais d'attente et vous pouviez laisser la page actuelle qui l'appelait continuer et afficher quelques détails supplémentaires.

Le seul problème avec cela est que si vous devez envoyer des données au script, vous le feriez soit via une autre source, soit via le & "ligne de commande &"; comme paramètres; qui n'est pas si sécurisé.

a bien fonctionné pour ce dont nous avions besoin et garantit que le script démarre toujours et est autorisé à s'exécuter sans interruption.

Cela peut également vous aider: Exécution de shell asynchrone en PHP

Je pense que la commande shell_exec est ce que vous recherchez.

Cependant, il est désactivé en mode sans échec.

L'article du manuel PHP à ce sujet est disponible à l'adresse suivante: http://php.net/shell_exec

Vous trouverez un article à ce sujet ici: http://nsaunders.wordpress.com/2007/01/12/running-a-background-process-in-php/

Il existe une autre option que vous pouvez utiliser, exécutez le script CLI ... Il s’exécutera en arrière-plan et vous pourrez même l’exécuter sous forme de tâche cron si vous le souhaitez.

exemple

> #!/usr/bin/php -q

<?php

//process logs

?>

Ceci peut être configuré en tant que travail cron et s’exécutera sans limitation dans le temps. Cet exemple s’applique cependant au système d’exploitation basé sur Unix.

FYI J'ai un script php fonctionnant avec une boucle infinie qui effectue un certain traitement et qui fonctionne depuis 3 mois sans interruption.

Vous pouvez utiliser ignore_user_abort() pour que le script continue de s'exécuter même si vous fermez votre navigateur ou accédez à une autre page.

Pensez à Gearman

  

Gearman est un cadre d’application générique pour la gestion de travaux   plusieurs machines ou processus. Il permet aux applications de compléter   tâches en parallèle, pour traiter la charge et appeler des fonctions   entre les langues. Le cadre peut être utilisé dans une variété de   applications, des sites Web à haute disponibilité au transport de   événements de réplication de base de données.

     

Cette extension fournit des classes pour écrire des clients Gearman et   travailleurs.   - Manuel php source

Site officiel de Gearman

Outre la réponse de bastiandoeen, vous pouvez combiner ignore_user_abort(true); avec une demande cUrl .

Faux avortement de requête en établissant un faible CURLOPT_TIMEOUT_MS et maintien du traitement après la fermeture de la connexion:

function async_curl($background_process=''){

    //-------------get curl contents----------------

    $ch = curl_init($background_process);
    curl_setopt_array($ch, array(
        CURLOPT_HEADER => 0,
        CURLOPT_RETURNTRANSFER =>true,
        CURLOPT_NOSIGNAL => 1, //to timeout immediately if the value is < 1000 ms
        CURLOPT_TIMEOUT_MS => 50, //The maximum number of mseconds to allow cURL functions to execute
        CURLOPT_VERBOSE => 1,
        CURLOPT_HEADER => 1
    ));
    $out = curl_exec($ch);

    //-------------parse curl contents----------------

    //$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
    //$header = substr($out, 0, $header_size);
    //$body = substr($out, $header_size);

    curl_close($ch);

    return true;
}

async_curl('http://example.com/background_process_1.php');

NB

  

Si vous souhaitez que cURL expire en moins d’une seconde, vous pouvez utiliser   CURLOPT_TIMEOUT_MS, bien qu'il y ait un bogue / & "Feature &"; sur & "Unix-like"   systèmes " libcurl expirera immédiatement si la valeur est <   1000 ms avec l'erreur & Quot; erreur cURL (28): le délai d'attente a été atteint & Quot ;. le   explication de ce comportement est:

     

[...]

     

La solution consiste à désactiver les signaux à l'aide de CURLOPT_NOSIGNAL

pros

  • Inutile de changer de méthode (Windows compatible & amp; linux)
  • Pas besoin d'implémenter la gestion de la connexion via des en-têtes et des tampons (indépendante du navigateur et de la version de PHP)

inconvénients

  • Besoin d'une extension de boucle

Ressources

Zuk.

Je suis à peu près sûr que cela fonctionnera:

<?php 

pclose(popen('php /path/to/file/server.php &'));
echo "Server started. [OK]"; 

?>

Le '& amp;' est important. Il indique au shell de ne pas attendre la fin du processus.

Aussi, vous pouvez utiliser ce code dans votre php (comme & "; bastiandoeen &" dit)

.
ignore_user_abort(true); 
set_time_limit(0);

dans votre commande d'arrêt du serveur:

<?php

$output;
exec('ps aux | grep -ie /path/to/file/server.php | awk \'{print $2}\' | xargs kill -9 ', $output);
    echo "Server stopped. [OK]";

?>

Appelez simplement StartBuffer () avant toute sortie et EndBuffer () lorsque vous souhaitez que le client ferme la connexion. Le code après l'appel de EndBuffer () sera exécuté sur le serveur sans connexion client.

    private function StartBuffer(){
        @ini_set('zlib.output_compression',0);
        @ini_set('implicit_flush',1);
        @ob_end_clean();
        @set_time_limit(0);
        @ob_implicit_flush(1);
        @ob_start();
    }

    private function EndBuffer(){
        $size = ob_get_length();
        header("Content-Length: $size");
        header('Connection: close');
        ob_flush();ob_implicit_flush(1);
    }

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top