2011-01-13 7 views
0
} 
public function backup(){ 
    $app =& JFactory::getApplication(); 
    $createTablesSQL = $this->_dbo->getTableCreate($this->_tables); 
    $databaseName = $app->getCfg("db"); 
    $data = "--\n-- Database: `{$databaseName}`\n--\n\n"; 
    foreach ($createTablesSQL as $key => $value){ 
     $data .= "DROP TABLE IF EXISTS `{$key}`;\n"; 
     $data .= "\n--\n-- Table structure for table `{$key}`\n--\n"; 
     $data .= $value . ";\n"; 
     $tableFields = $this->_dbo->getTableFields($key); 
     $this->_dbo->setQuery("SELECT * FROM `{$key}`"); 
     $this->_dbo->query(); 
     if($this->_dbo->getNumRows()){ 
      $data .= "--\n-- Dumping data for table `{$key}`\n--\n"; 
      $data .= "LOCK TABLES `{$key}` WRITE;\n"; 
      $fields = array_keys($tableFields); 
      $data .= "REPLACE INTO `{$key}` (`".implode("`, `", array_keys($tableFields[$fields[0]]))."`) VALUES \n"; 
      // Load data from table 
      $rows = $this->_dbo->loadRowList(); 
      $_ = array(); 
      foreach ($rows as $row){ 
       foreach ($row as $k => $v){ 
        if(!isset($v)) 
         $row[$k] = 'NULL'; 
        else 
         $row[$k] = "'".addslashes($v)."'"; 
        } 
       $_[] = "\t(".implode(", ", $row).")"; 
      } 
      $data .= implode(",\n", $_); 
      $data .= ";\nUNLOCK TABLES;\n\n"; 
     } 
    } 
    // fix dbprefix after getTableCreate 
    $tablePrefix = $app->getCfg("dbprefix"); 
    $data = str_replace($tablePrefix, "#__", $data); 
    // write backup file 
    $path2Filename = $this->path2BackupFiles; 
    $filename = $this->filePrefix . date("Y_m_d_H_i_s", time()) . "_" . CompanyUpdate::getCurrentVersion() . ".sql"; 
    if(JFile::write($path2Filename . $filename, $data)){ 
     // compression 
     if(false != ($arFile = $this->compressFile($path2Filename, $filename, 'zip', true))){ 
      return $arFile; 
     }else{ 
      return false; 
     } 
    }else{ 
     return false;  
    } 
} 
/** 
* 
* @param string $path2Filename 
* @param string $filename 
* @param string $type 
* @param bool $cleanUp 
* @return bool 
*/ 
private function compressFile($path2Filename, $filename, $type = 'zip', $cleanUp = false){ 
    $fullPathFilename = $path2Filename . $filename;  
    $adapter =& JArchive::getAdapter($type); // type compression 
    $files2ZIP = array(); 
    $files2ZIP[0]["name"] = $filename; 
    $files2ZIP[0]["data"] = JFile::read($fullPathFilename); 
    if($adapter->create($fullPathFilename . "." . $type, $files2ZIP, $type, $path2Filename)){ 
     if($cleanUp) 
      JFile::delete($fullPathFilename); 
     return JFile::stripExt($filename) . "." . $type; 
    }else{ 
     return false; 
    } 
} 

} ?>Hauptspeicher Leck in Joomla/PHP .. Was gibt?

Wer ein Leck irgendwo hier sehen?

EDIT: Sollte gedacht haben, um den Fehler zu schreiben. Leider

Fatal error: Aus Speicher (65.536.000 zugeordnet) (versucht 125459 Bytes zuzuteilen) in /home/user2/public_html/administrator/components/com_company/lib/CompanyBaseDManagement.php auf Leitung 395

Nach Dreamweaver dies ist Zeile 395: $ row [$ k] = "'" .addslashes ($ v). "'";

+0

Beitrag etwas wie Code der Fehler, Beschreibung, Zeilennummer Stack-Trace etc ........ nicht nur die große PHP-Datei. – Ish

+0

Danke Ish, gerade den Schnitt gemacht. – Nick

+0

Herrje, wird etwas schrecklich falsch ... – Qix

Antwort

0

Nun, ich weiß für eine Tatsache, dass ein Array bearbeiten, die von einer foreach Schleife beaufschlagt wird (wie, wie, dass foreach Schleife im Code ist) sehr gefährlich ist. Ich bin überrascht, dass es keinen Fehler wirft (ich dachte aus irgendeinem Grund - warten Sie, es gibt keine falsche Sprache, die einen Fehler beim Editieren von foreach-Schleifen-Arrays auslöst). Ich denke, dort könnte eine Endlosschleife sein. Ich habe Fälle gesehen, in denen eine foreach-Schleife ein neues Objekt auf das Array, auf das es referenziert wurde, schiebt, was letztendlich eine Endlosschleife verursacht (da es niemals Elemente zum Iterieren gibt)!

Ein guter Startpunkt wäre, das Array, auf das verwiesen wird, und ein neues Array mit den neuen Werten zu trennen und dann die nach der foreach-Schleife zusammenzuführen.

0

Sind Sie sehr sicher, dass es ein Leck ist? Nicht nur das Backup, das Ihr Speicherlimit überschreitet? Ich kann nicht sehen, was das offensichtliche Problem ist, aber haben Sie in Betracht gezogen, etwas Debugging des Speicherverbrauchs und der Schleifen-Iterationsnummer um diese Schleife herum vorzunehmen? Es könnte eine zweifelhafte Reihe von Daten, die mit einem plötzlichen Sprung Verbrauch

http://uk.php.net/manual/en/function.memory-get-usage.php

3

Das gesamte Skript ist schrecklich Speicher ineffizient sehr offensichtlich sein sollten. Es sollte die Daten in Blöcken an die Sicherungsdatei anhängen, anstatt die gesamte verdammte Datenbank in den Speicher einzulesen und dann eine str_replace() darauf laufen zu lassen und dann möglicherweise zu einer Komprimierungsfunktion zu senden, die die Datei erneut in den Speicher liest und komprimiert es. !!!

Ehrlich gesagt, die einzige einfache Möglichkeit, die ich sehen kann dies behoben wird auf bis die Speichergrenze in der php.ini-Datei ist, versuchen 128MB. Wenn Ihr db weiter wächst, muss diese Zahl weiter steigen. Es wäre effizienter, dieses Skript zu verwerfen und mysqldump + gzip in der Befehlszeile zu verwenden, wenn Sie Zugriff haben.

+0

Ich gebe diese Antwort in beiden Punkten an zweiter Stelle: Die Sicherungsfunktion versucht, alle Daten in einer Datenbanktabelle abzurufen, und sie könnte leicht den gesamten verfügbaren Speicher verbrauchen. Dies muss nur an kleinen Datensätzen getestet worden sein. Die Verwendung von mysqldump ist der richtige Weg, db backup zu machen, und es braucht keinen Programmierer dafür. –

+0

Hahahah Dies ist bei weitem die richtigste (und auch die erste) Antwort. MySQL Dump macht den Server die ganze Arbeit machen, * nicht * PHP (die entworfen wurde, um Skripte laufen zu lassen, nicht Speicher für große Teile von Daten wie die DB hier gezogen wird); Lassen Sie 'mysqldump' die ganze Arbeit erledigen und überlassen Sie PHP, was Sie tun müssen. – Qix