Comment faire pour désactiver le tampon de sortie en PHP
J'ai écrit un simple relais de script qui se connecte à une caméra web et un lit à partir de la prise, et les sorties de ces données en utilisant la fonction d'impression. Les données sont MJPG de données avec des limites déjà de l'installation. Je viens de copier les données qui sont lues.
Le problème, c'est PHP qui semble être mise en mémoire tampon des données. Lorsque j'ai mis l'appareil photo à 1 FPS, le flux de gel pour les 7-8 secondes, puis rapidement l'affichage de 8 images. Si j'ai mis la résolution d'une taille énorme, la caméra de se déplacer à plus ou moins 1 image par seconde. Je suppose alors que certains tampon qui se passe (puisque la taille gigantesque de remplissage de la mémoire tampon rapidement, et de faibles tailles ne le font pas), et je ne peux pas comprendre comment désactiver cette mise en mémoire tampon. Personne ne sait comment?
Code:
ignore_user_abort(false);
$boundary = "myboundary";
//Set this so PHP doesn't timeout during a long stream
set_time_limit(0);
$socketConn = @fsockopen ("192.168.1.6", 1989, $errno, $errstr, 2);
if (!$socketConn)
exit();
stream_set_timeout($socketConn, 10);
fputs ($socketConn, "GET /mjpeg HTTP/1.0\r\n\r\n");
//Setup Header Information
header("Cache-Control: no-cache");
header("Cache-Control: private");
header("Pragma: no-cache");
header("Content-type: multipart/x-mixed-replace; boundary=$boundary");
@ini_set('implicit_flush', 1);
for ($i = 0; $i < ob_get_level(); $i++)
ob_end_flush();
ob_implicit_flush(1);
stream_set_blocking($f2, false);
//Send data to client
while (connection_status() == CONNECTION_NORMAL)
{
$chunk = fread($socketConn, 128);
print $chunk;
}
fclose($socketConn);
- Montrez nous un peu de code! Nous ne pouvons pas deviner ce que vous faites. Ou plutôt, on le peut, mais il ne sera probablement pas beaucoup d'aide.
- seulement, cette solution a fonctionné pour moi sur l'ensemble de l'internet - stackoverflow.com/a/4978809/2083877
Vous devez vous connecter pour publier un commentaire.
tl;dr version
Faire deux choses:
Désactiver l'utilisateur tampon de sortie, soit...
À l'échelle mondiale, soit par...
output_buffering
dans votre php.ini, ouÉteindre
output_buffering
dans votre configuration d'Apache à l'aide deou tout simplement pour le script qui vous intéresse, soit par...
ob_end_flush()
, ouob_end_clean()
Aussi, désactiver le serveur au niveau de la mémoire tampon de sortie comme beaucoup que vous le pouvez, soit par:
ob_implicit_flush()
au début de votre script, ouflush()
après chaqueecho
déclaration ou autre information qui ajoute de sortie pour le corps de la réponseVersion longue
Point de prêter à confusion, il y a deux couches de mise en mémoire tampon qui peut être pertinente et la documentation de PHP a fait un mauvais travail de la distinction entre les deux.
La mémoire tampon de sortie
La première couche est généralement désigné par le PHP docs comme le "tampon de sortie'. Cette couche de mise en mémoire tampon n'affecte que la sortie de la corps de la réponse HTTP, pas les en-têtes. Vous pouvez activer le tampon de sortie avec
ob_start()
, et de l'éteindre avecob_end_flush()
ouob_end_clean()
. Vous pouvez également disposer de toutes vos scripts démarrer automatiquement avec le tampon de sortie sur l'utilisation de laoutput_buffering
option en php.ini.La valeur par défaut de cette option pour la production de versions de php.ini est de 4096, ce qui signifie que la première 4096 octets de sortie va être mis en mémoire tampon dans la mémoire tampon de sortie, à laquelle il sera vidé et le tampon de sortie est désactivé.
Vous pouvez désactiver cette couche de mise en mémoire tampon à l'échelle mondiale par la mise en
output_buffering
àOff
dans votre php.fichier ini (ou à l'aide dedans votre configuration d'Apache, si vous utilisez Apache). Alternativement, vous pouvez la désactiver pour un seul script, en appelant
ob_end_clean()
ouob_end_flush()
au début du script.La mémoire tampon d'écriture, et le serveur web tampon
Au-delà de la mémoire tampon de sortie est ce que le manuel PHP appelle le "tampon d'écriture', en plus de toute mise en mémoire tampon du système de votre serveur web. Si vous utilisez PHP avec Apache par
mod_php
, et ne sont pas à l'aide demod_gzip
, vous pouvez appelerflush()
de rincer ces; avec d'autres backends, il pourrait fonctionner, bien que le manuel est méfiant à propos de donner des assurances:Il ya aussi un couple de façons dont vous pouvez faire PHP appeler automatiquement
flush()
chaque fois que vousecho
rien (ou faire autre chose qui fait écho à la sortie du corps de la réponse).La première est d'appeler
ob_implicit_flush()
. Notez que cette fonction est faussement nommé; compte tenu de sonob_
préfixe, toute personne raisonnable s'attendre à ce que cela aurait une incidence sur la sortie de tampon", comme le fontob_start
,ob_flush
etc. Cependant, ce n'est pas le cas;ob_implicit_flush()
, commeflush()
, affecte le serveur au niveau de la mémoire tampon de sortie et ne pas interagir en aucune façon avec le tampon de sortie contrôlée par l'autreob_
fonctions.La deuxième est pour activer globalement implicite de rinçage par le réglage de la
implicit_flush
drapeau àOn
dans votre php.ini. Ceci est équivalent à l'appel deob_implicit_flush()
au début de chaque script. Notez que le manuel conseille contre cette, sibylline citant "de graves implications sur les performances", dont certains que j'explore dans ce tangentiellement liés répondre.Plutôt que de désactiver le tampon de sortie, vous pouvez les appeler
flush()
après chaque opération de lecture. Cela évite d'avoir à jouer avec la configuration du serveur et rend votre script plus portable.ob_flush()
est parfois également nécessaire.ob_start()
- je crois me souvenir qu'il émet un avertissement autrement.flush()
appel doit être placé immédiatement après leprint
appel dans la boucle. Si cela ne fonctionne toujours pas, s'il vous plaît montrer la sortie deini_get('output_buffering');
etini_get('zlib.output_compression');
ini_get('output_buffering');
retourne 1ini_get('zlib.output_compression');
retourne 0. J'ai modifié le code à exécuterini_set('zlib.output_compression', 0); ini_set('implicit_flush', 1);
mais étrangementini_set('output_buffering', 0);
n'est pas fixé à 0.ini_set('output_buffering', 0);
le script est déjà en cours d'exécution et la mémoire tampon de sortie a déjà commencé - il n'est pas changable au moment de l'exécution. Pouvez-vous mettre dans un .fichier htaccess? Ce doit être un travail autour, si vous avez d'accueil le permet. Vous aurez probablement encore besoin deflush()
.php_value "output_buffering" "0"
Le tampon de sortie peut être en couches, et j'ai eu des cas où le code précédent avait fait de multiples niveaux. Cela permettra d'effacer tous les.
Nous pouvons donner le code ci-dessous dans le .htaccess pour désactiver le tampon de sortie en PHP
Je sais que cette question est un peu vieux, mais pour en revenir à cette question, vous pouvez désactiver le tampon de sortie sur un script de script de base, comme ceci:
Ce devez la désactiver pour le tampon de sortie pour n'importe quel script qui le suit.