Bellek sınırı üzerinden gidiyor bir PHP çıktı tamponu nasıl engellenir?

5 Cevap php

Benim PHP Uygulamaların çoğu herşey bittikten sonra başında bir ob_start, bazı değişikliklerle, bazen tüm kodu ile çalışır ve sonra içeriği çıktılar var.

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

Bu PHP hataları web sitesinin içeriği parçası içinde görüntülenen olsun sağlar, ve hatalar header ve session_* çağrıları ile karışmaz.

Benim tek sorun bazı büyük sayfaları ile PHP bellek biterse olduğunu. Bunu nasıl oluyor durdurabilirim?

Bazı fikirler:

  1. Bu geçici bir dosya ve çıkış tamponlu tüm içerik yazın.
  2. tamponlar belirli bir büyüklüğe ulaştığında, çıkış o. Bu Mesaja filtre ile etkileşebilir rağmen.
  3. (@ Troelskn thanx) bellek sınırını kaldırın.

Bu yaklaşımların her biri nedir sakıncaları? Özellikle hafıza limitini yükselterek?

5 Cevap

Eğer hafıza limitini yükseltmek değil mi? Benim için en iyi çözüm gibi geliyor.

Edit: Açıkçası, bir komut dosyası dışarı başında sırf hafıza limitini yükselterek bazı kırmızı bayraklar yükseltmek, ama bu meşru bir durum gibi bana geliyor gerekir - örn. betik aslında çıkışının oldukça büyük boyutta üretiyor. Bunun gibi, çıkış somewhere saklamak zorunda ve bellek performansı ve kolaylık hem nedenlerden dolayı, en iyi seçim gibi görünüyor.

Bir limit - Ben bellek limiti ayarı sadece olması da dikkat etmelisiniz. Eğer sınırını yükseltmek sırf fazla bellek tüketmeyin Script, daha fazla tüketmek olmaz. Varlığı için temel nedeni, tüm sunucu aşağı alarak misbehaving / adamcağız betikleri önlemektir. Bu (bir şey PHP için bir çok kullanılan olmuştur) paylaşılan bir bilgisayar uzakta hack amatör bir sürü varsa önemli bir şeydir. Bu, kendi sunucu, ya da en azından genel olarak ne yaptığınızı biliyorsanız Yani, düşük bellek limitine sahip herhangi bir yararı yok gerçekten.

Diğer tek çözüm geçici bir dosyaya geçmesi için özellikle eğer, bir şey daha önce hafıza limitini yükseltmek gerekir.

Orada (başta, bu daha yavaş), geçici dosyaları kullanarak olumsuz yanlarını her türlü, ve gerçekten çıktılamak önce tampon saklamak için bir yol gerekiyorsa, memcached veya APC cache için bakın gidin. Bu RAM hızlı erişim dışında, bir dosya olarak kabaca aynı yapalım istiyorum.

Ama, genel olarak bu korkunç bir fikir olduğunu söylemeliyim. Tampon şu anda doğru işe yaramazsa, sitenizin daha iyi çalışması için farklı inşa edebileceğini olasılıkla bir şey var.

Php hataları tamponlama çıkışı için tek nedeni ise set_error_handler kullanmayı düşünün. Bu fonksiyon ile komut hataları için özel bir geri arama tanımlayabilirsiniz. Yere iletileri kaydetmek ve daha sonra yazdırmak için kullanın.

http://www.php.net/set_error_handler

Benim öneri aşamalarında dosyayı yüklemek için denemek için, ya da eklenmesi için küçük parçalar halinde parçalayın olacaktır. Bu ağır dosyanın ne bağlıdır, ama o hataları üretmek değilse o zaman kullanmak, diyelim ... 2mb parçalar yüklemek için izin verecek nasıl ob_flush() yüklemeden önce göndermek için sonraki yığın.

Örneğin, bir PHP şablon olmaktan bahsetmiyorum; Ben çalıştırıldığında çıktı üretir karışık PHP / HTML dosyası bahsediyoruz, o zaman şablon farklı parçalarını ayırmak için şablon içine blok-işaretleyici çeşit eklemeyi deneyebilirsiniz, tam olarak ne olacağını emin değilim . Bu şekilde sadece çıkış sonra, güncel bloğun sonuna kadar okumak ve devam etmek gerekir. Eğer döngü ya da varsa bu daha zor olur, ama çözüm için bir yol genellikle her zaman vardır. Örneğin aşamalarında döngü çıkışını işleyebilir ana komut bir yöntem / işlevi tetikler şablonlar PHP ekleyerek.

Ayrıca yüklemeden önce şablonu önceden doğrulanması için bir mekanizma bakmak isteyebilirsiniz, bu nedenle hatalar da tüm sayfaların içine sürünen hakkında endişelenmenize gerek yoktur.

Bellek kullanımı bu tür mümkünse kaçınılması gereken kesinlikle gibi, bu uzun vadeli bir çözüm değil, kısa vadede sorunu "çözmek" olacak bellek sınırı değişiyor iken. Veri için ilk defa azaltır kullanıcıya yolunda en az olduğu anlamına gelir, bunu önlemek eğer Genel olarak tüm belleğe büyük bir şey yüklemek istemiyorsanız, ya da ilk fırsatta dışarı tükürmek sayfa için bayt.

Nedeniyle çıkış bellek tükendi için dışarı gidiyor veri ya da çok düşük bellek sınırları büyük bir miktarda olması gerekir. 4 yıl kadar önce 8MB bellek sınırı yeterince yaygın ve makul. Ama ben geldim Dizelerin bellek kullanımını nesneleri kullanarak ve sadece daha genel stilleri kodlama anahtarı ile artmıştır.

Hrm ... nerede senin komut bellek tükendi olduğunu? Bu çıkış filtreleme fonksiyonları her zaman varsa belki onlar sadece optimize edilmiş olması gerekir? memory_get_usage() bu noktada komut tarafından kullanılan bellek miktarını dönecektir.

What's the current memory limit you're running at? Are you running in a shared environment? At the moment I've got memory limits between 64 and 128 depending on the server.

Eğer o zaman komut dosyası başına bunu yapabilir için sınırı artırmak isteyen komut sadece belirli bir alt kümesi ise:

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

Eğer komut dosyası için hiçbir sınırı isterseniz -1 bu ayarlayabilirsiniz