PHP Tutorial: Create a nl2br function that doesn’t add tags inside of textarea contents

Comment 1 Standard

So this really bugs me and I thought I would share. Let’s say you want to allow someone to post their own custom html in a message or on a part of your website. If you’re using nl2br to format that message and they have <textarea> tags inside of their content then when you apply nl2br it adds <br> tags to the content inside of their textarea. For example:

$query = mysql_query("SELECT custom_html FROM users WHERE uid='$uid'") or die ('cannot load user custom html content');
$user_content = mysql_fetch_assoc($query);
echo nl2br($user_content['custom_html']);

If the user’s custom_html had:

Hi guys!
My name is Joe.
<textarea>this is
my html content</textarea>

Applying nl2br to that would result in the following:

Hi guys!<br />My name is Joe.<br /><textarea>this is<br />my html content</textarea>

So here you can see that we have <br /> tags inside of our textarea. When we display this on the page the textarea displays the <br> tags instead of indenting the content to a new line like we expect it to. This is where my code snippet comes into play.

//replace your nl2br function with our new nl2br_textarea function
function nl2br_textarea($message)
{
    $message = nl2br($message);

    function scrub_textarea($data) {
        return str_replace(array("<br>", "<br/>", "<br />"), "", $data[0]);
    }
    return preg_replace_callback('#<textarea[^>]*>(.*?)</textarea>#is',scrub_textarea,$message);
}

Using our nl2br_textarea function our original code would be updated to look like this:

$query = mysql_query("SELECT custom_html FROM users WHERE uid='$uid'") or die ('cannot load user custom html content');
$user_content = mysql_fetch_assoc($query);
echo nl2br_textarea($user_content['custom_html']);

Which means the output of user’s custom_html will now be this where we actually see a line break in the textarea without the additional <br> tags thrown into the mix:

Hi guys!<br />My name is Joe.<br /><textarea>this is/nmy html content</textarea>