123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603 |
- Sending Messages
- ================
-
- Quick Reference for Sending a Message
- -------------------------------------
-
- Sending a message is very straightforward. You create a Transport, use it to
- create the Mailer, then you use the Mailer to send the message.
-
- To send a Message:
-
- * Create a Transport from one of the provided Transports --
- ``Swift_SmtpTransport``, ``Swift_SendmailTransport``,
- ``Swift_MailTransport`` or one of the aggregate Transports.
-
- * Create an instance of the ``Swift_Mailer`` class, using the Transport as
- it's constructor parameter.
-
- * Create a Message.
-
- * Send the message via the ``send()`` method on the Mailer object.
-
- .. caution::
-
- The ``Swift_SmtpTransport`` and ``Swift_SendmailTransport`` transports use
- ``proc_*`` PHP functions, which might not be available on your PHP
- installation. You can easily check if that the case by running the
- following PHP script: ``<?php echo function_exists('proc_open') ? "Yep,
- that will work" : "Sorry, that won't work"; ``
-
- When using ``send()`` the message will be sent just like it would
- be sent if you used your mail client. An integer is returned which includes
- the number of successful recipients. If none of the recipients could be sent
- to then zero will be returned, which equates to a boolean
- ``false``. If you set two ``To:`` recipients and
- three ``Bcc:`` recipients in the message and all of the
- recipients are delivered to successfully then the value 5 will be returned.
-
- .. code-block:: php
-
- require_once 'lib/swift_required.php';
-
- //Create the Transport
- $transport = Swift_SmtpTransport::newInstance('smtp.example.org', 25)
- ->setUsername('your username')
- ->setPassword('your password')
- ;
-
- /*
- You could alternatively use a different transport such as Sendmail or Mail:
-
- //Sendmail
- $transport = Swift_SendmailTransport::newInstance('/usr/sbin/sendmail -bs');
-
- //Mail
- $transport = Swift_MailTransport::newInstance();
- */
-
- //Create the Mailer using your created Transport
- $mailer = Swift_Mailer::newInstance($transport);
-
- //Create a message
- $message = Swift_Message::newInstance('Wonderful Subject')
- ->setFrom(array('john@doe.com' => 'John Doe'))
- ->setTo(array('receiver@domain.org', 'other@domain.org' => 'A name'))
- ->setBody('Here is the message itself')
- ;
-
- //Send the message
- $result = $mailer->send($message);
-
- Transport Types
- ~~~~~~~~~~~~~~~
-
- A Transport is the component which actually does the sending. You need to
- provide a Transport object to the Mailer class and there are several possible
- options.
-
- Typically you will not need to know how a Transport works under-the-surface,
- you will only need to know how to create an instance of one, and which one to
- use for your environment.
-
- The SMTP Transport
- ..................
-
- The SMTP Transport sends messages over the (standardized) Simple Message Transfer
- Protocol. It can deal with encryption and authentication.
-
- The SMTP Transport, ``Swift_SmtpTransport`` is without doubt the most commonly
- used Transport because it will work on 99% of web servers (I just made that
- number up, but you get the idea). All the server needs is the ability to
- connect to a remote (or even local) SMTP server on the correct port number
- (usually 25).
-
- SMTP servers often require users to authenticate with a username and password
- before any mail can be sent to other domains. This is easily achieved using
- Swift Mailer with the SMTP Transport.
-
- SMTP is a protocol -- in other words it's a "way" of communicating a job
- to be done (i.e. sending a message). The SMTP protocol is the fundamental
- basis on which messages are delivered all over the internet 7 days a week, 365
- days a year. For this reason it's the most "direct" method of sending messages
- you can use and it's the one that will give you the most power and feedback
- (such as delivery failures) when using Swift Mailer.
-
- Because SMTP is generally run as a remote service (i.e. you connect to it over
- the network/internet) it's extremely portable from server-to-server. You can
- easily store the SMTP server address and port number in a configuration file
- within your application and adjust the settings accordingly if the code is
- moved or if the SMTP server is changed.
-
- Some SMTP servers -- Google for example -- use encryption for
- security reasons. Swift Mailer supports using both SSL and TLS encryption
- settings.
-
-
- Using the SMTP Transport
- ^^^^^^^^^^^^^^^^^^^^^^^^
-
- The SMTP Transport is easy to use. Most configuration options can be set with
- the constructor.
-
- To use the SMTP Transport you need to know which SMTP server your code needs
- to connect to. Ask your web host if you're not sure. Lots of people ask me who
- to connect to -- I really can't answer that since it's a setting that's
- extremely specific to your hosting environment.
-
- To use the SMTP Transport:
-
- * Call ``Swift_SmtpTransport::newInstance()`` with the SMTP server name and
- optionally with a port number (defaults to 25).
-
- * Use the returned object to create the Mailer.
-
- A connection to the SMTP server will be established upon the first call to
- ``send()``.
-
- .. code-block:: php
-
- require_once 'lib/swift_required.php';
-
- //Create the Transport
- $transport = Swift_SmtpTransport::newInstance('smtp.example.org', 25);
-
- //Create the Mailer using your created Transport
- $mailer = Swift_Mailer::newInstance($transport);
-
- /*
- It's also possible to use multiple method calls
-
- $transport = Swift_SmtpTransport::newInstance()
- ->setHost('smtp.example.org')
- ->setPort(25)
- ;
- */
-
- Encrypted SMTP
- ^^^^^^^^^^^^^^
-
- You can use SSL or TLS encryption with the SMTP Transport by specifying it as
- a parameter or with a method call.
-
- To use encryption with the SMTP Transport:
-
- * Pass the encryption setting as a third parameter to
- ``Swift_SmtpTransport::newInstance()``; or
-
- * Call the ``setEncryption()`` method on the Transport.
-
- A connection to the SMTP server will be established upon the first call to
- ``send()``. The connection will be initiated with the correct encryption
- settings.
-
- .. note::
-
- For SSL or TLS encryption to work your PHP installation must have
- appropriate OpenSSL transports wrappers. You can check if "tls" and/or
- "ssl" are present in your PHP installation by using the PHP function
- ``stream_get_transports()``
-
- .. code-block:: php
-
- require_once 'lib/swift_required.php';
-
- //Create the Transport
- $transport = Swift_SmtpTransport::newInstance('smtp.example.org', 587, 'ssl');
-
- //Create the Mailer using your created Transport
- $mailer = Swift_Mailer::newInstance($transport);
-
- /*
- It's also possible to use multiple method calls
-
- $transport = Swift_SmtpTransport::newInstance()
- ->setHost('smtp.example.org')
- ->setPort(587)
- ->setEncryption('ssl')
- ;
- */
-
- SMTP with a Username and Password
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- Some servers require authentication. You can provide a username and password
- with ``setUsername()`` and ``setPassword()``.
-
- To use a username and password with the SMTP Transport:
-
- * Create the Transport with ``Swift_SmtpTransport::newInstance()``.
-
- * Call the ``setUsername()`` and ``setPassword()`` methods on the Transport.
-
- Your username and password will be used to authenticate upon first connect
- when ``send()`` are first used on the Mailer.
-
- If authentication fails, an Exception of type
- ``Swift_TransportException`` will be thrown.
-
- .. note::
-
- If you need to know early whether or not authentication has failed and an
- Exception is going to be thrown, call the ``start()`` method on the
- created Transport.
-
- .. code-block:: php
-
- require_once 'lib/swift_required.php';
-
- //Create the Transport the call setUsername() and setPassword()
- $transport = Swift_SmtpTransport::newInstance('smtp.example.org', 25)
- ->setUsername('username')
- ->setPassword('password')
- ;
-
- //Create the Mailer using your created Transport
- $mailer = Swift_Mailer::newInstance($transport);
-
- The Sendmail Transport
- ......................
-
- The Sendmail Transport sends messages by communicating with a locally
- installed MTA -- such as ``sendmail``.
-
- The Sendmail Transport, ``Swift_SendmailTransport`` does not
- directly connect to any remote services. It is designed for Linux servers that
- have ``sendmail`` installed. The Transport starts a local
- ``sendmail`` process and sends messages to it. Usually the
- ``sendmail`` process will respond quickly as it spools your
- messages to disk before sending them.
-
- The Transport is named the Sendmail Transport for historical reasons
- (``sendmail`` was the "standard" UNIX tool for sending e-mail
- for years). It will send messages using other transfer agents such as Exim or
- Postfix despite its name, provided they have the relevant sendmail wrappers so
- that they can be started with the correct command-line flags.
-
- It's a common misconception that because the Sendmail Transport returns a
- result very quickly it must therefore deliver messages to recipients quickly
- -- this is not true. It's not slow by any means, but it's certainly not
- faster than SMTP when it comes to getting messages to the intended recipients.
- This is because sendmail itself sends the messages over SMTP once they have
- been quickly spooled to disk.
-
- The Sendmail Transport has the potential to be just as smart of the SMTP
- Transport when it comes to notifying Swift Mailer about which recipients were
- rejected, but in reality the majority of locally installed
- ``sendmail`` instances are not configured well enough to
- provide any useful feedback. As such Swift Mailer may report successful
- deliveries where they did in fact fail before they even left your server.
-
- You can run the Sendmail Transport in two different modes specified by command
- line flags:
-
- * "``-bs``" runs in SMTP mode so theoretically it will act like the SMTP
- Transport
-
- * "``-t``" runs in piped mode with no feedback, but theoretically faster,
- though not advised
-
- You can think of the Sendmail Transport as a sort of asynchronous SMTP
- Transport -- though if you have problems with delivery failures you
- should try using the SMTP Transport instead. Swift Mailer isn't doing the work
- here, it's simply passing the work to somebody else (i.e.
- ``sendmail``).
-
- Using the Sendmail Transport
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- To use the Sendmail Transport you simply need to call
- ``Swift_SendmailTransport::newInstance()`` with the command as a
- parameter.
-
- To use the Sendmail Transport you need to know where
- ``sendmail`` or another MTA exists on the server. Swift Mailer
- uses a default value of ``/usr/sbin/sendmail``, which should
- work on most systems.
-
- You specify the entire command as a parameter (i.e. including the command line
- flags). Swift Mailer supports operational modes of "``-bs``"
- (default) and "``-t``".
-
- .. note::
-
- If you run sendmail in "``-t``" mode you will get no feedback as to
- whether or not sending has succeeded. Use "``-bs``" unless you have a
- reason not to.
-
- To use the Sendmail Transport:
-
- * Call ``Swift_SendmailTransport::newInstance()`` with the command, including
- the correct command line flags. The default is to use ``/usr/sbin/sendmail
- -bs`` if this is not specified.
-
- * Use the returned object to create the Mailer.
-
- A sendmail process will be started upon the first call to ``send()``. If the
- process cannot be started successfully an Exception of type
- ``Swift_TransportException`` will be thrown.
-
- .. code-block:: php
-
- require_once 'lib/swift_required.php';
-
- //Create the Transport
- $transport = Swift_SendmailTransport::newInstance('/usr/sbin/exim -bs');
-
- //Create the Mailer using your created Transport
- $mailer = Swift_Mailer::newInstance($transport);
-
- The Mail Transport
- ..................
-
- The Mail Transport sends messages by delegating to PHP's internal
- ``mail()`` function.
-
- In my experience -- and others' -- the ``mail()``
- function is not particularly predictable, or helpful.
-
- Quite notably, the ``mail()`` function behaves entirely
- differently between Linux and Windows servers. On linux it uses
- ``sendmail``, but on Windows it uses SMTP.
-
- In order for the ``mail()`` function to even work at all
- ``php.ini`` needs to be configured correctly, specifying the
- location of sendmail or of an SMTP server.
-
- The problem with ``mail()`` is that it "tries" to simplify things
- to the point that it actually makes things more complex due to poor interface
- design. The developers of Swift Mailer have gone to a lot of effort to make
- the Mail Transport work with a reasonable degree of consistency.
-
- Serious drawbacks when using this Transport are:
-
- * Unpredictable message headers
-
- * Lack of feedback regarding delivery failures
-
- * Lack of support for several plugins that require real-time delivery feedback
-
- It's a last resort, and we say that with a passion!
-
- Using the Mail Transport
- ^^^^^^^^^^^^^^^^^^^^^^^^
-
- To use the Mail Transport you simply need to call
- ``Swift_MailTransport::newInstance()``. It's unlikely you'll need
- to configure the Transport.
-
- To use the Mail Transport:
-
- * Call ``Swift_MailTransport::newInstance()``.
-
- * Use the returned object to create the Mailer.
-
- Messages will be sent using the ``mail()`` function.
-
- .. note::
-
- The ``mail()`` function can take a ``$additional_parameters`` parameter.
- Swift Mailer sets this to "``-f%s``" by default, where the "%s" is
- substituted with the address of the sender (via a ``sprintf()``) at send
- time. You may override this default by passing an argument to
- ``newInstance()``.
-
- .. code-block:: php
-
- require_once 'lib/swift_required.php';
-
- //Create the Transport
- $transport = Swift_MailTransport::newInstance();
-
- //Create the Mailer using your created Transport
- $mailer = Swift_Mailer::newInstance($transport);
-
- Available Methods for Sending Messages
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- The Mailer class offers two methods for sending Messages -- ``send()``.
- Each behaves in a slightly different way.
-
- When a message is sent in Swift Mailer, the Mailer class communicates with
- whichever Transport class you have chosen to use.
-
- Each recipient in the message should either be accepted or rejected by the
- Transport. For example, if the domain name on the email address is not
- reachable the SMTP Transport may reject the address because it cannot process
- it. Whichever method you use -- ``send()`` -- Swift Mailer will return
- an integer indicating the number of accepted recipients.
-
- .. note::
-
- It's possible to find out which recipients were rejected -- we'll
- cover that later in this chapter.
-
- Using the ``send()`` Method
- ...........................
-
- The ``send()`` method of the ``Swift_Mailer`` class
- sends a message using exactly the same logic as your Desktop mail client would
- use. Just pass it a Message and get a result.
-
- To send a Message with ``send()``:
-
- * Create a Transport from one of the provided Transports --
- ``Swift_SmtpTransport``, ``Swift_SendmailTransport``,
- ``Swift_MailTransport`` or one of the aggregate Transports.
-
- * Create an instance of the ``Swift_Mailer`` class, using the Transport as
- it's constructor parameter.
-
- * Create a Message.
-
- * Send the message via the ``send()`` method on the Mailer object.
-
- The message will be sent just like it would be sent if you used your mail
- client. An integer is returned which includes the number of successful
- recipients. If none of the recipients could be sent to then zero will be
- returned, which equates to a boolean ``false``. If you set two
- ``To:`` recipients and three ``Bcc:`` recipients in
- the message and all of the recipients are delivered to successfully then the
- value 5 will be returned.
-
- .. code-block:: php
-
- require_once 'lib/swift_required.php';
-
- //Create the Transport
- $transport = Swift_SmtpTransport::newInstance('localhost', 25);
-
- //Create the Mailer using your created Transport
- $mailer = Swift_Mailer::newInstance($transport);
-
- //Create a message
- $message = Swift_Message::newInstance('Wonderful Subject')
- ->setFrom(array('john@doe.com' => 'John Doe'))
- ->setTo(array('receiver@domain.org', 'other@domain.org' => 'A name'))
- ->setBody('Here is the message itself')
- ;
-
- //Send the message
- $numSent = $mailer->send($message);
-
- printf("Sent %d messages\n", $numSent);
-
- /* Note that often that only the boolean equivalent of the
- return value is of concern (zero indicates FALSE)
-
- if ($mailer->send($message))
- {
- echo "Sent\n";
- }
- else
- {
- echo "Failed\n";
- }
-
- */
-
- Sending Emails in Batch
- .......................
-
- If you want to send a separate message to each recipient so that only their
- own address shows up in the ``To:`` field, follow the following recipe:
-
- * Create a Transport from one of the provided Transports --
- ``Swift_SmtpTransport``, ``Swift_SendmailTransport``,
- ``Swift_MailTransport`` or one of the aggregate Transports.
-
- * Create an instance of the ``Swift_Mailer`` class, using the Transport as
- it's constructor parameter.
-
- * Create a Message.
-
- * Iterate over the recipients and send message via the ``send()`` method on
- the Mailer object.
-
- Each recipient of the messages receives a different copy with only their own
- email address on the ``To:`` field.
-
- .. note::
-
- In the following example, two emails are sent. One to each of
- ``receiver@domain.org`` and ``other@domain.org``. These recipients will
- not be aware of each other.
-
- .. code-block:: php
-
- require_once 'lib/swift_required.php';
-
- //Create the Transport
- $transport = Swift_SmtpTransport::newInstance('localhost', 25);
-
- //Create the Mailer using your created Transport
- $mailer = Swift_Mailer::newInstance($transport);
-
- //Create a message
- $message = Swift_Message::newInstance('Wonderful Subject')
- ->setFrom(array('john@doe.com' => 'John Doe'))
- ->setBody('Here is the message itself')
- ;
-
- //Send the message
- $failedRecipients = array();
- $numSent = 0;
- $to = array('receiver@domain.org', 'other@domain.org' => 'A name');
-
- foreach ($to as $address => $name)
- {
- if (is_int($address)) {
- $message->setTo($name);
- } else {
- $message->setTo(array($address => $name));
- }
-
- $numSent += $mailer->send($message, $failedRecipients);
- }
-
- printf("Sent %d messages\n", $numSent);
-
- Finding out Rejected Addresses
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- It's possible to get a list of addresses that were rejected by the Transport
- by using a by-reference parameter to ``send()``.
-
- As Swift Mailer attempts to send the message to each address given to it, if a
- recipient is rejected it will be added to the array. You can pass an existing
- array, otherwise one will be created by-reference.
-
- Collecting the list of recipients that were rejected can be useful in
- circumstances where you need to "prune" a mailing list for example when some
- addresses cannot be delivered to.
-
- Getting Failures By-reference
- .............................
-
- Collecting delivery failures by-reference with the ``send()`` method is as
- simple as passing a variable name to the method call.
-
- To get failed recipients by-reference:
-
- * Pass a by-reference variable name to the ``send()`` method of the Mailer
- class.
-
- If the Transport rejects any of the recipients, the culprit addresses will be
- added to the array provided by-reference.
-
- .. note::
-
- If the variable name does not yet exist, it will be initialized as an
- empty array and then failures will be added to that array. If the variable
- already exists it will be type-cast to an array and failures will be added
- to it.
-
- .. code-block:: php
-
- $mailer = Swift_Mailer::newInstance( ... );
-
- $message = Swift_Message::newInstance( ... )
- ->setFrom( ... )
- ->setTo(array(
- 'receiver@bad-domain.org' => 'Receiver Name',
- 'other@domain.org' => 'A name',
- 'other-receiver@bad-domain.org' => 'Other Name'
- ))
- ->setBody( ... )
- ;
-
- //Pass a variable name to the send() method
- if (!$mailer->send($message, $failures))
- {
- echo "Failures:";
- print_r($failures);
- }
-
- /*
- Failures:
- Array (
- 0 => receiver@bad-domain.org,
- 1 => other-receiver@bad-domain.org
- )
- */
|