Добрый вечер уважаемые знатоки. помогите с кодом, имеется txt файл в него ссыпаться логи. как сделать выборку и поиск по значению я разобрался Код (Text): <?php $file = 'main.txt'; $need = '0000001A0BC1E3'; foreach (file($file, FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES) as $line) { if (preg_match("~{$need}.*~", $line, $string)) { echo str_replace($need, "$need:", $string[0]); } } ?> все выводится на сайт, но в этом текстовом файле есть информация до поискового значения, и как ее вывести не знаю. Может кто подскажет?
Если это подобие лога, где каждая запись это новая строка, то можно распарсить в массив и далее работать уже с массивом.
Да это лог файл, каждая запись новая строка. Вот его содержимое Код (Text): 137.34.14.1 Jun 09 19:39:56 1 user err 2023-06-09T19:39:34.000000+07:00 60.5.3.252 DKS20211_rev5.4.3.8.4_18688231BFF5 - - - Unable to sync time with ntp server time.windows.com, timezone 28 137.34.14.1 Jun 09 19:39:56 1 user info 2023-06-09T19:39:34.000000+07:00 60.5.3.252 DKS20211_rev5.4.3.8.4_18688231BFF5 - - - EVENT:000:RTSP client 185.111.219.4 incoming command GET_PARAMETER 137.34.14.1 Jun 09 19:40:01 1 user info 2023-06-09T19:39:39.000000+07:00 60.5.3.252 DKS20211_rev5.4.3.8.4_18688231BFF5 - - - EVENT:000:Request: /cgi-bin/sip_cgi?action=regstatus, userLevel=2, ip=91.107.86.49 137.34.14.1 Jun 09 19:40:14 1 user err 2023-06-09T19:39:51.000000+07:00 60.5.3.252 DKS20211_rev5.4.3.8.4_18688231BFF5 - - - Unable to sync time with ntp server time-nw.nist.gov, timezone 28 137.34.14.1 Jun 09 19:40:26 1 user info 2023-06-09T19:40:03.000000+07:00 60.5.3.252 DKS20211_rev5.4.3.8.4_18688231BFF5 - - - EVENT:000:RTSP client 185.111.219.4 incoming command GET_PARAMETER Вот после искомого значения "185.111.219.4" я получаю текст, а вот до него нет. подскажите кодик? или строчку вывести со всем значением.
PHP: foreach (file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $line) { if (stripos($line, $need) !== false) { echo str_replace($need, "$need:", $line) . PHP_EOL; } }
PHP: function read($path): Generator { $handle = fopen($path, "r"); while (!feof($handle)) { yield fgets($handle); } fclose($handle); } $generator = read($file); foreach ($generator as $line) { if (stripos($line, $need) !== false) { echo str_replace($need, "$need:", $line); } }
Все выше перечисленный код говно. Все ваши fopen, popen, file - канут на дно. Явись на свет о божественный и встроенный класс для всего этого... Спойлер: О боги PHP кода, ААААААА.... PHP: new SplFileObject( "Пук" )
Протестировал быстродействие чтения файла размером 12GB. При этом, если в данном файле делать поиск функцией stripos результата можно не дождаться. Изначально думал, что fopen будет быстрее, чем SplFileObject, но тесты показывают идентичный результат. fopen + yield: Time 12.416576147079 seconds. Memory 2.37 mb SplFileObject: Time 12.427870988846 seconds. Memory 2.37 mb SplFileObject + strpos: Time 30.803168058395 seconds. Memory 2.37 mb SplFileObject + stripos: Time 508.74000191689 seconds. Memory 3.32 mb Оптимальный результат. PHP: $file = new SplFileObject($file, 'r'); while (!$file->eof()) { $line = $file->fgets(); if (strpos($line, $need) !== false) { echo str_replace($need, "$need:", $line); } }
В файле нет пустых строк и искомого значения "0000001A0BC1E3" PHP: <?php $time_start = microtime(true); function formatBytes($bytes, $precision = 2) { $units = array("b", "kb", "mb", "gb", "tb"); $bytes = max($bytes, 0); $pow = floor(($bytes ? log($bytes) : 0) / log(1024)); $pow = min($pow, count($units) - 1); $bytes /= (1 << (10 * $pow)); return round($bytes, $precision) . " " . $units[$pow]; } $file = 'dev.log'; $need = '0000001A0BC1E3'; //function read($path): Generator //{ // $handle = fopen($path, "r"); // // while (!feof($handle)) { // yield fgets($handle); // } // // fclose($handle); //} // //$generator = read($file); // //foreach ($generator as $line) { // if ($line === '') { // echo $time_start . "\n"; // } //} $file = new SplFileObject($file, 'r'); //while (!$file->eof()) { // $line = $file->fgets(); // if ($line === '') { // echo $time_start . "\n"; // } //} //while (!$file->eof()) { // $line = $file->fgets(); // if (stripos($line, $need) !== false) { // echo $time_start.'\n'; // } //} while (!$file->eof()) { $line = $file->fgets(); if (strpos($line, $need) !== false) { echo $time_start.'\n'; } } $time_end = microtime(true); $time = $time_end - $time_start; echo "Time $time seconds.\n"; echo "Memory " . formatBytes(memory_get_peak_usage());
PHP: $time_start = microtime(true); // Time 16.979219913483 seconds. foreach ( new SplFileObject( '3g.bin', 'r' ) AS $id => $line ) { } // Time 17.596244096756 seconds. /* $handle = fopen('3g.bin', "r"); while (!feof($handle)) { fgets($handle); } fclose($handle); */ $time_end = microtime(true); $time = $time_end - $time_start; echo "Time $time seconds.\n";
Делал тесты не один раз. С моим конфигом (php 7.4) время всегда разное, но плюс минут одинаковое. Иногда SplFileObject быстрее иногда fopen. Пробовал добавлять флаги для SplFileObject. Время практически не отличается. Возможно foreach немного быстрее.
каким циклов неважно. SplFileObject имеет все остальные функции по чтению больших файлов. То что выше написал - это результат только на 3 гигов данных и чем выше объем, тем существенно разница будет видна. По поводу цикла, я не вижу смысла дергать feof. И включать strpos у одной измеряемой функции, а в другой - игнорируя. Так что хз как у тебя там измеряется и при каких размерах файла.
Выше писал что тест проводил на логах в 12 GB. Четыре теста первые два на скорость чтения там нет strpos. 3 и 4 на поиск в строке. Да, можно и без feof SplFileObject наследуется от итератора. SplFileObject без feof не тестировал.
Провел тесты еще раз. Чтобы не быть голословным SplFileObject + почти всегда быстрее SplFileObject + foreach всегда медленней чем while + eof и fopen + eof AMD Ryzen 5 3350G 16,0 ГБ samsung ssd 970 evo plus 250gb Результаты тестов: SplFileObject + eof Time 15.993134021759 seconds. Memory 2.35 mb Time 16.395498991013 seconds. Memory 2.35 mb Time 15.90164399147 seconds. Memory 2.35 mb ========================================= SplFileObject без eof Time 18.657531023026 seconds. Memory 2.38 mb Time 17.759664058685 seconds. Memory 2.38 mb Time 18.000351905823 seconds. Memory 2.38 mb ======================================= fopen + eof Time 16.367401123047 seconds. Memory 2.35 mb Time 16.460517883301 seconds. Memory 2.35 mb Time 16.38111114502 seconds. Memory 2.35 mb ===================================== SplFileObject + setFlags +eof Time 16.057915210724 seconds. Memory 2.35 mb Time 16.160215139389 seconds. Memory 2.35 mb Time 15.913039922714 seconds. Memory 2.35 mb