2012-08-25 16 views
6

PHP 5.2.10'da basit bir web sitesi ayrıştırıcısı yazıyorum. (ISO-8859-1) varsayılan dahili kodlamayı kullanırken
, ben aynı işlev çağrısı her zaman bir hata alıyorum: Bu durumda dize $ endeksinin uzunluğu 2981190 PHP dizgilerinin iç gösterimi

$start = mb_strpos($index, '<a name=gr1>'); 

Fatal error: Allowed memory size of 50331648 bytes exhausted (tried to allocate 11924760 bytes)

edildi bayt - PHP'den tam olarak 4 kat daha az tahsis etmeye çalıştı. Ben

mb_internal_encoding('UTF-8') 

kullanırsanız

Şimdi, hata kaybolur. Bu, PHP'nin çok baytlı olanlar için tek bayt dizeleri için daha fazla bellek kullandığı anlamına mı geliyor? Bu nasıl mümkün olabilir? Herhangi bir fikir?

YUKARI: Bellek kullanımı kodlamaya bağlı görünmüyor: ortalama bellek_get_usage() UTF-8 ve ISO-8859-1 kullanılarak neredeyse aynıdır. Problemin mb_strpos'ta olabileceğini düşünüyorum. Aslında, $ dizgisi Windows-1251 kodlaması (kiril) var, bu yüzden UTF-8 için geçerli olmayan simgeler içeriyor. Bu, mb_strpos'un bir şekilde dönüştürmeye çalışmasına veya bazı gereksinimler için ek belleği kullanmasına neden olabilir. Cevabı mb_strpos kaynaklarında bulmayı deneyeceğim.

+0

yardımı olabilir değer mi? http://www.php.net/manual/en/function.mb-strpos.php#81722 –

+0

PHP'nizi yükseltmeyi düşündünüz mü? Birincisi, 5.2 artık desteklenmediği ve ikincisi de 5.3 ve 5.4 sürümlerinin önemli bellek kullanımı iyileştirmeleri (özellikle 5.3) olduğu için. Bu geliştirmeler arasında mb_strpos() bulunup bulunmadığından emin değilsiniz, ancak her durumda yükseltmeye değer. – Spudley

+0

Güncellemenizin doğru yolda olduğunu düşünün. Bir kaç şey etkileyebilir ... mb_detect_order, 'auto' veya 'pass' kullanımı, birkaç isim. 'Iconv' kullanmak, dizelerinizin" aklı "olduğundan emin olmak ve algılanan/ayarlanan kodlamayı eşleştirmek için iyi bir yol olabilir. Bu 1252 kontrol kodlarıyla ne yaptığınızı görmek ve görmek istersiniz. Oh, şeytan m-dash. – ficuscr

cevap

3

Bu potansiyel sorunları zaten düşündüğünüz için üzgünüz. http://www.serverphorums.com/read.php?7,552099

Eğer sorguluyor musunuz:

baytlı dize fonksiyonları geçersiz karakterler varsa, mb_strpos() olduğu gibi (boş bir dize veya false döndürür, hatalar için UTF-8 kodlamaları kontrol edip edecektir Eğer (dönüşümleri gerçekleştirmek zorunda kaldığında

mb_strpos() fonksiyon mbfl_strpos() kullanır false yerine? 0 dizeleri kopyalarını (iğne, samanlık) yapar sen almıyorsanız emin olmak için === operatörünü kullanarak alıyoruz sonucu gözlemlediğiniz gibi bellekte artışa yol açar d): Varsayılan iç kodlamayı (ISO-8859-1) aracılığıyla her şeyi tadında ve bellek limitini kullanarak çarptı eğer utf-8 kodlama kısa nedeniyle devre oysa Yani https://github.com/php/php-src/blob/master/ext/mbstring/libmbfl/mbfl/mbfilter.c#L811

, ben merak ediyorum geçersiz karakterler ve döndürülen (eğer == ile test olsaydı, fonksiyon sadece bir maç bulamadık görünür kılacak olan.) yanlış

bir atış :)

+0

Güzel bir çekim! Sonucun “false” veya “0” olup olmadığını kontrol etmek için “assert()” gibi bir işlev yazdım, kontrol kesinlikle yapılır (===). Ama şimdi neden PHP'nin 4 kez strlen belleğe ihtiyacı olduğunu anlamıyorum - aslında, her iki argümanı da UTF-8'e dönüştürüyor (ve bir "mb_internal_encoding()'). Araştırmanız ve ekli kaynaklarınız için teşekkürler! ;) – Dmitry