0

I am using phpmailer to send a monthly report.

It includes the € sign. Thus I need to set encoding to utf-8. I ran into a problem here.

Without encoding like this:

$mail->addStringAttachment($csvstring, $fileName);

the mail gets sent but in the attachment the € sign does not show up

when I try to add encoding:

$mail->addStringAttachment($csvstring, $fileName,  "utf-8", "text/csv");

The mail is sent but body and attachment are not present. I tried looking it up but there seems to be very little documentation.

Am I missing the obvious?

Mathias Kiekens
  • 60
  • 1
  • 10
  • Just browsed the source and I must say PHPmailer seems really awkward and you might consider a switch. However, have a look at what your third parameter is expected to be: `https://github.com/PHPMailer/PHPMailer/blob/master/src/PHPMailer.php#L62`, so "utf-8" is not expected. As the fourth parameter you might wanna try `"text/html; charset=utf-8"`. Bit that's just experimenting. I think I'd reverse-engineer how PHPMailer works if nothing else helps. – Adrian Föder Nov 06 '17 at 10:59
  • There is tons of documentation, linked from the project home page, hidden cryptically under the "Documentation" heading. [The docs on addStringAttachment](http://phpmailer.github.io/PHPMailer/classes/PHPMailer.PHPMailer.PHPMailer.html#method_addStringAttachment) make it pretty clear how you should specify a content-tansfer-encoding when adding an attachment, and it's pretty much the same as in any other library - because it's all the same stuff. – Synchro Nov 06 '17 at 11:41
  • Not everyone works with PHPMailer everyday... So I would prefer not have my nose bitten of. Still I would like to thank you for the helpful link. – Mathias Kiekens Nov 06 '17 at 12:14

2 Answers2

0

See: this line in PHPMailer's source code

$mail->CharSet = 'utf-8';

If you want the CSV to be read as UTF-8 in programs that open it, add a BOM (Byte Order Marker; i.e., "\\xef\\xbb\\xbf") to the string file contents.

"\\xef\\xbb\\xbf".$csvstring

UPDATE:

You can also do it like this.

$mail->addStringAttachment($csvstring, $fileName, "base64", "text/csv; charset=utf-8");

See also, the specs on MIME Content-Type, as it points out the proper way to set encoding; i.e., text/csv; charset=utf-8.

jaswrks
  • 1,115
  • 9
  • 13
  • That sets the encoding for the email body I need to set encoding for the attachment. I allready use this line in the rest of my code – Mathias Kiekens Nov 06 '17 at 11:08
  • @MathiasKiekens Understood. I updated my solution for you. – jaswrks Nov 06 '17 at 11:10
  • after the update: still doesn't seem to work I'm afraid – Mathias Kiekens Nov 06 '17 at 11:12
  • @MathiasKiekens Change encoding that you had, from `utf-8` to `base64` and leave `text/csv; charset=utf-8`. I just tested and it's working good. – jaswrks Nov 06 '17 at 11:13
  • The charset param should not be there, it's irrelevant for base-64-encoded MIME parts. – Synchro Nov 06 '17 at 11:16
  • See also, the [specs on MIME type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type), as it points out the proper way to set encoding; i.e., `text/csv; charset=utf-8` – jaswrks Nov 06 '17 at 11:16
  • @Synchro It's not irrelevant. Base64 is the transfer encoding. The MIME type and encoding (i.e., `text/csv; charset=utf-8`) is how the file should be opened and interpreted once it arrives. – jaswrks Nov 06 '17 at 11:18
  • How and where exactly does a CSV file contain a charset indicator? We'd love to know... Hint: it doesn't, so a charset provided at that point is irrelevant. If it was using a quoted-printable CTA and displayed inline, you might have a point, but it isn't. – Synchro Nov 06 '17 at 11:24
  • @Synchro In the MIME type for the file, or with a BOM. Which is a problem if it's not explicitly stated somewhere, because many CSV apps like the one that Gmail uses, or Excel, will try to open a CSV in another default encoding. So anything we can do to tell the other end it's a UTF-8 file is good. I personally use the BOM to do this, as it's a better way to tell Excel, a popular app. See: https://stackoverflow.com/questions/6002256/is-it-possible-to-force-excel-recognize-utf-8-csv-files-automatically – jaswrks Nov 06 '17 at 11:32
  • @Synchro Just to clarify, I think we are hitting on two different points here. One is about the transfer encoding, which I agree with you. Binary is binary, or base64, whatever. But once the file arrives and is opened, the BOM would help too. – jaswrks Nov 06 '17 at 11:40
  • In apps that don't barf on BOMs, which is largely my experience with them. Most apps assume UTF-8 now - BOMs used to be more useful many years ago when other UTF charsets were more commonly used and you needed to tell them apart. As far as this question goes, the UTF-8 charset might have helped (because the att. would have inherited that), but the thing I meant was "wrong" was failing to correct the use of "UTF-8" as a CTE, which you fixed in an update. FWIW, I find LibreOffice is much better than Excel for CSV wrangling. – Synchro Nov 06 '17 at 11:49
0

You're getting confused. Encoding and CharSet are two different things. Generally the charset does not affect attachments because they are usually base-64 encoded, and thus are only 7-bit.

You can set an overall CharSet and an Encoding for your entire message, but you can override the overall encoding for each attachment.

The correct way to attach your content, as per the docs:

$mail->addStringAttachment($csvstring, $fileName, 'base64', 'text/csv');

With that pattern, the attachment will retain the exact binary content you pass into it - if you still have trouble with characters, it's a problem with the source data, not the sending that's causing it.

Synchro
  • 29,823
  • 14
  • 69
  • 85
  • I don't disagree with my earlier confusion regarding the question and charset. However, I still feel that adding the charset in the content type is the proper way to handle this. Currently, there's nothing in your solution that explicitly sets the encoding to UTF-8, whereas `text/csv; charset=utf-8` does do that according to spec. https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type – jaswrks Nov 06 '17 at 11:23