filter_var with the FILTER_SANITIZE_SPECIAL_CHARS option is doing what it is supposed to do:
HTML-escape '"<>& and characters with
ASCII value less than 32, optionally
strip or encode other special
characters.
The newline character (
) has an ASCII value of less than 32, so will be converted to . You could therefore use html_entity_decode to convert them back to their original characters:
$string = "line 1
line 2";
$filtered = filter_var($string, FILTER_SANITIZE_SPECIAL_CHARS);
echo "$filtered
";
echo(html_entity_decode($filtered));
Outputs:
line 1 line 2
line 1
line 2
But I guess that defeats the object of using FILTER_SANITIZE_SPECIAL_CHARS in the first place.
If it is only the newline that is causing the problem, you could replace the HTML character entity ( ) with a newline character, before using nl2br():
echo str_replace(' ', "
", $filtered);
Outputs:
line 1
line 2
Or perhaps even better, skip the middle step, and replace the HTML character entity ( ) with <br />:
echo str_replace(' ', '<br />', $filtered);
Outputs:
line 1<br />line 2
...but I'm not 100% sure what it is you are trying to do.