views:

90

answers:

3

Hi.

I am trying to store HTML posted from a textarea into a database. I have a textarea inside a form which I have called "message". The PHP code that processes it is:

if(isset($_POST['submit'])){
    if(isset($_POST['title']) && isset($_POST['message'])){
        $title = $_POST['title'];
        $message = $_POST['message'];

        if(get_magic_quotes_gpc()){         
            $title = stripslashes($title);
            $message = stripslashes($message);
        }

        $title = mysql_real_escape_string($title);
        $message = mysql_real_escape_string($message);

        $q = "INSERT INTO table (title,datetime,text) VALUES ('{$title}',NOW(),'{$message}')";
        $rows_affected = $db->exec($q);
        if($rows_affected > 0){
            echo "<p>Done.</p>";
        } else {
            echo "<p>Failed. </p>"; 
        }
    }
}

The problem I am having is then retrieving this and converting newlines to <br />. Here is what I am doing:

$res = array();

$order = array("\r\n","\n","\r");
$replace = '<br />';

$q = "SELECT title,datetime,text FROM table";
$res = $db->get_all($q);
if($res){
    foreach($res as $result){
        $result['title'] = stripslashes($result['title']);
        $result['text'] = str_replace($order, $replace, stripslashes($result['text']));
    }       
}

echo "<pre>";
print_r($res);
echo "</pre>";

I just can't get rid of those pesky \r\n's in the message. I have tried changing $order to

$order = array("\\r\\n","\\n","\\r");
// and even
$order = array("\\\r\\\n","\\\n","\\\r");

but nothing seems to work. Any ideas?

A: 
if ($res = $db->get_all('SELECT title,datetime,text FROM table')){
    foreach ($res as &$result){
        $result['text'] = nl2br($result['text']);
    }       
}

echo "<pre>";
print_r($res);
echo "</pre>";

I did three things:

  • Remove the stripslashes. They mustn't be there. The slashes mysql_real_escape_string adds are removed when the query is executed.
  • I used the function nl2br for the new lines. Why write something yourself if it's already built in?
  • I added a & in front of $result in the foreach loop. If I didn't do this only the shallow copies were modified, not the variables themselves. Thus there wouldn't be any change at all.
nikic
tomh
Actually you did 4 things: you left useless ` $result['title'] = $result['title'];` line in place :)
Col. Shrapnel
@Col: Ooops, didn't even look at the resulting code ^^ Fixed that now.
nikic
A: 

For the retrieving of the data you don't need to screw around with str_replace/stripslashes.

$res = array();

$q = "SELECT title,datetime,text FROM table";
$res = $db->get_all($q);
if($res){
    foreach($res as &$result){
        $result['title'] = $result['title']; // Don't see the reason for stripslashes here
        $result['text'] = nl2br($result['text']);
    }       
}

echo "<pre>";
print_r($res);
echo "</pre>";

Use nl2br to convert your \n to proper HTML line breaks. (Note: If you want to show the text inside of a textarea again, e.g. for editing, you need to output the "text" as-is). The only thing that you would want to do is use strip_tags to prevent HTML from being inserted into your output.

halfdan
He doesn't use magic quotes, he removes them.
nikic
Whoops. True, I was too quick on that one.
halfdan
An important point imo is that nl2br() adds "<br />" (or "<br>" if the second argument is false) to the string in front of "\r\n", or in front of any "\n" that isn't directly preceded by "\r" (as Lekensteyn also pointed out). It doesn't "convert your \n to proper HTML line breaks".
GZipp
A: 

more usual way of what nikic did

foreach ($data as $key => $row){
  $data[$key]['text'] = nl2br($row['text']);
}

you did overwrite your temporary $result variable, while you have to write modified variable back into array. and give our variables sensible names.
Also, consider to use htmlspecialchars() if it's user supplied text.

Col. Shrapnel