-1

My code as below

$ID = mysqli_real_escape_string($cnx, trim($data->id));
$MSG = mysqli_real_escape_string($cnx, trim($data->message));

$query = "REPLACE INTO mytbl ".
           "(id, msg, dateentry, status, rate) ".
           "VALUES ('$ID', '$MSG', NOW(), 'ok', '$RATE')";

$result =mysqli_query($cnx, $query) or die ("Can't execute query!");

$to = 'my@gmail.com';
$subject = 'my report';
$message = 'Message From User on:  '. $MSG  . "\r\n";
$headers = 'From: anonymous@mymail.com' . "\r\n" .
           'Reply-To: anonymous@mymail.com' . "\r\n" .
           'X-Mailer: PHP/' . phpversion();

mail($to, $subject, $message, $headers);

In my message ($MSG), it contains new line, which is represented by \n. So when the email is sent, the \n persist, instead of the making a new line, it stays as \n. I would like it to be a new line instead of \n displaying on the email.

I have read about How to replace \r & \n with <br/>?, and think perhaps I could use double-quote instead of single, and work with nl2br, but of no success. Perhaps my value comes from somewhere else (i.e. $data->message), so I don't know how to make it a single quote or double quote string. Any light to shed?

Thanks!

(Note the $MSG is both used for DB insertion and Emailing)

Community
  • 1
  • 1
Elye
  • 53,639
  • 54
  • 212
  • 474
  • 2
    So you're saying that `$MSG` contains literal `'\n'` escapes instead of newlines? Find out how that happened, before venturing into a workarounds. (like stripcslashes) – mario Jan 31 '15 at 14:58
  • *"perhaps I could use double-quote instead of single"* - Yes, because `'\n'` will literally show up as \n where using `"\n"` will give you a newline feed. – Funk Forty Niner Jan 31 '15 at 15:00
  • You have to find out where $MSG comes from and find the source of the problem. – Lorenz Meyer Jan 31 '15 at 15:05
  • Thanks guys. I check in more detail, the line of $MSG comes from mysqli_real_escape_string(...), as per my edit above. If I remove the mysqli_real_escape_string, then I get my new line. But then for security purpose, I believe I need to use mysqli_real_escape_string... So how could I do that, yet get my new line? – Elye Jan 31 '15 at 15:12
  • As per your edit `mysqli_real_escape_string` that is most likely the reason. It is escaping characters, and newline most likely. I don't see why you're using that. You're sending mail, not querying a DB. Get rid of it. `mysqli_real_escape_string` has nothing to do with `mail()`. – Funk Forty Niner Jan 31 '15 at 15:12
  • Thanks Fred. I use that for both mail and DB query. I assume I could workaround by separating the variable into two variables then, one with mysqli_real_escape_string (for db query), and one without (for email), right? Is there a way I could just do it using a single variable? – Elye Jan 31 '15 at 15:18
  • 1
    You'd need to show us a bit more code, the one related to the query. If the query is "not" coming from user input, you don't need to escape the data. If you need to filter user input from a form which won't go as an INSERT/UPDATE in DB, just use PHP's filters, not MySQL's. You can also set a new variable for outgoing mail. – Funk Forty Niner Jan 31 '15 at 15:19
  • Thanks Fred. The entire code is pretty long. So I just put a simpler version to illustrate my problem. The $MSG will go into a field to be inserted into MySQL DB. I'll go with the solution of separating them for each usage then. Thanks!! – Elye Jan 31 '15 at 15:25
  • You're welcome Elye. – Funk Forty Niner Jan 31 '15 at 15:26
  • @Elye I used some of my comments and posted it as an answer to close the question; seeing others put answers in, mine was the solution. – Funk Forty Niner Jan 31 '15 at 15:36
  • This is exactly why libraries like [PHPMailer](https://github.com/PHPMailer/PHPMailer) exist. Essentially if you're calling `mail()` yourself, you're doing it wrong. – Synchro Feb 01 '15 at 09:19
  • Fred has answer my inquiry, and I have explained in the comment that I need the $MSG for both DB and Email. Not sure what's wrong with my question that I got -1 for it?. So I put on the question for further clarification showing $MSG is indeed for both DB and Email – Elye Feb 06 '15 at 07:26

3 Answers3

1

Not knowing anything about how $MSG is constructed, you could try something like this:

$MSG = str_replace("\\n","\n",$MSG);

Before adding $MSG to your $message.

Double quotes should be used whenever you want \n to mean newline rather than \\n.

pelmetennui
  • 136
  • 1
  • 3
  • Thanks Pelmetennui. It didn't work for me :(. Removing mysqli_real_escape_string works for me. – Elye Jan 31 '15 at 15:22
  • Ah this has been bugging me for so long, til I realised mysqli_real_escape_string was changing all new lines "\n" to escaped versions "\\n". The str_replace suggestion works for me, finally! – Tiago Mar 16 '16 at 16:16
0

According to mail() documentation the body message MUST have line breaks that include carriage return.

As your email does not seem to be multipart -- with HTML body --, that is, at least you don't specify that it is, you should be able to achieve what is needed with

preg_replace("/(?<=[^\r]|^)\n/", "\r\n", $MSG);

which will replace alone-standing \n with \r\n.

I would suggest, however, not using on mysqli_real_escape_string, as you are not using it to build a SQL statement.

h7r
  • 4,944
  • 2
  • 28
  • 31
0

Removing mysqli_real_escape_string works for me. – Elye

^ as said after my initial comments. ^

Taken from my commments to close the question:

Using mysqli_real_escape_string() is most likely the reason.

It is escaping characters, and newline charcters most likely.

I don't see why you're using that. You're sending mail, not querying a DB. Remove it.

mysqli_real_escape_string() has nothing to do with sending mail().

If the query is "not" coming from user input, you don't need to escape the data.

If you need to filter user input from a form which won't go as an INSERT/UPDATE in DB, use PHP's filters http://php.net/manual/en/filter.filters.php, not MySQL's.

You can also set a new variable for outgoing mail and using PHP's filters; that's what they are there for.

Funk Forty Niner
  • 74,450
  • 15
  • 68
  • 141