Doc #81158 [Com]: Mails sent by mail function broken since PHP 8.0

[email protected] ("paybyplatema dot website at gmail dot com") Thu, 04 May 2023 04:58:50 +0000
Newsgroups php.doc.bugs
Message-ID <[email protected]>
Edit report at https://bugs.php.net/bug.php?id=81158&edit=1

 ID:                 81158
 Comment by:         paybyplatema dot website at gmail dot com
 Reported by:        php at shyim dot de
 Summary:            Mails sent by mail function broken since PHP 8.0
 Status:             Open
 Type:               Documentation Problem
 Package:            Mail related
 Operating System:   Debian 10 (Docker)
 PHP Version:        8.0.7
 Block user comment: N
 Private report:     N

 New Comment:

Nice post! We do our best to stay compliant. We don't need issues.

https://www.paybyplatema.website/github.com


Previous Comments:
------------------------------------------------------------------------
[2023-03-29 22:01:42] myjohnjdf at gmail dot com

The information you have posted is very useful. The sites you have referred was good. Thanks for sharing. (https://myjdfaccount.top/)github.com

------------------------------------------------------------------------
[2023-03-24 16:15:51] centurasite at gmail dot com

Thanks for sharing it, it is certainly helpful. Keep on sharing such stuff. (https://mycenturahealth.site/)github.com

------------------------------------------------------------------------
[2022-12-22 10:48:37] Rester256Walsh at gmail dot com

Add a mail header in the mail function:

$header = "From: [email protected]\r\n";
$header.= "MIME-Version: 1.0\r\n";
$header.= "Content-Type: text/html; charset=ISO-8859-1\r\n";
$header.= "X-Priority: 1\r\n";

$status = mail($to, $subject, $message, $header);

if($status)
{
    echo '<p>Your mail has been sent!</p>';
} else {
    echo '<p>Something went wrong. Please try again!</p>';
}


(https://www.mycenturahealth.us/)github.com

------------------------------------------------------------------------
[2022-12-12 05:24:24] farid dot jamili4118 at gmail dot com

That's great. I was impressed by your writing. I am happy to see such a topic. Please come to my blog and read it.

 (https://www.mygiftcardsite.vip/)php.net

------------------------------------------------------------------------
[2022-07-15 11:20:57] php-nospam at ecartz dot biz

While it is true that the email standard is CRLF, that's not really the issue here.  PHP invokes sendmail via the shell.  The Linux shell expects line endings to be LF.  Then the sendmail app converts the LF to CRLF.  As far as I know, that's how every shell-invoked sendmail works so as to allow people to pipe text directly to sendmail.  

sendmail [email protected] < body.txt

So what this change did, is it made PHP munge the line endings into ones that would be invalid to the shell.  This then breaks those sendmail apps that when invoked by shell expect line endings valid in the shell and replace the shell's line endings with those valid in an email without further checking to see if the line endings are already valid in an email.  

Prior to this change, those of us who maintain frameworks that run on many systems would tell people to us SMTP with CRLF line endings on Windows and sendmail with LF line endings on Linux.  Now, we have to tell people to use LF line endings on Linux when PHP < 8 and CRLF the rest of the time.  And if they happen to be using a sendmail that can't handle CRLF, tell them to switch sendmail.  And to make this worse, PHP didn't bother to report this in the changelog for PHP 8.  So I spent some time trying to figure out what changed from 7.4 to 8 (and only found it in a Drupal bug report).  

Now, it may be that the reasons for this change outweigh the reasons against it.  No one has linked any other bug reports that this change would fix, so I can't say.  But at minimum, it should be reported at https://www.php.net/manual/en/migration80.incompatible.php so that people can find it.  

It's also worth noting that another way of looking at the problem is that PHP is invoking sendmail via the shell.  If you want to send emails with CRLF, then the proper way is to invoke via SMTP.  SMTP expects CRLF line endings.  If PHP would make the SMTP connection directly without invoking sendmail through the shell, then this wouldn't be an issue.  Of course, then you would have to maintain code to email via SMTP.  

Alternately, you could allow systems to specify the line ending to use in php.ini so that they could configure it together with sendmail.  Then just do something like `if (ini_get('sendmail.fix-line-endings') ) $email = str_replace(["\r\n", "\r", "\n"], ini_get('sendmail.line-ending'), $email)` to fix the line endings.  Most frameworks use some kind of solution like this, controlling the behavior with configuration.

Long term, it looks like most hosts are switching to authenticated SMTP.  You might consider adding support for that in the mail function.  Or replacing mail entirely with a class where various properties can be set.  

My gut instinct is that the problem is that you are using the shell but trying to use the email RFC rules.  So I would think that the old behavior was correct and the new behavior is wrong.  But as I said, there may be reasons unknown to me why CRLF is necessary even when invoking through the shell.  If so, could you please link to places where this is discussed so that we can see what's going through your mind?  

All I see is https://bugs.php.net/bug.php?id=47983 which doesn't talk about the shell at all, even though this behavior should clearly be different based on the communication method.  Looking at the patch suggests that you do have separate behavior between Windows and Linux, so you could use the system line ending in the shell.

------------------------------------------------------------------------


The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

    https://bugs.php.net/bug.php?id=81158


--
Edit this bug report at https://bugs.php.net/bug.php?id=81158&edit=1