Как «освободить» память в цикле? - PullRequest
4 голосов
/ 10 сентября 2011

У меня есть скрипт, который выполняется в среде общего хостинга, где я не могу изменить доступный объем памяти PHP. Скрипт использует веб-сервис через мыло. Я не могу получить все свои данные за один раз, иначе мне не хватает памяти, поэтому у меня был некоторый успех с локальным кэшированием данных в базе данных mysql, чтобы последующие запросы выполнялись быстрее.

По сути, вместо того, чтобы запрашивать данные у веб-службы за 5 месяцев, я запрашиваю их по 1 месяцу за раз, сохраняя их в таблице mysql, получая данные за следующий месяц и т. Д. Обычно это работает, но иногда мне все еще не хватает памяти.

моя основная кодовая логика выглядит так:

  1. подключиться к веб-сервису с помощью мыла;
  2. подключиться к базе данных mysql
  3. запросить веб-сервис и сохранить результат в переменной $ results;
  4. выгрузка результатов $ в таблицу mysql
  5. повторите шаги 3 и 4 для каждого месяца данных

одни и те же переменные используются в каждой итерации, поэтому я предполагаю, что каждая партия результатов веб-службы будет перезаписывать предыдущую в памяти? Я пытался использовать unset ($ results) между итерациями, но ничего не сделал. Я выводлю память, используемую с memory_get_usage (true) каждый раз, и с каждой итерацией используемая память увеличивается.

Есть идеи, как я могу исправить эту утечку памяти? Если я не достаточно ясно, оставьте комментарий, и я могу предоставить более подробную информацию. Спасибо!

*** EDIT

Вот некоторый код (я использую nusoap, а не клиент мыла php5, если это имеет значение):

$startingDate = strtotime("3/1/2011");
$endingDate = strtotime("7/31/2011");
// connect to database
mysql_connect("dbhost.com", "dbusername" "dbpassword");
mysql_select_db("dbname");
// configure nusoap
$serverpath ='http://path.to/wsdl';
$client = new nusoap_client($serverpath);
// cache soap results locally
while($startingDate<=$endingDate) {
    $sql = "SELECT * FROM table WHERE date >= ".date('Y-m-d', $startingDate)." AND date <= ".date('Y-m-d', strtotime($startingDate.' +1 month'));
    $soapResult = $client->call('SelectData', $sql);
    foreach($soapResult['SelectDateResult']['Result']['Row'] as $row) {
        foreach($row as &$data) {
            $data = mysql_real_escape_string($data);
        }
        $sql = "INSERT INTO table VALUES('".$row['dataOne']."', '".$row['dataTwo']."', '".$row['dataThree'].")";
        $mysqlResults = mysql_query($sql);
    }
    $startingDate = strtotime($startingDate." +1 month");
    echo memory_get_usage(true); // MEMORY INCREASES EACH ITERATION
}

Ответы [ 2 ]

5 голосов
/ 10 сентября 2011

Решил это.По крайней мере, частично.При использовании nusoap произошла утечка памяти.Nusoap записывает журнал отладки в переменную $ GLOBALS.Изменение этой строки в nusoap.php освободило много памяти.

изменить

$GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = 9;

на

$GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = 0;

Я бы предпочел просто использовать родное мыло php5клиент, но я получаю странные результаты, которые, как я считаю, относятся к веб-сервису, который я пытаюсь использовать.Если кто-нибудь знает, как использовать мыльный клиент php5 с SOAP API www.mindbodyonline.com, дайте мне знать.

0 голосов
/ 10 сентября 2011

Вы пробовали unset() для $ initialDate и mysql_free_result() для $ mysqlResults?

Также SELECT * не одобряется, даже если это не проблема здесь.

РЕДАКТИРОВАТЬ: Возможно, также бесплатно получить результат SOAP. Несколько простых вещей для начала, чтобы посмотреть, поможет ли это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...