PHP language provides the mail() function. But it requires properly configured mail server on the local machine. Developers often don't have the necessary infrastructure at their disposal. Sometimes sending emails from a PHP script becomes a frustrating experience.
The PHP manual page states that the mail() function is not suitable for larger volumes of email in a loop as it opens and closes an SMTP socket for each mail. The mail() function on Linux depends on local installation of sendmail. To successfully send an email using the mail() function you have to have a properly configured MTA on the host. During the development phase of your project the necessary email infrastructure may not be available to you. Due to these infrastructure problems the emails you send using the mail() function may not be delivered. Many receiving email servers may treat your emails as SPAM.
To solve the email delivery problem, you use a properly configured email server. From your PHP script you connect to this properly configured email server via SMTP and send emails.
Most likely, your company has already provided you an email account with POP and SMTP access. If you have subscribed to a web and email hosting service, you can use the mail server provided by your web hosting provider. If you already don't have an email account with SMTP access, take advantage of free email service providers like Gmail. Gmail provides free POP, IMAP and SMTP access to all Gmail accounts.
Once you have an email account you will require the following information
Once you obtain the above details from your email server administrator or provider you are ready to start writing the script.
How do we connect to the remote email server from our PHP script? We could open a socket connection to the email server and communicate with it from our PHP script. People have written libraries in PHP to communicate with email servers. Why not take advantage of these libraries? Using an open source third party library like the Zend Framework saves lot of development time and energy.
In this example, we use the Zend_Mail component of the Zend Framework. Zend Framework is a PHP5 framework with large number of independent components. In a previous blog post we discussed the reasons to use Zend Framework. In this example, we do not use the MVC components of Zend Framework. If you are new to frameworks it is a good way to start using the Zend Framework. Familiarize yourself with individual components of the Zend Framework one at a time. Learning a framework takes some time. With this approach you can scale the learning curve smoothly.
To install the Zend Framework, you download the tarball (or zip file) from framework.zend.com and copy it to the library directory of your project. Let's install it step by step.
Step 1: Do you have a 'library' directory in your project? If not create one now. You can put all the libraries - third party and your own in the library directory.
Step 2: Download the Zend Framework.
Visit http://framework.zend.com/download/latest. At the bottom of the page find the download link on the same row as "Zend Framework 1.9.3 patch 1 Minimal" and click it. At the time of writing 1.9.3PL is the latest release. Save the archive in your downloads directory.
Step 3: Extract the archive and copy the Zend directory to your project's library directory.
tar -zxvf ZendFramework-1.9.3PL1-minimal.tar.gz cp -a ZendFramework-1.9.3PL1-minimal/library/Zend/ /path/to/your/project/library/
After copying your project directory structure should look like
projectdir/library/Zend/
Create the file sendemail.php. We will put our PHP code in sendemail.php.
Let us first set up the include_path.
My directory structure is as follows
web/mail/sendemail.php library/Zend/
From within sendemail.php I have to traverse to ../../library to access the directory Zend.
<?php
/**
* @file sendemail.php
*/
$currentFilePath = dirname(realpath(__FILE__));
set_include_path($currentFilePath . '/../../library/' . PATH_SEPARATOR . get_include_path());
?>Include the Zend/Mail.php file in our sendemail.php script.
<?php
require_once 'Zend/Mail.php';
?>Aggregate the server access details. In this example we use a Gmail account to send emails.
<?php
$smtpServer = 'smtp.gmail.com';
$username = 'you@gmail.com';
$password = 'yoursecretgmailpassword';
?>Configure Zend_Mail to use our SMTP credentials.
<?php
$config = array('ssl' => 'tls',
'auth' => 'login',
'username' => $username,
'password' => $password);
$transport = new Zend_Mail_Transport_Smtp($smtpServer, $config);
?>Instantiate the Zend_Mail object.
<?php
$mail = new Zend_Mail();
?>Set the from email address, to email address, subject and body text.
<?php
$mail->setFrom('sender@example.com', 'Some Sender');
$mail->addTo('recipient@example.com', 'Some Recipient');
$mail->setSubject('Test Subject');
$mail->setBodyText('This is the text of the mail.');
?>Finally, send the email.
<?php
$mail->send($transport);
?>At this point our sendemail.php looks like:
<?php
/**
* @file sendemail.php
*/
/**
* Send email from PHP script
* Use SMTP
* Use Zend_Mail component of Zend Framework
*/
$currentFilePath = dirname(realpath(__FILE__));
set_include_path($currentFilePath . '/../../library/' . PATH_SEPARATOR . get_include_path());
require_once 'Zend/Mail.php';
$smtpServer = 'smtp.gmail.com';
$username = 'you@gmail.com';
$password = 'yoursecretgmailpassword';
$config = array('ssl' => 'tls',
'auth' => 'login',
'username' => $username,
'password' => $password);
$transport = new Zend_Mail_Transport_Smtp($smtpServer, $config);
$mail = new Zend_Mail();
$mail->setFrom('sender@example.com', 'Some Sender');
$mail->addTo('recipient@example.com', 'Some Recipient');
$mail->setSubject('Test Subject');
$mail->setBodyText('This is the text of the mail.');
$mail->send($transport);
?>If you are using an email server other than Gmail, make sure you have the correct values in the $config array.
Congratulations. You just used Zend_Mail component of the Zend Framework to send emails from your PHP scipt via remote SMTP server.
Setting up the include_path in every PHP script is a boring task and a maintenance overhead. To avoid setting up the include_path in every PHP script, you can use a bootstrap file. Within the bootstrap.php file set up your include paths, database, constants and other configuration. Include this bootstrap.php file in your scripts.
Also, writing require_once statements is a tedious task. If you use autoload, you don't have to require the particular Zend framework component file in your scripts. The Zend Framework offers an autoloading solution. You might want to use it in your bootstrap.php.
An example bootstrap.php looks like this
<?php
$bootstrapFilePath = dirname(realpath(__FILE__));
define('APPLICATION_PATH', $bootstrapFilePath);
set_include_path($bootstrapFilePath . '/../library/' . PATH_SEPARATOR . get_include_path());
require_once 'Zend/Loader/Autoloader.php';
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->setFallbackAutoloader(true);
?>After implementing the bootstrap, the code from sendmailImproved.php is pasted below:
<?php
require_once '../bootstrap.php';
$smtpServer = 'smtp.gmail.com';
$username = 'yourusername@gmail.com';
$password = 'yoursecretpassword';
$config = array('ssl' => 'tls',
'auth' => 'login',
'username' => $username,
'password' => $password);
$transport = new Zend_Mail_Transport_Smtp($smtpServer, $config);
$mail = new Zend_Mail();
$mail->setFrom('napolean.bonaparte@gmail.com', 'Some Sender');
$mail->addTo('sudheer@sudheer.net', 'Some Recipient');
$mail->setSubject('Test Subject');
$mail->setBodyText('This is the text of the mail.');
$mail->send($transport);
?>Browse or download the code from the Code Album github git repository.
Let me know your experience using Zend_Mail to send emails through SMTP from your PHP script.
Reference:
SMTP - Wikipedia article
Gmail SMTP access details
Zend Framework Zend_Mail documentation
include Zend/Mail/Transport/Smtp.php
add below one line statement
================================
require_once 'Zend/Mail/Transport/Smtp.php';
================================
before class Zend_Mail_Transport_Smtp is been initialized.
so, after adding above statement script looks like this.
---------------------------------------------------------------------
<?php
/**
* @file sendemail.php
*/
/**
* Send email from PHP script
* Use SMTP
* Use Zend_Mail component of Zend Framework
*/
$currentFilePath = dirname(realpath(__FILE__));
set_include_path($currentFilePath . '/../../library/' . PATH_SEPARATOR . get_include_path());
require_once 'Zend/Mail.php';
require_once 'Zend/Mail/Transport/Smtp.php';
$smtpServer = 'smtp.gmail.com';
$username = 'you@gmail.com';
$password = 'yoursecretgmailpassword';
$config = array('ssl' => 'tls',
'auth' => 'login',
'username' => $username,
'password' => $password);
$transport = new Zend_Mail_Transport_Smtp($smtpServer, $config);
$mail = new Zend_Mail();
$mail->setFrom('sender@example.com', 'Some Sender');
$mail->addTo('recipient@example.com', 'Some Recipient');
$mail->setSubject('Test Subject');
$mail->setBodyText('This is the text of the mail.');
$mail->send($transport);
?>
Thanks
This script working fine.
thanks Sudheer .
Slighty off topic but...
First thanks for sharing,
I had no problem to make this script work fine.
I've just wanted to mention the excellent library SwiftMailer :
"Swift Mailer integrates into any web app written in PHP 5, offering a flexible and elegant object-oriented approach to sending emails with a multitude of features."
swiftmailer dot org
Fred
It gets many warning and notice and unable to send any mail
I wrote the exact same above problem mentioned in this site and running from the wamp server after configuring the minimal framework but that is unable to send however it gets the below warning and notice listing in the browser fdrom where I am running the above php code
Warning: stream_socket_enable_crypto() [streams.crypto]: this stream does not support SSL/crypto in C:\wamp\library\Zend\Mail\Protocol\Smtp.php on line 206
Notice: fwrite() [function.fwrite]: send of 36 bytes failed with errno=10054 An existing connection was forcibly closed by the remote host. in C:\wamp\library\Zend\Mail\Protocol\Abstract.php on line 301
Notice: fwrite() [function.fwrite]: send of 6 bytes failed with errno=10054 An existing connection was forcibly closed by the remote host. in C:\wamp\library\Zend\Mail\Protocol\Abstract.php on line 301
Notice: fwrite() [function.fwrite]: send of 42 bytes failed with errno=10054 An existing connection was forcibly closed by the remote host. in C:\wamp\library\Zend\Mail\Protocol\Abstract.php on line 301
Notice: fwrite() [function.fwrite]: send of 47 bytes failed with errno=10054 An existing connection was forcibly closed by the remote host. in C:\wamp\library\Zend\Mail\Protocol\Abstract.php on line 301
Notice: fwrite() [function.fwrite]: send of 23 bytes failed with errno=10054 An existing connection was forcibly closed by the remote host. in C:\wamp\library\Zend\Mail\Protocol\Abstract.php on line 301
Notice: fwrite() [function.fwrite]: send of 39 bytes failed with errno=10054 An existing connection was forcibly closed by the remote host. in C:\wamp\library\Zend\Mail\Protocol\Abstract.php on line 301
Notice: fwrite() [function.fwrite]: send of 46 bytes failed with errno=10054 An existing connection was forcibly closed by the remote host. in C:\wamp\library\Zend\Mail\Protocol\Abstract.php on line 301
Notice: fwrite() [function.fwrite]: send of 45 bytes failed with errno=10054 An existing connection was forcibly closed by the remote host. in C:\wamp\library\Zend\Mail\Protocol\Abstract.php on line 301
Notice: fwrite() [function.fwrite]: send of 29 bytes failed with errno=10054 An existing connection was forcibly closed by the remote host. in C:\wamp\library\Zend\Mail\Protocol\Abstract.php on line 301
Notice: fwrite() [function.fwrite]: send of 19 bytes failed with errno=10054 An existing connection was forcibly closed by the remote host. in C:\wamp\library\Zend\Mail\Protocol\Abstract.php on line 301
Notice: fwrite() [function.fwrite]: send of 2 bytes failed with errno=10054 An existing connection was forcibly closed by the remote host. in C:\wamp\library\Zend\Mail\Protocol\Abstract.php on line 301
Notice: fwrite() [function.fwrite]: send of 31 bytes failed with errno=10054 An existing connection was forcibly closed by the remote host. in C:\wamp\library\Zend\Mail\Protocol\Abstract.php on line 301
Notice: fwrite() [function.fwrite]: send of 3 bytes failed with errno=10054 An existing connection was forcibly closed by the remote host. in C:\wamp\library\Zend\Mail\Protocol\Abstract.php on line 301
Notice: fwrite() [function.fwrite]: send of 6 bytes failed with errno=10054 An existing connection was forcibly closed by the remote host. in C:\wamp\library\Zend\Mail\Protocol\Abstract.php on line 301
Interesting problem
Are you trying to connect to Gmail or another SMTP server?
Can you try connecting to another SMTP server and see what happens?
using script but not working
hi
I am using this script with post name - include Zend/Mail/Transport/Smtp.php.
But it shows 5.7.6 Unknown authentication method error. And not sending mails.
I check my smtp settings and username/password. All r fine.
Pl help
Hiral
correct values for auth and ssl in your config.
Make sure you are using the correct values for auth and ssl in your config.
<?phparray('ssl' => 'tls',
'auth' => 'login',
'username' => $username,
'password' => $password);
?>
If your SMTP server does not support SSL, remove the
'ssl'=>'tls'
line.
minor doubt about zend mail
hi to all,
for me that code working fine no problem .. but i want to know some more information about 'ssl' => 'tls', what its mean.. can u help me plsss
Re: minor doubt about zend mail
Some SMTP servers operate only on TLS transport for security reasons. Zend_Mail allows you to set the TLS transport. You can read more about TLS on Wikipedia.
HI when i run this it gives
HI when i run this it gives me this error. please help
Warning: date() [function.date]: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'Europe/London' for 'BST/1.0/DST' instead in /home/www/ZendPrivate/library/Zend/Mail.php on line 760
Fatal error: Uncaught exception 'Zend_Mail_Protocol_Exception' with message 'Permission denied' in /home/www/ZendPrivate/library/Zend/Mail/Protocol/Abstract.php:234 Stack trace: #0 /home/www/ZendPrivate/library/Zend/Mail/Protocol/Smtp.php(167): Zend_Mail_Protocol_Abstract->_connect('tcp://smtp.gmai...') #1 /home/www/ZendPrivate/library/Zend/Mail/Transport/Smtp.php(195): Zend_Mail_Protocol_Smtp->connect() #2 /home/www/ZendPrivate/library/Zend/Mail/Transport/Abstract.php(348): Zend_Mail_Transport_Smtp->_sendMail() #3 /home/www/ZendPrivate/library/Zend/Mail.php(973): Zend_Mail_Transport_Abstract->send(Object(Zend_Mail)) #4 /home/www/123shift.ca/emtest.php(42): Zend_Mail->send(Object(Zend_Mail_Transport_Smtp)) #5 {main} thrown in /home/www/ZendPrivate/library/Zend/Mail/Protocol/Abstract.php on line 234
set date
Like the error message suggests, set the date early in your application. In a typical Zend Framework application, this is set in the application.ini file:
Error in zend mail
It worked in localhost, but when i try to upload on host, it failed
$host = 'smtp.gmail.com'; $config = array('auth'=>'login', 'ssl'=>'tls', 'port'=> 465, 'username'=>'uitbookshop@gmail.com', 'password'=>'xxx'); $transport = new Zend_Mail_Transport_Smtp($host,$config); $emailAddress = $this->_arrParam["email"]; $fullName = $this->_arrParam["full_name"]; $mail = new Zend_Mail(); $mail->setFrom('uitbookshop@gmail.com','UIT Bookshop'); $mail->addTo($emailAddress, $fullName); $mail->setSubject('Ordered book sucessfully'); $mail->setBodyHtml($body,'utf-8'); $mail->send($transport);Here is the error:
Fatal error: Uncaught exception 'Zend_Controller_Dispatcher_Exception' with message 'Invalid controller specified (error)' in /home/vol3/php0h.com/p0_9866140/htdocs/library/Zend/Controller/Dispatcher/Standard.php:248 Stack trace: #0 /home/vol3/php0h.com/p0_9866140/htdocs/library/Zend/Controller/Front.php(954): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http)) #1 /home/vol3/php0h.com/p0_9866140/htdocs/library/Zend/Application/Bootstrap/Bootstrap.php(97): Zend_Controller_Front->dispatch() #2 /home/vol3/php0h.com/p0_9866140/htdocs/library/Zend/Application.php(366): Zend_Application_Bootstrap_Bootstrap->run() #3 /home/vol3/php0h.com/p0_9866140/htdocs/index.php(9): Zend_Application->run() #4 {main} thrown in /home/vol3/php0h.com/p0_9866140/htdocs/library/Zend/Controller/Dispatcher/Standard.php on line 248Post new comment