2016-09-29 11 views
0

J'ai un problème étrange. J'essaie de contourner la mise en tampon de sortie en PHP pour lancer des appels system() et obtenir une sortie instantanée. Cela fonctionne très bien, mais pour une raison étrange, la commande ping sur "test.de" ne présente pas de sortie instantanée comme le fait le ping sur google.de. Je vois la première ligne pour 'ping test.de' dans le shell linux instantanément, mais elle n'apparaît pas instantanément avec ce script. Quelqu'un peut-il aider?PHP se bloquer avec passthru()/system() appel et la mise en mémoire tampon de sortie

<?php 

    // Turn off output buffering 
    ini_set('output_buffering', 'off'); 
    // Turn off PHP output compression 
    ini_set('zlib.output_compression', false); 
    // Implicitly flush the buffer(s) 
    ini_set('implicit_flush', true); 
    ob_implicit_flush(true); 
    // Clear, and turn off output buffering 
    while (ob_get_level() > 0) { 
     // Get the curent level 
     $level = ob_get_level(); 
     // End the buffering 
     ob_end_clean(); 
     // If the current level has not changed, abort 
     if (ob_get_level() == $level) break; 
    } 
    // Disable apache output buffering/compression 
    if (function_exists('apache_setenv')) { 
     apache_setenv('no-gzip', '1'); 
     apache_setenv('dont-vary', '1'); 
    } 

    header('Cache-Control: no-cache'); 

    $i=0; 
    while($i < 1000) { 
    $i++; 
    echo '      '; 
    } 
    echo '<pre>'; 
    echo "Pinging google.de \n\n"; 
    passthru("ping -w 10 -c 4 google.de"); 
    echo "\n\nPinging test.de \n\n"; 
    passthru("ping -w 10 -c 4 test.de"); 
    echo '</pre>'; 
?> 

J'ai marqué la ligne retardée dans cette sortie:

Pinging google.de 

PING google.de (172.217.16.131) 56(84) bytes of data. 
64 bytes from zrh04s06-in-f131.1e100.net (172.217.16.131): icmp_seq=1 ttl=56 time=22.0 ms 
64 bytes from zrh04s06-in-f131.1e100.net (172.217.16.131): icmp_seq=2 ttl=56 time=22.0 ms 
64 bytes from zrh04s06-in-f131.1e100.net (172.217.16.131): icmp_seq=3 ttl=56 time=22.2 ms 
64 bytes from zrh04s06-in-f3.1e100.net (172.217.16.131): icmp_seq=4 ttl=56 time=22.0 ms 

--- google.de ping statistics --- 
4 packets transmitted, 4 received, 0% packet loss, time 3004ms 
rtt min/avg/max/mdev = 22.016/22.067/22.200/0.130 ms 


Pinging test.de 

PING test.de (104.45.6.189) 56(84) bytes of data. <<<< THAT line is delayed!! 

--- test.de ping statistics --- 
11 packets transmitted, 0 received, 100% packet loss, time 9999ms 

Répondre

0

Je pense qu'il est parce que vous utilisez la fonction system() car il ne retourne la dernière ligne. Vous pourriez être mieux adapté en utilisant les fonctions passthru() ou exec(). Voici un grand writeup sur ce que ces fonctions font et leurs différences:

https://stackoverflow.com/a/21016100/1789650

mise à jour basée sur les commentaires

Vous pouvez également essayer annexant un argument de sortie à votre script shell. Ajoutez 2>&1 à la fin de votre ligne et cela placera chaque nouvelle ligne de sortie du shell dans une variable. Voici ce qu'il devrait ressembler à:

exec("ping -w 10 -c 4 google.de 2>&1", $output); 
print_r($output); 
+0

** 'exec()' ** retourne la dernière ligne –

+0

je l'ai déjà essayé 'exec()' et 'passthru()'. exec() ne convient pas pour une sortie directe. passthru() a semblé raisonnable, mais cela n'a pas fonctionné non plus. Il a produit le même délai: -/J'ai aussi essayé popen() et lu l'octet STDOUT par octet, mais cela ne fonctionnait pas non plus. J'ai également essayé d'envoyer la sortie vers un fichier (avec une console détachée) et de faire un appel à system() pour lire le fichier pendant que l'autre processus l'écrit - mais cela n'a pas fonctionné non plus ... Je suis coincé : -/ – xsign

+0

Ajoute une variable '$ output' et affiche l'argument screen après la commande, mettant à jour la réponse avec cette info ... –

0

Solution:

Apparemment, il a quelque chose à voir avec mise en mémoire tampon linux. J'ai retravaillé la commande shell pour qu'elle fonctionne maintenant. La solution consiste à envelopper la commande linux avec la commande script. Alors:

passthru("script -q -c 'ping -w 10 -c 4 test.de' /dev/null") 

Cet article a aidé: https://unix.stackexchange.com/questions/25372/turn-off-buffering-in-pipe