0

I've this function to remove lines from a txt file:

function replace_file($path, $string, $replace)
    {
        set_time_limit(0);

        if (is_file($path) === true)
        {
            $file = fopen($path, 'r');
            $temp = tempnam('./', 'tmp');

            if (is_resource($file) === true)
            {
                while (feof($file) === false)
                {
                    file_put_contents($temp, str_replace($string, $replace, fgets($file)), FILE_APPEND);
                }

                fclose($file);
            }

            unlink($path);
        }

        return rename($temp, $path);
    }

Usage: replace_file("file.txt", "line to remove", '');

It is working perfectly but it always keep an empty line at the end of the file.

Is it possible to solve that?

Any help would be appreciated.

Thanks!

Mario
  • 1,374
  • 6
  • 22
  • 48
  • 1
    It is typically considered correct to leave an empty line at the end of a file. https://stackoverflow.com/a/2287990/2562137 – OrderAndChaos Jul 27 '18 at 16:17
  • 1
    If your only handling small files, then using [file()](http://php.net/manual/en/function.file.php) and array walk then implode into a file would work just the same, but a more optimal solution for both big and small files would be to [use a generator](https://stackoverflow.com/a/43053295/661872), you can't fix the issue with your current code as your using FILE_APPEND, and won't know if its the last line to trim the new line. – Lawrence Cherone Jul 27 '18 at 16:27
  • @Sarcoma Why is that? (Technically speaking). I always remove it when I come across it; wondering if I should stop, lol. – J. Scott Elblein Jul 27 '18 at 16:35
  • @J.ScottElblein It's a hang over from older systems that expect an empty line before EOF. In PHP it's part of PSR-2. – OrderAndChaos Jul 27 '18 at 16:41
  • [`set_time_limit(0)`](https://php.net/set_time_limit) Setting that to zero is a REALLY bad idea within a function call. Functions shouldn't have side effects like that. – Mark Tomlin Jul 27 '18 at 17:05

2 Answers2

1

If you're only looking to remove the empty line at the end, have a look at rtrim.

J. Scott Elblein
  • 4,013
  • 15
  • 58
  • 94
1

I've edited the function to be like that:

function replace_file($path, $string, $replace)
    {
        set_time_limit(0);

        if (is_file($path) === true)
        {
            $file = fopen($path, 'r');
            $temp = tempnam('./', 'tmp');

            if (is_resource($file) === true)
            {
                while (feof($file) === false)
                {
                    file_put_contents($temp, str_replace($string, $replace, fgets($file)), FILE_APPEND);
                    file_put_contents($temp,
                        implode('', file($path, FILE_SKIP_EMPTY_LINES)));
                }

                fclose($file);
            }

            unlink($path);
        }

        return rename($temp, $path);
    }

And now it works.

Mario
  • 1,374
  • 6
  • 22
  • 48