1
\$\begingroup\$

So I ran into an issue where a client sent me a sample file and the line breaks were not preserved when reading the file using PHP from linux. So I wrote up a little function that should hopefully fix the issue for all platforms.

This is from a larger File class. The function names are pretty self explanatory.

public function fixLineBreaks() {
 $this->openFile();
 // replace all placeholder with proper \r\n
 $contents = str_replace("[%LINEBREAK%]", "\r\n",
 // replace all double place holder with single
 // in case both \r and \n was used.
 str_replace("[%LINEBREAK%][%LINEBREAK%]", "[%LINEBREAK%]",
 // replace all \n with place holder
 str_replace("\n", "[%LINEBREAK%]",
 // replace all \r with placeholder
 str_replace("\r", "[%LINEBREAK%]", 
 // First, read the file.
 fread($this->fp, filesize($this->filename))
 )
 )
 )
 );
 $this->closeFile();
 $this->writeOpen();
 fwrite($this->fp, $contents);
 $this->closeFile();
}

EDIT

Okay, to clarify. I received a CSV file that was supposed to be parsed in PHP. Open it up in notepad and everything is on one line. Opening it with fopen and then reading with fgetcsv would also return the contents as one line. However, if you copy and paste the contents from notepad into NetBeans then all the line breaks are there. This made me realize that there are line breaks but they're not the ones that notepad or PHP recognize.

This was the function that I wrote up which essentially re-writes the file with proper line breaks.

I was posting this here to see if anyone possible had a better solution.

asked Nov 3, 2013 at 20:21
\$\endgroup\$
5
  • \$\begingroup\$ And what exactly are you after? \$\endgroup\$ Commented Nov 3, 2013 at 21:20
  • \$\begingroup\$ What is the expected behaviour? I'm not sure that this code does anything useful. \$\endgroup\$ Commented Nov 3, 2013 at 23:04
  • \$\begingroup\$ @200_success I think it replaces all line breaks (Mac and Unix style) with windows line breaks. \$\endgroup\$ Commented Nov 4, 2013 at 2:56
  • \$\begingroup\$ Have you considered enabling the auto_detect_line_endings setting? \$\endgroup\$ Commented Nov 4, 2013 at 3:28
  • \$\begingroup\$ This title is too vague. Can you provide a sample input string and show us what the desired output is? I am pretty sure I can give a better answer than the one provided, but I need to better understand the desired behavior. @Vit \$\endgroup\$ Commented Mar 4, 2021 at 22:44

1 Answer 1

4
\$\begingroup\$

This conversion can be done by simple apps from the Dos2Unix package.

However, if you insist on writing your own converter, I'd suggest making fewer function calls. The function str_replace() can accept arrays, so there is no need for embedded calls.

$contents = str_replace(
 array("\r", "\n", "[%LINEBREAK%][%LINEBREAK%]", "[%LINEBREAK%]"),
 array("[%LINEBREAK%]", "[%LINEBREAK%]", "[%LINEBREAK%]", "\r\n"),
 fread($this->fp, filesize($this->filename))
);

However, you ought to be careful. For example, if your file has two Unix-standard newlines, i.e., \n\n, then your code will replace this with \r\n, which is only one Windows-standard newline.

This regex (see about its syntax here) would probably do the trick:

preg_replace('#(?<!\r)\n|\r(?!\n)#', "\r\n", fread($this->fp, filesize($this->filename)));

But I still think it's better to use already existing and proven software, like the one from the beginning of this answer, or simply turn on the auto_detect_line_endings setting, as suggested in the comments by 200_success.

By the way, if your files are huge, your fread will still (try to) read them whole at once, which is not pleasant for the computer memory and performance.

Sᴀᴍ Onᴇᴌᴀ
29.5k16 gold badges45 silver badges201 bronze badges
answered Nov 4, 2013 at 12:12
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.