Current e-mail handling in PHP is dreadful. Almost every framework
implements it's own email handling class in order to make sending e-mail
reliable, easy to configure, and to implement multiple mail schemes.
This means for developers working on multiple frameworks, they can't
just call mail($recipient, $subject, $message) - they have to perform
convoluted checking to find out what framework they are using, and then
use the appropriate api.
That was understandable in PHP v4 and in v5 - 5.2.
Today though it is a waste of time, PHP internally has implemented a
smart, extensible system for generalizing access to system oriented
structures. Handlers/Wrappers.
By subclassing the appropriate handler class, a PHP application can
implement specific functionality to handle specific elements of Session
and Stream processing, without having to implement every one of them and
without requiring specialized PHP classes to be used directly.
http://www.php.net/manual/en/function.session-set-save-handler.php
http://www.php.net/manual/en/function.stream-wrapper-register.php
http://www.php.net/manual/en/class.sessionhandler.php
http://www.php.net/manual/en/class.streamwrapper.php
My proposal[which I am willing to work on coding] is to replace the
current mail()
function with one that will support handlers.
Note: This is only to handle HALF of the issues that we deal with when
sending e-mail: sending the actual message. It does not attempt to
address creating/formatting e-mail messages except in a very general
since. My proposed class would be:
class MailMessage {
/* Properties */
$private array $recipients;
$private string $sender;
$private string $subject;
$private string $body;
$private string $header;
$private string $additionalParamters;
$private array $sentTo;
// Mail handler used to send mail, if none specified the current default
handler is used
$private MailHandler $handler;
/* Primary Methods */
/* create a new mail message, constructor parameters mimic current
mail()
function parameters. Throws exception if there is a problem.
It is perfectly valid to create a message and not specify any of the
parameters - it is only when the message is SENT that the parameters
must be valid */
public MailMessage __construct ( [string $to, string $subject, string
$message, string $additional_headers, string $additional_parameters,
string $from, MailHandlerInterface $handler] )
/* Send a mail message. Throws exception on problems. If $handler is
specified, then that handler is used. If not specified, then the the
objects $handler property is used. */
public MailMessage send ([MailHandle $handler ]);
/* Utility Methods */
/* Sets appropriate private properties, checks parameters and
throwsexceptions when not properly formatted */
public MailMessage setRecipients ( array $recipients )
public MailMessage setSender ( string $sender );
public MailMessage setSubject ( string $$subject );
public MailMessage setBody ( string $body );
public MailMessage setHeader ( string $header );
public MailMessage setAdditionalParameters ( string $additionalParameters );
public MailMessage setHandler( MailHandlerInterface $handler );
public MailMessage setSentTo();
/* Magic method to allow direct setting of sender, subject, body,
recipients, and additionalParameters. It is not recommended to
allow the setting of mail handler or sentTo in this manner. */
public MailMessage __set();
/* Gets appropriate private properties and returns them
either as strings or as arrays */
public mixed getRecipients([string $format = 'string']);
public mixed getSubject([string $format = 'string']);
public mixed getBody([string $format = 'string']);
public mixed getHeader([string $format = 'string']);
public mixed getAdditionalParameters([string $format = 'string']);
public MailHandlerInterface getHandler();
public array getSentTo();
/* Magic get method for sender, subject, body, recipients,
and additionalParameters. It is not recommended to allow retrieval
of the mail handler in this manner. Always returns data as an
associative array. */
public array __get();
}
Sending e-mail in an object oriented manner can be as simple as:
$message = new MailMessage($to, $subject, $message);
$message->send;
Or simply continue to use mail($to, $subject, $message) and it will
handle the above transparently.
In addition to a MailMessage class, there would also be a MailHandler
interface. It only requires 2 methods, send and sendBatch.
MailHandlerInterface {
/* Methods */
abstract public bool send ( MailMessage $message [, string $address ] )
abstract public bool sendBatch ( MailMessage $message [, array
$recipients ] )
}
sendBatch at it's simplest would simply loop through each recipient in
the message and call send($message, $recipient). It could also be
called to send mail only to specific recipients. Handlers are free to
use other logic, for example if using Postfix's maildrop function, the
message can be saved as a file to a specific directory and Postfix
monitors the directory and send's e-mail from it: no need to make costly
network connections for every recipient.
send is used to deliver a message to a single recipient. If a message
has multiple potential recipients, send should throw an exception if the
specific recipient is not specified via $address.
The send and sendBatch function CAN be used to send a message to an
address that is not listed as a recipient. IE this method can be used
for transparently copying others for every message the handler sends out.
Both send and sendBatch must update the sentTo property of the message
to add each recipient a message is actually sent to. This allows mass
e-mail situations to add tracking information to embedded images in the
message for each recipient. Note, such functionality is beyond the
scope of the base interface.
Both send and sendBatch MAY check the sentTo property and avoid sending
duplicate copies of a message but this is NOT required.
Lastly, this would require an additional function:
bool mail_handler_register ( MailHandlerInterface $handler [, int $flags
= 0 ] )
My goal is that the creation and sending of basic e-mail should be a
simple operation. It should be possible for a developer to simply call
the mail()
function and not be concerned about possible e-mail handling
configurations.
At the same time, Application Designers and Framework designers should
be able to augment basic e-mail delivery with their own custom handling
rules. Adding the above functionality to PHP would allow for easy
migration - in most cases all they would have to do is add the send and
sendBatch methods to their current mail class and make sure to flag the
class as implementing the MailHandlerInterface. Then it can be
registered to deal with sending or not.
Possible additions to the above would be:
A MailHandlerClass which can be extended. This way a handler that only
wanted to customize the send or sendBatch method could simply inherit
the base methods and customize.
Adding a createMessage method to the MailHandlerInterface so that the
message object that is created by mail($to, $subject, $message) can
include custom functionality.
Adding a mail_create() function which would return a MailMessage object
using the createMessage method from the currently registered
MailHandlerInterface.
Feedback on changes to the classes to bring things in line with current
standards is appreciated. In addition, pointers to the files which
currently implement the handler functionality in PHP would be
appreciated. I believe I found the functionality, but as I read the
code it seems that SessionHandlers and StreamHandlers do not inherit any
common code, ie each one is coded individually - so if there is a
generic mechanism for registering/using handlers already in the code I
am missing I'd rather extend that then write new code. :-)
-Gary
Hi!
Current e-mail handling in PHP is dreadful. Almost every framework
implements it's own email handling class in order to make sending e-mail
reliable, easy to configure, and to implement multiple mail schemes.
That is probably because sending mail involves more than just passing a
stream of bytes to SMTP server. There's MIME, encodings, headers, etc.
which all need to be taken care of. There's email server configurations.
There's error handling.
class MailMessage {
/* Properties */
$private array $recipients;
$private string $sender;
$private string $subject;
$private string $body;
$private string $header;
What is "header"? If it's a content of whole header, then a) it already
includes all previous fields except "body" and b) you'd still need a
user class to actually make any use of it.
Does it mean if I set $header it would automatically set all the rest of
the fields contained there? Does it mean if I set $subject $header would
automatically be updated?
$private string $additionalParamters;
What those will be used for?
public MailMessage __construct ( [string $to, string $subject, string
$message, string $additional_headers, string $additional_parameters,
string $from, MailHandlerInterface $handler] )
Why additional_headers is a string and not array? That would open the
door to a lot of confusion with formatting the long lines, line endings,
etc. that should be taken care of by basic class.
Same with to - why won't it accept array of email addresses too instead
of making the user figure out how to properly quote and merge them? If
we are already trying to help them...
/* Send a mail message. Throws exception on problems. If $handler is
specified, then that handler is used. If not specified, then the the
objects $handler property is used. */
public MailMessage send ([MailHandle $handler ]);
Why send returns MailMessage? What use would I make of it?
/* Magic method to allow direct setting of sender, subject, body,
recipients, and additionalParameters. It is not recommended to
allow the setting of mail handler or sentTo in this manner. */public MailMessage __set();
Why the difference with mail handler and sentTo?
In addition to a MailMessage class, there would also be a MailHandler
interface. It only requires 2 methods, send and sendBatch.MailHandlerInterface {
/* Methods */
abstract public bool send ( MailMessage $message [, string $address ] )
abstract public bool sendBatch ( MailMessage $message [, array
$recipients ] )
}
Why we need $address and $recipients if those are already in the message?
sendBatch at it's simplest would simply loop through each recipient in
the message and call send($message, $recipient). It could also be
Why one needs a separate method then? Also, being the interface, it
means that each implementation should copy this method even though we
already know what it would look like. Also, sending to each recipient
individually may be a waste of resources since for most configs one can
send the email with multiple recipients to the mail server once, and let
the server figure out how to handle them.
send is used to deliver a message to a single recipient. If a message
has multiple potential recipients, send should throw an exception if the
specific recipient is not specified via $address.
How this would be useful? Sending email to one or more than one
recipient is not different in any way, moreover, same email may be sent
to one or more recipients depending on the configuration. Why would a
method throw an exception if the email does not contain specific address
in the recipient list? What's the use case for such logic?
Both send and sendBatch must update the sentTo property of the message
to add each recipient a message is actually sent to. This allows mass
e-mail situations to add tracking information to embedded images in the
message for each recipient. Note, such functionality is beyond the
scope of the base interface.
I'm not sure how that is supposed to work - send will return after the
message is sent, supposedly, so how I would add embedded images if the
message has been already sent? Also, why would I use message sending
class to get email addresses which I supposedly passed it anyway - if I
had them, why wouldn't I first set the images and only then send it?
My goal is that the creation and sending of basic e-mail should be a
simple operation. It should be possible for a developer to simply call
themail()
function and not be concerned about possible e-mail handling
configurations.
I'm not sure - so how you actually configure the email server in your
model and what advantage it gives over mail()
? Is it just the framework
for mail()
to call? Then it probably should just have one send() method
and not contain any business logic - that should be either in mail()
or
in specific handlers. I actually like the idea of such class for mail()
alike to what we did for sessions, but the API should be refined so that
it matches what people do with emails, and error reporting capabilities
should be added (e.g. for some applications what email server answered
is actually important).
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
Gary Mort wrote:
My goal is that the creation and sending of basic e-mail should be a
simple operation. It should be possible for a developer to simply call
themail()
function and not be concerned about possible e-mail handling
configurations.I'm not sure - so how you actually configure the email server in your
model and what advantage it gives overmail()
? Is it just the framework
formail()
to call? Then it probably should just have one send() method
and not contain any business logic - that should be either inmail()
or
in specific handlers. I actually like the idea of such class formail()
alike to what we did for sessions, but the API should be refined so that
it matches what people do with emails, and error reporting capabilities
should be added (e.g. for some applications what email server answered
is actually important).
Right, the real complication is actually at the PHP configuration level.
At the userspace level it is hard to know how a particular PHP
installation has been configured in terms of what happens when you call
mail()
. That is partially by design. Not the information hiding part,
but the separation between the configuration and the mail function
itself and the relative dumbness of that mail()
function.
The way I intended, and the way I hoped, people would configure their
PHP and underlying mail setups when I initially wrote the mail()
function (nearly 20 years ago now) was for sendmail (or equivalent) to
run in queue-only mode with a periodic queue run. This has multiple
advantages:
-
Sending an email is virtually instantaneous as far as PHP is
concerned since the email is just written to the local queue (which
could be on the same or a different host on the local network) -
A high percentage of people have their emails hosted by a small
number of large companies. gmail, hotmail, yahoo mail, etc. So by
using a queue and batch process mode your mail transfer agent will
make a single connection to gmail and send every message destined
for gmail in a single connection even if those messages originated
from many different scripts on your end. -
Mail transfer agents are incredibly complex. Trying to do any of
this in PHP to any acceptable level of completeness would have been
way too much of a timesink.
I know some frameworks have tried to tackle #3 there because they can't
rely on a sane local mail configuration. I read your suggestions through
twice and honestly I can't quite figure out what you are trying to
solve. Is it #3? It didn't quite seem like it. You still want to let the
system admin define the actual underlying mail stream mechanism, I
think, since #1 and #2 are essential for performance and efficiency. So
it is just a really complicated version of the mail()
function, right?
-Rasmus
Hi!
Current e-mail handling in PHP is dreadful. Almost every framework
implements it's own email handling class in order to make sending e-mail
reliable, easy to configure, and to implement multiple mail schemes.That is probably because sending mail involves more than just passing a
stream of bytes to SMTP server. There's MIME, encodings, headers, etc.
which all need to be taken care of. There's email server configurations.
There's error handling.
Sending mail is just passing a stream of bytes to a stream. That stream
could be an SMTP server, it can be an executable program, or it can be a
file.
Generating proper Mime attachments, encoding, headers, etc deal with
e-mail formatting and will affect how mail is displayed- but their
impact on mail delivery should be non-existant!
See RFC2822, https://tools.ietf.org/html/rfc2822#section-3.5
The only elements you need for e-mail delivery is a recipient and a
message. Subject, from, headers, etc are all optional.
Note 'should be' - in practice they MAY have an impact depending on to
what MDA[Mail Delivery Agent] PHP is submitting the message. The MDA
/may/ extrapolate missing information from the header fields and it
/may/ modify the header fields. This message is a good example, if you
are receiving individual list messages you will have 2 copies[the one I
sent to the list and the one I sent to you] - you can compare the
headers and see how the mail list[which itself is an MDA] modified the
headers from the originals.
class MailMessage {
/* Properties */
$private array $recipients;
$private string $sender;
$private string $subject;
$private string $body;
$private string $header;What is "header"? If it's a content of whole header, then a) it already
includes all previous fields except "body" and b) you'd still need a
user class to actually make any use of it
Does it mean if I set $header it would automatically set all the rest of
the fields contained there? Does it mean if I set $subject $header would
automatically be updated?
Good point, there are a couple of extra parameters/properties:
$recipients['cc'], and $recipients['bcc']. Everything else maps
directly to the current mail function. Those 2 properties are mapped
implicitly for the mail function today.
bool mail ( string $to , string $subject , string $message [, string
$additional_headers [, string $additional_parameters ]] )
CC and BCC today must be placed manually in $additional_parameters today
and under this proposal, you can still do that when using the mail()
function.
If, however you decide to use the MailMessage class, you have the option
of specifying them directly through setRecipients().
Beyond that, everything functions in the same manner as it does today.
IE $header has no direct relationship to $subject, $to, or $from.
Frameworks are encouraged to subclass MailMessage and extend it's
functionality to suite their requirements - ie if they to synchronize
the header property with the recipients/from/subject properties they are
free to do so - there is no rule/standard saying they cannot.
$mail = new MailMessage(null, $subject, $body, $headers, $from,
$parameters);
$mail->setRecipients($recipients);
$mail->sendBatch();
Would be equivalent to:
// Calculate the message TO recipients
$to = implode(','.$recipients['to']);
// Update parameters with optional cc recipients
$cc = implode(',',$recipients['cc']);
$parameters .= (!empty($cc)) ? ' -c '.$cc : '';
// Update parameters with optional bcc recipients
$bcc = implode(',',$recipients['bcc']);
$parameters .= (!empty($cc)) ? ' -b '.$bcc : '';
mail($to, $subject, $body, $headers, $parameters);
Which incidentally, could be emulated using exec as follows:
/* A message consists of a header followed by an optional body.
Must be seperated by a CRLF
*/
$message = $headers ? $headers .CRLF . $body : $body;
// Mail command
$mailcommand = 'mail';
// Add subject
$mailcommand .= ' -s '.$subject;
// Add extra parameters
mailcommand .= '$parameters';
// Add to recipients
$mailcommand .= ' '.$to;
// Add the messsage
$mailcommand .= ' < '.escapeshellarg($message);
// Send the message
exec($mailcommand);
Sending mail is just passing a stream of bytes to a stream. That stream
could be an SMTP server, it can be an executable program, or it can be a
file.
Even that is not that easy, as Rasmus wrote.
Frameworks are encouraged to subclass MailMessage and extend it's
functionality to suite their requirements - ie if they to synchronize
the header property with the recipients/from/subject properties they are
free to do so - there is no rule/standard saying they cannot.
So frameworks should still contain their own mail classes working
differently? So this is neither solving the sending problem nor the
"it's different everywhere" problem.
That aside I repeat my typical statement: This is better done in
userland, i.e. by PHP-FIG. It should only be in core when there are
obvious benefits. Userland gives more contributors, simpler debugging,
less issues for evolving the implementation, ...
johannes
Sending mail is just passing a stream of bytes to a stream. That stream
could be an SMTP server, it can be an executable program, or it can be a
file.Even that is not that easy, as Rasmus wrote.
The only reason people think of it as complicated is because of
combining the different elements of e-mail:
Formatting an e-mail
Sending an e-mail
Relaying an e-mail
Delivering an e-mail
Verifying an e-mail
When you send an e-mail you are submitting it to a Mail Delivery Agent
for delivery. The MDA either accepts your submission or rejects it.
There are only 3 items of data are mandated by RFC: sender, recipient,
and message.
Of those, only sender and recipient have a specified format. The
message itself just has to be a string of some sort.
Frameworks are encouraged to subclass MailMessage and extend it's
functionality to suite their requirements - ie if they to synchronize
the header property with the recipients/from/subject properties they are
free to do so - there is no rule/standard saying they cannot.So frameworks should still contain their own mail classes working
differently? So this is neither solving the sending problem nor the
"it's different everywhere" problem.
Yes, frameworks should still contain their own mail classes - the issue
is not that they have them, but that PHP Applications[as opposed to
frameworks] such as Drupal, Wordpress, and Joomla require application
specific code to perform the simple task of sending e-mail.
At the moment the mail()
function is almost useless because it cannot be
assumed work - on windows it is likely to generate an error. On Linux
it depends on if sendmail/postfix/etc are configured. Make it a
handler with a sane default setting and then it can be trusted.
Take writing a simple "contact us" form processor. A theoretical
contact form could have fields for:
Category of Problem, $category
Summary of Problem, $summary
Full details of Problem, $details
Who it is to be sent to is pre-defined. Subject is pre-defined.
It only takes a few lines to send this e-mail:
$message = <<<EOT
Category: $category.\n
Summary: $summary.\n
Details: $$details.\n
EOT;
mail($to, $subject, $message);
I would guess that over half of all sending of e-mail can be
accomplished with these types of simple steps.
Instead, for some applications like drupal you have to use the
relatively simple:
drupal_mail($module, $key, $to, $language, $params = array(), $from =
NULL, $send = TRUE)
https://api.drupal.org/api/drupal/includes!mail.inc/function/drupal_mail/7
Joomla is more complex with a nice OO interface:
http://docs.joomla.org/Sending_email_from_extensions
$mailer = JFactory::getMailer();
$mailer->addRecipient($to);
$mailer->setSubject($subject);
$mailer->setBody($message);
$mailer->send();
By making it possible to register a mail handler, a Drupal website
merely has to call:
set_mail_handler(
function ( $to , $subject , $message ) {
$module = 'drupal';
$key = unique();
$language = language_default();
$params = array('body' => $message);
return drupal_mail($module, $key, $params);
return strtoupper($match[1]);
}
);
And all simple e-mail can now be generated and sent with the PHP mail
function, rather then requiring custom use.
A Joomla website would just call:
set_mail_handler(
function ( $to , $subject , $message ) {
$mailer = JFactory::getMailer();
$mailer->addRecipient($to);
$mailer->setSubject($subject);
$mailer->setBody($message);
return $mailer->send();
}
);
The basic concept here is to not require application developers to keep
changing how they write code based on the underlying application -
instead always use basic PHP function unless your needs go beyond that.
IE $myvar = _SESSION['somekey'] is the best way to retrieve session
data. The framework/application can use the SessionHandler
functionality to implement specific custom methods of dealing with
session data. The Session Handler can deal with sanitizing/filtering data.
$filedata = file_get_contents($filepath) is the best way to get the
contents of a file. Don't worry about if the file is local, from the
web, stored in some weird virtual file system, etc. The
Framework/Application can use Stream Handlers to deal with oddball
situations.
Sending an e-mail message is a basic requirement for PHP, as such mail()
should be the preferred method of doing so. If you have custom
formatting needs, then use a library to format the e-mail message.
Consider this list itself, it's using an archaic web interface[ezmlm]
because to implement an email list in /any/ language requires a stupid
amount of work.
When this list receives an e-mail message, it has to loop through a list
of all subscribers and: skip subscribers who are set to nomail, add it
to a periodic digest for subscribers who are set to digest, send it
directly to subscribers who want mail immediately.
Using registered e-mail handlers, in PHP this becomes a simple process:
foreach ($subscribers as $recipient)
{
mail($recipient, $subject, $message);
}
All the heavy lifting is offloaded to the Mail Handler, which is only
required to deal with one thing - delivering e-mail. A hypothetical
list handler would check the subscriber database for the recipient, if
the recipient is set to nomail it can return immediately, if the
recipient is in digest it can append queue it for a future digest
generator, and if the recipient is immediate invoke the default PHP mail
handler.
At the moment the
mail()
function is almost useless because it cannot be
assumed work - on windows it is likely to generate an error. On Linux
it depends on if sendmail/postfix/etc are configured. Make it a
handler with a sane default setting and then it can be trusted.
That's a pretty big leap there. In order combat spam, many places have
pretty tight restrictions on who and what can send mail. Outbound port
25 is often blocked, for example, and the only way to send an email is
through a local smarthost MTA relay. And how exactly you need to connect
to that relay will vary from one environment to another. I don't see how
we can provide a default stream handler that "can be trusted" since it
needs the same level of local configuration attention as the current
mail()
function.
-Rasmus
At the moment the
mail()
function is almost useless because it cannot be
assumed work - on windows it is likely to generate an error. On Linux
it depends on if sendmail/postfix/etc are configured. Make it a
handler with a sane default setting and then it can be trusted.That's a pretty big leap there. In order combat spam, many places have
pretty tight restrictions on who and what can send mail. Outbound port
25 is often blocked, for example, and the only way to send an email is
through a local smarthost MTA relay. And how exactly you need to connect
to that relay will vary from one environment to another. I don't see how
we can provide a default stream handler that "can be trusted" since it
needs the same level of local configuration attention as the current
mail()
function.
True, I am not interested in providing a "better" default stream handler.
What I'm interested in is that a developer can use mail()
in the same way
that they use fopen()
and be reasonably confident that the function will
work during execution.
There has been a long exodus of using native PHP functionality and instead
using methods exposed by frameworks to perform simple functions. While it
made sense in the past, it leads to this weird skill gap where all the
"learning PHP" tutorials aimed at beginners use built in functions and
global variables such as $_GET, $_POST, etc
And then "enterprise" applications have people use
someFrameworkClass::mail(), someFrameworkClass::get(), etc.
The silly thing is that these calls are almost exactly identical.
$mail = someFrameworkMailClass();
$mail->send($to, $subject, $message);
vs
mail($to, $subject, $message);
The primary difference being that the mail()
function will /always/
function while creating a mail object of a particular type only works for
that framework. So why not allow a framework to define it's own custom
"mail handler" and override the current one? In the same manner that you
can override a session handler or a stream handler.
My goal is not to help the framework developer, their already dealing with
the complexities. My goal is to help the developers who are going from
beginner to experienced programmers in that they don't have to learn a lot
of window dressing/new syntax to perform a simple function.
Mail does partially support this concept. it supports using the
sendmail_wrapper ini flag to designate an external program which handles
all the mail processing. I just feel that it should be possible to do this
internally as well - especially as it allows for more fine grained error
checking.
Hi!
Current e-mail handling in PHP is dreadful. Almost every framework
implements it's own email handling class in order to make sending e-mail
reliable, easy to configure, and to implement multiple mail schemes.That is probably because sending mail involves more than just passing a
stream of bytes to SMTP server. There's MIME, encodings, headers, etc.
which all need to be taken care of. There's email server configurations.
There's error handling.
Thanks for the detailed feedback Stas! After thinking over your
questions a bit, I realized that I combined multiple features into one
item - and while I would like to see all those features in PHP, the
primary issue is Mail Handlers.
IE when a PHP program invokes:
mail( $to, $subject, $message );
Instead of running the rough equivalent of exec('mail -s $subject $to <
$message') the PHP engine should invoke a registered callable in the
same manner as it currently handles errors, streams, and sessions.
The default mail handler is merely the current mail handler.
From a coding perspective, this means that there only needs to be a
single extra function added:
mixed set_mail_handler ( callable $mail_handler )
Providing a base MailHandler class along with some implementations would
be best done with a seperate RFC to avoid confusion. The same with
MailMessage.
The only additional item I might place in the RFC would be possibly
adding blackhole and maildrop callables as blackhole is extremely useful
for development purposes and maildrop is a feature I have long lamented
that no language seems to provide[when you have an app which generates
and sends over a million emails in the course of a single day maildrop
is the only way to maintain performance]
hi Gary,
Current e-mail handling in PHP is dreadful. Almost every framework
implements it's own email handling class in order to make sending e-mail
reliable, easy to configure, and to implement multiple mail schemes.This means for developers working on multiple frameworks, they can't just
call mail($recipient, $subject, $message) - they have to perform convoluted
checking to find out what framework they are using, and then use the
appropriate api.That was understandable in PHP v4 and in v5 - 5.2.
Today though it is a waste of time, PHP internally has implemented a smart,
extensible system for generalizing access to system oriented structures.
Handlers/Wrappers.By subclassing the appropriate handler class, a PHP application can
implement specific functionality to handle specific elements of Session and
Stream processing, without having to implement every one of them and without
requiring specialized PHP classes to be used directly.http://www.php.net/manual/en/function.session-set-save-handler.php
http://www.php.net/manual/en/function.stream-wrapper-register.php
http://www.php.net/manual/en/class.sessionhandler.php
http://www.php.net/manual/en/class.streamwrapper.phpMy proposal[which I am willing to work on coding] is to replace the current
mail()
function with one that will support handlers.Note: This is only to handle HALF of the issues that we deal with when
sending e-mail: sending the actual message. It does not attempt to address
creating/formatting e-mail messages except in a very general since. My
proposed class would be:
I do like the idea to simplify or making developers life easier while
working with emails.
However your last note summarizes pretty well the problem. No matter
what we do or provide, I am somehow convinced that applications,
frameworks or components developers will wrap something around it to
match more closely their needs or flows, like swift mailer for
Symfony. That's why I am not totally sure it is a good idea to
implement something high level when users already rely on php
compoenents (userland) heavily for this job. By the way, a similar
discussion happens for imap, both cases are very similar, there is no
performance gains to do it in the core and that's why I tend to think
to leave things as is (well, killing ext/imap for security reasons
f.e. :) instead of trying to create something that won't match users
need fully anyway.
If there were an immediate gain for our users (performance or
easiness), I would be all for it, but that's not the case, to my
understanding.
Cheers,
Pierre