2008-11-11 5 views
2

La plupart de mes applications PHP ont un ob_start au début, parcourt tout le code, puis affiche le contenu, parfois avec quelques modifications, après que tout soit fait.Comment empêcher un tampon de sortie PHP de dépasser la limite de mémoire?

ob_start() 
//Business Logic, etc 
header->output(); 
echo apply_post_filter(ob_get_clean()); 
footer->output(); 

Cela garantit que les erreurs PHP s'affichent dans la partie du contenu du site, et que les erreurs ne gênent pas header et session_* appels.

Mon seul problème est qu'avec quelques grandes pages PHP manque de mémoire. Comment puis-je empêcher cela de se produire?

Quelques idées:

  1. Ecrire tous du contenu en mémoire tampon dans un fichier temporaire et de sortie.
  2. Lorsque les tampons atteignent une certaine taille, affichez-le. Bien que cela puisse interférer avec le post-filtre.
  3. Augmenter la limite de mémoire (thanx @troelskn).

Quels sont les inconvénients de chacune de ces approches? Surtout augmenter la limite de la mémoire? Vous ne pouvez pas augmenter la limite de mémoire?

Répondre

5

Cela me semble être la meilleure solution. Editer: Évidemment, augmenter la limite de mémoire juste parce qu'un script arrive à la fin devrait soulever quelques drapeaux rouges, mais il me semble que c'est un cas légitime - par exemple. le script produit en fait de gros morceaux de sortie. En tant que tel, vous devez stocker la sortie quelque part, et la mémoire semble être le meilleur choix, pour des raisons de performance et de commodité.

Je devrais noter également que le paramètre de limite de mémoire est juste cela - une limite. Les scripts qui ne consomment pas beaucoup de mémoire, ne consommeront pas plus simplement parce que vous augmentez la limite. La raison principale de son existence, est d'empêcher les scripts de mauvaise conduite/bogué de détruire tout le serveur. C'est quelque chose qui est important si vous avez beaucoup d'amateurs qui piratent sur un hôte partagé (Quelque chose PHP a été beaucoup utilisé pour). Donc, si c'est votre propre serveur, ou au moins vous savez généralement ce que vous faites, il n'y a pas vraiment de bénéfice à avoir une limite de mémoire basse.

+0

Je pense que c'est aussi la meilleure approche. –

+0

J'ai essayé ça, mais quelque chose me pousse à augmenter la limite de mémoire. Des inconvénients à augmenter la limite de mem? – Jrgns

2

Vous devriez augmenter la limite de mémoire avant tout, surtout si votre seule autre solution est de passer par un fichier temporaire. Il ya toutes sortes d'inconvénients à l'utilisation de fichiers temporaires (principalement, c'est plus lent), et si vous avez vraiment besoin d'un moyen de stocker le tampon avant de le sortir, Allez chercher memcached ou APC cache. Cela vous permettrait de faire à peu près la même chose qu'un fichier, sauf que vous avez un accès rapide à la RAM.

Je dois dire que c'est une mauvaise idée dans l'ensemble, cependant. Si la mémoire tampon ne fonctionne pas correctement à l'heure actuelle, il est probable que vous puissiez construire différemment afin de rendre votre site plus performant.

2

Si les erreurs PHP sont la seule raison pour la sortie de mise en mémoire tampon, pensez à utiliser set_error_handler. Avec cette fonction, vous pouvez définir un rappel personnalisé pour les erreurs dans votre script. Utilisez-le pour enregistrer les messages quelque part et les imprimer plus tard.

http://www.php.net/set_error_handler

+0

Ce n'est pas seulement pour les erreurs. Notez la fonction apply_post_filter qui modifie la sortie. – Jrgns

1

Pour que vous manquez de mémoire en raison de la sortie vous devez avoir une énorme quantité de données qui sortent ou très faibles limites de la mémoire. Il y a environ 4 ans, une limite de mémoire de 8 Mo était assez courante et raisonnable. Mais avec le passage à l'utilisation d'objets et juste de meilleurs styles de codage en général, l'utilisation de la mémoire des scripts que j'ai rencontrés a augmenté.

Hrm ... où est-ce que vos scripts manquent de mémoire? Si c'est toujours dans vos fonctions de filtrage de sortie, peut-être qu'ils ont juste besoin d'être optimisés? memory_get_usage() retournera la quantité de mémoire utilisée par votre script à ce stade.

Quelle est la limite de mémoire en cours d'exécution? Courez-vous dans un environnement partagé? Pour le moment j'ai des limites de mémoire entre 64 et 128 selon le serveur.

Si c'est un sous-ensemble spécifique de scripts que vous souhaitez augmenter la limite car alors vous pouvez le faire par script: Si vous voulez pas de limite pour le script

ini_set('memory_limit','64M'); 

vous pouvez définir ce à -1

+0

Le serveur est un serveur de production pour quelques très grandes applications Web. Je pense que la limite de mem est de 128Mg. Je frappe la limite quand je charge un très grand fichier de modèle PHP dans le tampon. – Jrgns

1

Ma recommandation serait d'essayer de charger le fichier par étapes, ou de le diviser en plus petits morceaux pour inclusion. La façon dont vous faites ceci dépendra fortement de ce que le fichier est, mais cela vous permettra de le charger en disons ... morceaux de 2mb, s'il ne génère pas d'erreur, alors utilisez ob_flush() pour l'envoyer avant de charger le morceau suivant. Par exemple, vous mentionnez qu'il s'agit d'un modèle PHP; Je ne suis pas sûr de ce que ce serait exactement, si vous parlez d'un fichier PHP/HTML mixte qui, une fois exécuté produit des résultats, vous pouvez essayer d'ajouter dans le modèle une forme de marqueur de bloc pour séparer les différentes parties du modèle . De cette façon, il suffit de lire jusqu'à la fin du bloc courant, puis de le sortir et de continuer. Cela devient plus difficile si vous avez une boucle ou autre, mais il y a généralement toujours un moyen de contourner ce problème. Par exemple, en ajoutant PHP à vos templates qui déclenche une méthode/fonction dans votre script principal qui peut gérer la sortie de la boucle par étapes.

Vous pouvez également examiner un mécanisme de pré-validation du modèle avant de le charger, vous n'avez donc pas à vous soucier des erreurs qui se glissent dans les pages. Si la modification de la limite de mémoire résoudra le problème à court terme, ce n'est pas une solution à long terme, car ce type d'utilisation de la mémoire doit absolument être évité si possible. En général, vous ne voulez rien charger du tout en mémoire si vous pouvez l'éviter, ou le cracher le plus tôt possible, car cela signifie que les données sont au moins sur le chemin de l'utilisateur, ce qui réduit le temps au premier octet pour la page.

Questions connexes