Background
To undestand what's going on you need to understand that there are multiple conventions regarding how the end of a line should be represented in a text file.
- Text files generated on Unix/Apple machines usually separate lines with a single newline character:
\n.
- Text files generated on Windows machines usually separate lines with two characters, carriage-return + line-feed:
\r\n.
- Text files generated on very old Apple machines usually separate lines with a carriage return character:
\r. You probably don't need to worry about this as it is very rarely encountered in practice.
Wikipedia has a good summary that explains the history of these different standards.
Your problem
It looks like your example file was created on Windows, and therefore there are two characters between each line. This means that when you explode() on \n each line except for the last one will contain an invisible \r character at the end. This is why only the last line is matching in your example.
Solutions
There are a couple of solutions to this, depending on where your multi-line string data comes from.
If your situation is as indicated in your example, where the string is defined as a literal string in a file you control, you have two options:
- Convert the file to use Unix-style line endings. Most text editors/IDEs allow you to do this via a menu option. You only need to do this once per file (assuming you save it having made the change). If you make this change, your current code will work as-is.
- Update your code to use
$array = explode("\r\n", $multiline_string); so that you are exploding based on Windows line-endings.
If, on the other hand, your data comes from user input then you should code it to handle both types of line-endings1. There are a couple of options here, too:
- Make sure the code that performs the split recognises both line ending styles. The simplest way is to replace the
explode() call with $array = preg_split("/\r?\n/", $multiline_string), which will explode on any instance of \n or \r\n.
- Convert one line-ending style to the other, so that you know the line-ending style in use, and then use
explode(), as before. For example, $multiline_string = str_replace("\r\n", "\n", $multiline_string);. This method is preferable if you are going to do other things with the string later, e.g. store it in the database, as it means you only need to handle this once rather than having to handle both possibilities in all situations.
1 Or all three types, if you want to be thorough. This is left as an excercise for the reader...
preg_spliton\Rinstead: 3v4l.org/HUXr6explode("\n", $multiline_string)toexplode("\r\n", $multiline_string), and it works. So it was the issue of dos line endings.