Uploader работал нормально, пока файл не стал больше, чем 100 000 строк.Я не писал код, но хочу это исправить.Я работал с другими языками, но не с PHP.Я знаю, что есть разные способы решения этой проблемы, но я не уверен в том, что стоит потратить больше времени.В идеале я хотел бы, чтобы загрузчик принимал файлы любого размера.Изменение распределения памяти кажется самым быстрым решением, но я ожидаю долгосрочных проблем, когда файл перерастет память.Очистка памяти и пакетная загрузка - это две стороны одной монеты, однако в настоящее время загрузчик будет обрабатывать только один файл и одну загрузку в базу данных, каждый раз, когда файл загружается, он удаляет предыдущие данные и заменяет их наданные из файла.В частности, я настраивал загрузчик CSV, а не загрузчик XLSX.
Я уже безуспешно пытался выделить дополнительную память для программы, но она вызвала сбой сервера, и я предпочел бы не делать этого снова.Я также пытался пакетировать файл CSV, но он также не удалось.
<?php
class Part {
public $id;
public $oem;
public $part_number;
public $desc;
// Assigning the values
public function __construct($id, $oem, $part_number, $desc) {
$this->id = $id;
$this->oem = $oem;
$this->part_number = $part_number;
$this->desc = $desc;
}
}
//imports single csv file and returns an array of Parts
function importCSVpartfinder($filename, $brand, $root){ //$filename is a dataTable of dimensions: first row contains dimension labels, second row are units, the first column is the part number
$handle = fopen($filename, 'r') or die('unable to open file: $filename');
$contents = fread($handle, filesize($filename));
fclose($handle);
$row = explode("\r" , $contents);
$data = array();
$data2 = array();
for ($i=0; $i < sizeof($row); $i++) {
$columns = explode(",", $row[$i]);
array_push($data, $columns);
}
$all = array(); //array of all Parts
//I should probably sanatize here
for ($i=0; $i < sizeof($data); $i++) {
if (sizeof($data[$i]) != 1){
$id = $data[$i][0];
$oem = $data[$i][1];
$part_number = $data[$i][2];
$desc = $data[$i][3];
$obj = new Part($id, $oem, $part_number, $desc);
array_push($all, $obj);
}
}
return $all;
}
//returns a message with # of succes and list of failures //this is slow with large uploads
function addPartsToDB($data, $connection){ //$data is an array of Parts
//delete
$deleteSQL = "DELETE FROM Part_finder WHERE 1";
$res = $connection->query($deleteSQL);
if (!$res){
echo " Failed to delete Part_finder data, ";
exit;
}
//insert
$e=0;
$s=0;
$failures = "";
$d="";
for ($i=0; $i < sizeof($data); $i++) {
$d .= "(".$data[$i]->id.",'".$data[$i]->oem."','".$data[$i]->part_number."','".$data[$i]->desc."'),";
$s++;
}
$d = substr($d, 0, -1);
$sqlquery = "INSERT INTO Part_finder (id_part, oem, part_number, description) VALUES $d";
$res = $connection->query($sqlquery);
if (!$res){
$sqlError = $connection->error;
return ( $s." items failed to update. Database error. ".$sqlError);
}else{
return ( $s." items updated.");
}
/*
for ($i=0; $i < sizeof($data); $i++) {
$d = "(".$data[$i]->id.",'".$data[$i]->oem."','".$data[$i]->part_number."','".$data[$i]->desc."')";
$sqlquery = "INSERT INTO Part_finder (id_part, oem, part_number, description) VALUES $d";
#$res = $connection->query($sqlquery);
if (!$res){
$failures .= $data[$i]->part_number . "
" ;
$e++;
}else{
$s++;
}
}*/
#return $sqlquery;
}
function importXLSXpartfinder($filename, $root){
require($root.'./plugins/XLSXReader/XLSXReader.php');
$xlsx = new XLSXReader($filename);
/* $sheetNames = $xlsx->getSheetNames();
foreach ($sheetNames as $Name) {
$sheetName = $Name;
}*/
$sheet = $xlsx->getSheet("Sheet1");
$rawData = $sheet->getData();
#$columnTitles = array_shift($rawData);
$all = array(); //array of all Parts
for ($i=0; $i < sizeof($rawData); $i++) {
if (sizeof($rawData[$i]) != 1){
$id = $rawData[$i][0];
$oem = $rawData[$i][1];
$part_number = $rawData[$i][2];
$desc = $rawData[$i][3];
$obj = new Part($id, $oem, $part_number, $desc);
array_push($all, $obj);
}
}
return $all;
}
$filename = $file["partfinder"]["tmp_name"];
if($file["partfinder"]["size"] > 100000000){
echo "File too big".$file["partfinder"]["size"];
exit;
}
//$file comes from edit.php
if($file["partfinder"]["type"] === "text/csv" ) {
$a = importCSVpartfinder($filename, $brand, $root);
}elseif ($file["partfinder"]["type"] === "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ) {
$a = importXLSXpartfinder($filename, $root);
}else{
var_dump($file["partfinder"]["type"]);
echo ".xlsx or .csv file types only";
exit;
}
$b = addPartsToDB($a,$connection);
echo $b;
?>
В настоящее время происходит исчерпание памяти в строке 25
$columns = explode(",", $row[$i]);
, а код ошибки
Fatal error: Allowed memory size of 94371840 bytes exhausted (tried to allocate 20480 bytes) in /www/tools/import-csv-partfinder.php on line 25
В идеале я все же хотел бы загрузить один файл для обновления базы данных, и мне нужно было бы изменить дополнительные программы, чтобы можно было загружать несколько файлов или чтобы база данных не стиралась сама при каждой загрузке.К сожалению, я не могу связаться с человеком, который изначально писал программы, поэтому я сам по себе, чтобы выяснить это.