Reputation: 501
I have a function which sanitizes input from a form and another function which decodes it. It's kind of like bbcode which also converts line breaks into <br />
when storing it in the database (using the nl2br()
function), and then converts the <br />
back into line breaks whenever it is put back into a field for the "edit page" where the user can edit their post (using str_replace('<br />',"\n",$data))
.
The problem is that every time a post is decoded for editing and then coded again for storage, each <br />
turns into two <br /><br />
.
Is a \n or \r equal to two HTML line breaks?
Here is the code for the two functions.
function sanitize2($data) {
$patterns = array();
$patterns[0] = '/</';
$patterns[1] = '/>/';
$data1 = preg_replace($patterns, "", $data);
$bopen = substr_count($data1, '[b]') + substr_count($data1, '[B]');
$bclosed = substr_count($data1, '[/b]') + substr_count($data1, '[/B]');
$iopen = substr_count($data1, '[i]') + substr_count($data1, '[I]');
$iclosed = substr_count($data1, '[/i]') + substr_count($data1, '[/I]');
$uopen = substr_count($data1, '[u]') + substr_count($data1, '[U]');
$uclosed = substr_count($data1, '[/u]') + substr_count($data1, '[/U]');
$bx = $bopen - $bclosed;
$ix = $iopen - $iclosed;
$ux = $uopen - $uclosed;
if ($bx > 0) {
for ($i = 0; $i < $bx; $i++) {
$data1 .= "[/b]";
}
}
if ($ix > 0) {
for ($i = 0; $i < $ix; $i++) {
$data1 .= "[/i]";
}
}
if ($ux > 0) {
for ($i = 0; $i < $ux; $i++) {
$data1 .= "[/u]";
}
}
$newer = sanitize($data1);
$search = array('[b]', '[/b]', '[i]', '[/i]', '[u]', '[/u]', '[B]', '[/B]', '[I]', '[/I]', '[U]', '[/U]');
$replace = array('<b>', '</b>', '<i>', '</i>', '<u>', '</u>', '<b>', '</b>', '<i>', '</i>', '<u>', '</u>');
$newest = str_replace($search, $replace, $newer );
$final = nl2br($newest);
return $final;
}
function decode($data) {
$new = str_replace('<br />',"\n",$data);
$search = array('[b]', '[/b]', '[i]', '[/i]', '[u]', '[/u]');
$replace = array('<b>', '</b>', '<i>', '</i>', '<u>', '</u>');
$newer = str_replace($replace, $search, $new );
return $newer;
}
UPDATE:
I found this page which gives a workaround. Apparently this is a problem with the nl2br() function. :-/
http://websolstore.com/how-to-use-nl2br-and-its-reverse-br2nl-in-php/
Upvotes: 3
Views: 161
Reputation: 6711
From the documentation for nl2br:
nl2br — Inserts HTML line breaks before all newlines in a string
(emphasis mine).
It doesn't replace the newlines, it just inserts linebreaks. So if you try to revert nl2br
by replacing <br />
, you will get two \n
, the old one and the one you inserted when replacing the <br />
.
The easiest fix would be removing all \n
in the string you get from nl2br
, the right thing would be storing the text without the <br />
and convert when you display it.
Upvotes: 1