Сайтда бирор саҳифани очганингизда оқ экран чиқса ёки лог файлида Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 20480 bytes) деган қатор пайдо бўлса, бу PHP скрипт ўзига ажратилган хотира чегарасига етганини билдиради. Хатодаги биринчи сон чегаранинг байтлардаги қиймати: 134217728 байт айнан 128 MB га тенг. Иккинчи сон эса скрипт охирги марта сўраган қўшимча хотира ҳажми, у кўпинча жуда кичик бўлади ва асосий муаммони кўрсатмайди. Бу хатони икки йўл билан ҳал қилиш мумкин: чегарани ошириш ёки хотирани ортиқча сарфлаётган кодни топиш. Кўп ҳолларда иккаласи ҳам керак бўлади.
memory_limit нима ва нега у керак
memory_limit битта PHP сўрови (битта саҳифа очилиши ёки битта скрипт ишга тушиши) фойдалана оладиган энг кўп оператив хотирани белгилайди. Бу ҳимоя механизми: хато ёзилган сикл ёки чексиз рекурсия сервернинг бутун хотирасини эгаллаб, бошқа сайтларни ҳам тўхтатиб қўймаслиги учун PHP бундай скриптни ўзи тўхтатади. Шунинг учун чегарани -1 қилиб, яъни чексиз қилиб қўйиш ёмон фикр, айниқса умумий хостингда. Одатий сайтлар учун 128 MB етарли бўлади, оғир CMS ва интернет дўконлар учун 256 MB кенг тарқалган қиймат, катта импорт ёки расм қайта ишлаш вазифалари учун эса вақтинча 512 MB керак бўлиши мумкин.
Ҳозирги қийматни билишнинг энг оддий усули вақтинчалик файл яратишдир. Текшириб бўлгач, файлни албатта ўчиринг, чунки phpinfo() сервер ҳақида жуда кўп маълумот очиб беради:
<?php
echo ini_get('memory_limit');
// yoki to'liq ma'lumot uchun: phpinfo();
Чегарани қаерда ошириш мумкин
Қайси усул ишлаши PHP серверда қандай режимда ишга туширилганига боғлиқ. Хостингларнинг аксариятида PHP алоҳида жараён сифатида (PHP-FPM ёки CGI) ишлайди, баъзиларида эса Apache модули сифатида. Нотўғри усулни танласангиз, созлама ё шунчаки эътиборсиз қолади, ёки бутун сайт 500 хато бера бошлайди.
Хостинг панелидаги PHP созламалари
Энг ишончли йўл хостинг панелидан фойдаланиш. ISPmanager панелида ҳар бир сайт учун PHP версияси ва асосий параметрларини, жумладан memory_limit ни ўзгартириш имконияти бўлади (қайси параметрлар очиқлиги тарифга боғлиқ бўлиши мумкин). sayt.uz мижозлари панелга sayt.uz кабинетидаги хостинг саҳифасидан киради. Панел орқали киритилган қиймат тўғри конфигурация файлига ёзилади ва PHP режимидан қатъи назар ишлайди.
.user.ini файли (PHP-FPM ва CGI учун)
Агар PHP FPM ёки CGI режимида ишласа, сайт папкасида .user.ini файлини яратиб, унга керакли параметрни ёзиш мумкин. PHP бу файлни ҳар сафар эмас, белгиланган вақт оралиғида қайта ўқийди (стандарт ҳолатда 300 сония), шунинг учун ўзгариш бир неча дақиқадан кейин кучга киради:
; .user.ini
memory_limit = 256M
.htaccess (фақат Apache модули режимида)
Интернетдаги кўплаб маслаҳатларда .htaccess га php_value қаторини қўшиш тавсия этилади. Бу фақат PHP Apache модули (mod_php) сифатида ишлаганда ишлайди. FPM ёки CGI режимида эса Apache бу кўрсатмани танимайди ва бутун сайт 500 хато беради. Шунинг учун бу қаторни қўшгандан кейин сайт ишдан чиқса, уни дарҳол олиб ташланг ва .user.ini усулига ўтинг:
# .htaccess
php_value memory_limit 256M
Код ичида ва WordPress'да
Айрим скриптлар учун чегарани коднинг ўзида ошириш мумкин. Бу айниқса битта оғир вазифа (масалан, ҳисобот яратиш) учун қулай, чунки қолган саҳифалар оддий чегарада қолади. Сервер администратори чегарани қаттиқ белгилаган бўлса, бу усул ишламаслигини унутманг:
ini_set('memory_limit', '512M');
WordPress'да хотира учун ўзининг иккита константаси бор. WP_MEMORY_LIMIT сайтнинг оддий саҳифалари учун, WP_MAX_MEMORY_LIMIT эса админ панел ва расм қайта ишлаш каби оғирроқ вазифалар учун ишлатилади. Улар wp-config.php файлида That's all, stop editing қаторидан олдин ёзилади. Бу константалар PHP'нинг сервер чегарасидан ошиб кета олмайди, яъни сервер 128 MB берган бўлса, WordPress'да 512 MB ёзиш натижа бермайди:
define('WP_MEMORY_LIMIT', '256M');
define('WP_MAX_MEMORY_LIMIT', '512M');
Қачон чегарани ошириш ечим эмас
Агар чегарани 256 MB дан 512 MB га, кейин 1 GB га кўтарсангиз-у, хато барибир қайтса, муаммо кодда. Кўп учрайдиган сабаблар қуйидагилар:
- Базадаги бутун жадвални битта сўров билан массивга юклаш, масалан, ўн минглаб буюртмани
fetchAll()билан олиш. - Катта расмни GD орқали қайта ишлаш: 6000x4000 пикселли фотосурат дискда бир неча мегабайт бўлса ҳам, хотирада ҳар бир пиксел учун бир неча байт керак бўлади ва бу 100 MB дан ошиб кетиши мумкин.
- Чексиз рекурсия ёки ўз-ўзини чақирадиган ҳук, бунда хотира ҳар қанча бўлса ҳам тугайди.
- Бир-бирига зид ишлайдиган ёки сифатсиз ёзилган плагинлар.
Хотирани қайси қисм еяётганини аниқлаш учун коднинг турли жойларига ўлчов қўйиш мумкин. memory_get_peak_usage(true) функцияси скрипт шу пайтгача эришган энг юқори хотира сарфини қайтаради:
error_log('Xotira: ' . round(memory_get_peak_usage(true) / 1048576, 1) . ' MB');
Катта жадваллар билан ишлаганда маълумотни қисмлаб олиш хотира сарфини кескин камайтиради. Бутун натижани массивга йиғиш ўрнига қаторларни бирма-бир ўқинг ёки LIMIT ва OFFSET билан 500-1000 тадан бўлиб ишланг.
Мисол: Тошкентдаги интернет дўконда экспорт
Тошкентдаги маиший техника дўкони example.uz WooCommerce'да ишлайди ва ҳар ҳафта барча маҳсулотларни Excel'га экспорт қилади. Маҳсулотлар сони 12 мингдан ошгач, экспорт саҳифаси Allowed memory size хатоси билан тўхтай бошлади. Дастурчи аввал панел орқали memory_limit ни 256 MB га кўтарди, бу вақтинча ёрдам берди. Кейин memory_get_peak_usage билан текширганда экспорт плагини барча маҳсулотларни расмлари ва мета маълумотлари билан бирга бир вақтда хотирага юклаётгани маълум бўлди. Плагин созламасида экспортни 500 тадан бўлакларга бўлиш ёқилгач, сарф 90 MB атрофида барқарор қолди ва чегарани яна оширишга эҳтиёж қолмади.
Хостинг тарифининг чегараси
Умумий хостингда PHP созламасидан ташқари тариф бўйича умумий хотира чегараси ҳам бўлиши мумкин. Агар memory_limit етарли бўлса-ю, сайт бир вақтда кўп ташриф бўлганда барибир секинлашса ёки хато берса, гап битта скриптда эмас, балки бир вақтда ишлаётган барча жараёнларнинг умумий сарфида бўлиши мумкин. Бундай ҳолатда лог файлларни кўриб чиқиш, кераксиз плагинларни ўчириш ва кешлашни ёқиш биринчи қадам бўлади. Агар лойиҳа ҳақиқатан ҳам ўсган бўлса, каттароқ тариф ёки VPS ҳақида ўйлаш вақти келган бўлади. Аниқ чегаралар бўйича саволларни sayt.uz кабинетидан техник ёрдамга тикет орқали бериш мумкин.