mail()

The mail() Function and Its Limits

On Linux mail($to, $subject, $message, $headers) does not speak SMTP. It pipes the message into the program in sendmail_path (/usr/sbin/sendmail -t -i, supplied by Postfix 25,527 or Exim 38,599 ) and returns true if that program exits with status 0. $headers has accepted an array since PHP 7.2.

mail-plain.php: a plain-text message through mail()PHP
<?php
declare(strict_types=1);
var_dump(mail('reader@example.com', 'Your order #1001', "Thanks for your order.\r\n",
    ['From' => 'Bookshop <orders@example.com>']));
Output
$ php -d log_errors=0 mail-plain.php                  # this server has no MTA
sh: 1: /usr/sbin/sendmail: not found
bool(false)
$ php -d sendmail_path='docker exec -i mailpit /mailpit sendmail' mail-plain.php
bool(true)

The second run uses Mailpit's sendmail command. true means "handed over", not "delivered": a later bounce never reaches PHP. There is no SMTP authentication, TLS or timeout (on Windows PHP speaks bare SMTP to the SMTP ini host), you build the MIME yourself, and PHP adds no Date, Message-ID or DKIM signature. Keep mail() for cron notices to yourself.