Я пытаюсь записать файл в базу данных по 500 строк за раз, поэтому я не запускаюсь с низким объемом памяти, избегая работы с очень большими массивами. По какой-то причине я не получаю никаких ошибок, но я вижу очень маленькую долю, внесенную в мой стол.
$ln = intval(shell_exec("wc -l $text_filename_with_path"));
echo "FILENAME WITH PATH: " . $text_filename_with_path ."\n\n";
echo "ARRAY LENGTH: " . $ln . "\n\n";
//pointer is initialized at zero
$fp = fopen($text_filename_with_path, "r");
$offset = 0;
$c = 0;
while($offset < $ln){
$row_limit = 500;
//get a 500 row section of the file
$chunk = fgets($fp, $row_limit);
//prepare for 'pg_copy_from' by exploding to array
$chunk = explode("\n", $chunk);
//each record from the file being read is just one element
//prepare for three column DB table by adding columns (one
//unique PK built from UNIX time concat with counter, the
//other from a non-unique batch ID)
array_walk($chunk,
function (&$item, $key) use ($datetime, $c) {
$item = time() . $c . $key . "\t" . $datetime . "\t" . $item;
}
);
//increase offset to in order to move pointer forward
$offset += $row_limit;
//set pointer ahead to new position
fseek($fp, $offset);
echo "CURRENT POINTER: " . ftell($fp) . "\n"; //prints out 500, 1000, 1500 as expected
//insert array directly into DB from array
pg_copy_from($con, "ops.log_cache_test", $chunk, "\t", "\\NULL");
//increment to keep PK column unique
$c++;
}
Я получаю, как я говорю, часть содержимого файла, и многие данные выглядят немного испорченными, например, о том, что записи не заполнены в части элемента массива, которая присваивается $item
в моем array_walk()
. Далее кажется, что взрыва на \n
не работает должным образом, поскольку строки кажутся взорванными на неравномерных позициях (т.е. Записи журнала не выглядят симметричными). Я только что сделал полный беспорядок из этого
Вы не используете fgets правильно (2-й параметр - это не количество строк);
На данный момент я могу придумать два способа решить эту проблему: 1. Цикл, получающий одну строку за раз, пока вы не достигли предела строки. код должен выглядеть примерно так (не тестировался, предполагая, что конец строки char "\n" и no "\ r")
<?php
/**Your code and initialization here*/
while (!feof($file)){
$counter = 0;
$buffer = array();
while (($line = fgets($file)) !== false && $counter < $row_limit) {
$line = str_replace("\n", "", $line); // fgets gets the line with the newline char at the end of line.
$buffer[] = $line;
$counter++;
}
insertRows($rows);
}
function insertRows($rows){
/** your code here */
}?>
Предполагая, что файл не слишком big-, используя file_get_contents(); код должен выглядеть примерно так (такие же предположения)
<?php
/**Your code and initialization here*/
$data = file_get_contents($filename);
if ($data === FALSE )
echo "Could not get content for file $filename\n";
$data = explode("\n",$data);
for ($offset=0;$offset<count($data);$offset+=$row_limit){
insertRows(array_slice ($rows,$offset,$row_limit));
}
function insertRows($rows){
/** your code here */
}
Я не тестировал его, поэтому я надеюсь, что все в порядке.