2013-04-19 5 views
5

Ho diverse migliaia di record (memorizzati in una tabella in una tabella MySQL) che devo "elaborare in batch". Tutti i record contengono un grande JSON. In alcuni casi, il JSON è superiore a 1 MB (sì, il mio DB è ben oltre 1 GB).Esecuzione di un processo batch intensivo in PHP ed eliminazione dell'esaurimento della memoria

Ho una funzione che acquisisce un record, decodifica il JSON, modifica alcuni dati, ricodifica nuovamente l'array PHP in un JSON e lo salva nel db. Abbastanza semplice. FWIW, questo è nel contesto di un'applicazione CakePHP.

Dato un array di ID di, sto cercando di fare qualcosa di simile (codice finto molto semplice):

foreach ($ids as $id) { 
    $this->Model->id = $id; 
    $data = $this->Model->read(); 
    $newData = processData($data); 
    $this->Model->save($newData); 
} 

Il problema è che, molto rapidamente, PHP esaurisce la memoria. Quando si esegue un foreach come questo, è come se PHP passasse da un record all'altro, senza rilasciare la memoria richiesta per le operazioni precedenti.

È comunque necessario eseguire un ciclo in modo tale che la memoria venga liberata prima di passare alla successiva iterazione del ciclo, in modo da poter effettivamente elaborare l'enorme quantità di dati?

Modifica: aggiunta di più codice. Questa funzione accetta il mio JSON, lo converte in un array PHP, esegue alcune manipolazioni (ovvero riconfigura i dati in base a ciò che è presente in un altro array) e sostituisce i valori nell'array originale. Il JSON ha molti strati profondi, quindi i loop foreach estremamente lunghi.

function processData($theData) { 
    $toConvert = json_decode($theData['Program']['data'], $assoc = true); 
    foreach($toConvert['cycles'] as $cycle => $val) { 
     foreach($toConvert['cycles'][$cycle]['days'] as $day => $val) { 
      foreach($toConvert['cycles'][$cycle]['days'][$day]['sections'] as $section => $val) { 
       foreach($toConvert['cycles'][$cycle]['days'][$day]['sections'] as $section => $val) { 
        foreach($toConvert['cycles'][$cycle]['days'][$day]['sections'][$section]['exercises'] as $exercise => $val) { 
         if (isset($toConvert['cycles'][$cycle]['days'][$day]['sections'][$section]['exercises'][$exercise]['selectedFolder'])) { 
          $folderName = $toConvert['cycles'][$cycle]['days'][$day]['sections'][$section]['exercises'][$exercise]['selectedFolder']['folderName']; 
          if (isset($newFolderList['Folders'][$folderName])) { 
           $toConvert['cycles'][$cycle]['days'][$day]['sections'][$section]['exercises'][$exercise]['selectedFolder'] = $newFolderList['Folders'][$folderName]['id']; 
          } 
         } 
         if (isset($toConvert['cycles'][$cycle]['days'][$day]['sections'][$section]['exercises'][$exercise]['selectedFile'])) { 
          $fileName = basename($toConvert['cycles'][$cycle]['days'][$day]['sections'][$section]['exercises'][$exercise]['selectedFile']['fileURL']); 
          if (isset($newFolderList['Exercises'][$fileName])) { 
           $toConvert['cycles'][$cycle]['days'][$day]['sections'][$section]['exercises'][$exercise]['selectedFile'] = $newFolderList['Exercises'][$fileName]['id']; 
          } 
         } 
        } 
       } 
      } 
     } 
    } 
    return $toConvert; 
} 

Model-> read() essenzialmente solo dice torta di tirare un record dal db, e lo restituisce in un array. C'è un sacco di cose che stanno accadendo dietro le quinte, qualcuno più esperto dovrebbe spiegarlo.

+0

si poteva dormire alla fine di ogni ciclo, e se si sta eseguendo PHP 5.3 o superiore è possibile (provare a) avviare il garbage collector. –

+0

Come potrebbe aiutare il sonno? –

+0

@therefromhere dare al gc più tempo per dare il via, o finire quello che sta facendo. –

risposta

2

Il primo passo che vorrei fare è assicurarsi che tutto sia passato per riferimento.

Ad esempio,

foreach ($ids as $id) { 
processData($data); 
} 

function processData(&$d){} 

http://php.net/manual/en/language.references.pass.php

+0

Ottima idea! Lo prendo in JS ... –

+1

Sarebbe saggio chiamare 'unset()' se i dati non sono più necessari? –

Problemi correlati