Я пытаюсь показать пользователей на карте с помощью API Google. Теперь, когда число пользователей увеличивается до 12000, я получил ошибку исключения памяти. Пока я увеличил память до 256 с 128. Но я уверен, что когда его 25000 пользователей снова придут к той же ошибке.
Ошибка: Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 30720 bytes)
в /var/www/html/digitalebox_v2_20150904_100/protected/extensions/bootstrap/widgets/TbBaseMenu.php on
строке 193
Неустранимая ошибка: объявления классов не могут быть вложены
in
/var/www/html/yii-1.1.14.f0fee9/framework/collections/CListIterator.php on
строке 20`.
Мой код,
$ criteria = новый CDbCriteria (); $ criteria-> condition = 't.date МЕЖДУ: from_date И: to_date';
$ modelUsers = User :: model () -> findAll ($ criteria); foreach ($ modelUsers as $ modelUser) {$ fullAddress = $ modelUser-> address1. ','. $ modelUser-> zip. ''. $ modelUser-> город. ','. Страна :: Модель () -> findByPk ($ modelUser-> COUNTRYCODE) -> COUNTRYNAME; }
когда этот $modelUsers
имеет 12000 записей, эта проблема памяти возникает как ее 12000 пользовательских объектов.
что я должен сделать, чтобы предотвратить такие проблемы в будущем? каков минимальный размер требуемой памяти для запуска php-приложения?
Когда вы вызываете findAll, он загружает все записи вовремя, поэтому вы получаете ошибку конечной памяти. Speacialy для этих ситуаций Yii имеет CDataProviderIterator . Он позволяет выполнять итерацию на больших наборах данных без сохранения всего набора в памяти.
$dataProvider = new CActiveDataProvider("User"); $iterator = new CDataProviderIterator($dataProvider); foreach($iterator as $user) { $fullAddress = $modelUser->address1 . ', ' . $modelUser->zip . ' ' . $modelUser->city . ', ' . Country::model()->findByPk($modelUser->countryCode)->countryName; }
Я бы решил эту проблему совершенно по-другому, чем предполагалось. Я бы выбрал концепцию всей модели, и я бы запросил MySQL для адресов. Вы можете запросить MySQL, чтобы он возвращал уже конкатенированный адрес, что означает, что вы можете избежать его объединения в PHP, что позволяет избежать потери памяти.
Следующим шагом будет использование PDO
и выдача небуферизованного запроса. Это означает, что PHP-процесс не будет хранить в памяти всего 12 000 записей – так вы можете избежать исчерпания памяти.
Заключительный шаг выводит результат – при прохождении через небуферизованный запрос вы можете использовать вывод одной строки (или 10 строк) за раз.
Что происходит, так это то, что вы торгуете процессором для ОЗУ. Поскольку вы не знаете, сколько оперативной памяти вам понадобится, лучший подход – использовать как можно меньше.
Использование небуферизованных запросов и сброс выходного буфера PHP кажется единственным жизнеспособным способом для вашего использования, поскольку вы не можете избежать вывода большого количества данных.
Возможно, немного увеличьте память и посмотрите, исправляет ли она эту проблему. Попробуйте установить его на 512M или 1024M. Я расскажу вам по собственному опыту, если вы пытаетесь загрузить маркеры карт Google, количество маркеров, вероятно, приведет к краху карты.
Увеличьте значение memory_limit
в php.ini
. Затем перезапустите Apache или любой другой PHP. Имейте в виду, что то, что вы добавляете сюда, нужно убирать из других программ, работающих на одном компьютере (таких MySQL и его innodb_buffer_pool_size
).