Кажется, это должно быть просто, но у меня возникли некоторые проблемы с fgetc () при возврате последней строки дескриптора открытого файла. то, что я пытаюсь сделать, это вернуть последнюю строку, записанную в дескриптор, у меня есть следующее, которое работает, если дескриптор имеет только одну строку:
function getLastLineFromHandle($handle)
{
$seeker = function($handle) use (&$seeker) {
fseek($handle, -1, SEEK_CUR);
return ftell($handle) ?
$seeker($handle) :
$handle;
};
return trim(fgets($seeker($handle)));
}
$handle = fopen('php://temp', 'w+');
fwrite($handle, 'Hello World'.PHP_EOL);
//prints Hello World
print getLastLineFromHandle($handle);
Проблема в том, что когда у меня есть несколько строк, записанных в дескриптор, добавление fgetc () к условию проверки, кажется, не работает, например:
function getLastLineFromHandle($handle)
{
$seeker = function($handle) use (&$seeker) {
fseek($handle, -1, SEEK_CUR);
return ftell($handle) && fgetc($handle) != PHP_EOL ?
$seeker($handle) :
$handle;
};
return trim(fgets($seeker($handle)));
}
Это возвращает пустое значение, если в дескриптор записано несколько строк, а fgetc ($ handle), кажется, каждый раз возвращает один и тот же символ?
Я уверен, что есть кое-что очень простое, что я пропустил, но любые указатели были бы хороши, поскольку это сводит меня с ума!
Благодарю.
Обнаружил то, что отсутствовало в приведенном выше примере, оказалось, что это был случай непредвиденного конца символа строки в указателе при запуске, поэтому перемещение на одну позицию в решает проблему, например:
function getLastLineFromHandle($handle)
{
$seeker = function($handle) use (&$seeker) {
fseek($handle, -2, SEEK_CUR);
return ftell($handle) && fgetc($handle) != PHP_EOL ?
$seeker($handle) :
$handle;
};
return trim(fgets($seeker($handle)));
}
Исследуя это, я также нашел другой способ сделать то же самое, благодаря комментарию @ TheMarlboroMan о поиске до конца, который вызвал это:
function getLastLineFromHandle($handle)
{
$seeker = function($handle, $cur = -2, $line = '') use (&$seeker)
{
$char = '';
if (fseek($handle, $cur, SEEK_END) != -1) {
$char = fgetc($handle);
$line = $char.$line;
}
return ftell($handle) > 0 && $char != PHP_EOL?
$seeker($handle, $cur-1,$line) :
$line;
};
return trim($seeker($handle));
}
Это не проходило цикл рефакторинга, однако он проходит те же тесты, что и другой метод, описанный выше. Это решение кажется немного грязным, чтобы возвращать строку строки вместо дескриптора файла, поскольку это то, что вы ожидаете получить обратно.
Установка как решенная, но открытая для комментариев, если у кого-то есть другой путь
Других решений пока нет …