I need to test some script using PHP's mail. I'd like to be able to finally get this working locally. I am using MAMP. Is there a way to do this without installing any third party software?
I've done some searching on this but haven't found anything appealing.
Thanks
Are you specifically trying to test the sending of mail, or are you testing the rest of the code?
In the case of the former, you need to configure:
SMTP = smtp.example.com
smtp_port = 25
sendmail_from = me#example.com
in your php.ini file (check where it is with phpinfo()), substituting in appropriate values.
To test the code other than the process of sending mail, then I'd recommend creating 2 include files:
<?php
// for live usage/mail send testing
function ori_mail()
{
return call_user_func_array('mail',func_get_args());
}
and for testing other code
function ori_mail()
{
file_put_contents('debug_mail_scripts.txt'
,date('r') . ':' . var_export(func_get_args(), true)
, FILE_APPEND);
}
And include the relevant one to your testing.
Note that testing integration with the SMTP server, and testing deliverbility of your code is rather complex but should be done independently of testing your PHP.
C.
You might want to consider the Swift Mailer library
http://swiftmailer.org/
It makes doing email from PHP code much more reliable. You could even point your mailer script to a real SMTP service. This can eliminate a a lot of issues you would run into when moving from local to to production environments.
Using swift mailer is as simple as using a single include at the top of your PHP script and writing a code block to send a simple message. And it is fully object oriented.
Few months ago I had a similar problem whilst developing on my local machine an application which involved sending automating email notifications. I have lost quite some time installing Sendmail on OSX and eventually I could not get it working right..
My approach was to use the PEAR Mail as a temporary replacement for php's native mail function. Basically you can define a function called send-mail (see code below) and, once you deploy your app on a server, you can possibly replace the calls to that function with calls to mail().
<?php
require_once 'Mail.php';
function send_mail($recipient,$subject,$body){
$host = "yourmailserver.net";
$username = "you#yourmailserver.net";
$password = "password";
$port = 25;
$headers = array ('From' => "Your agent <noreply#yoursite.net>",
'To' => $recipient,
'Subject' => $subject
);
$smtp = Mail::factory(
'smtp',
array ('host' => $host,
'auth' => true,
'port' => $port,
'username' => $username,
'password' => $password)
);
$smtp->send($recipient, $headers, $body);
}
?>
what i do is i use the phpmailer class (warning: horrible website !) and specify a real smtp server on which i have an account. So i don't use mail() but use smtp. In this way, it does not matter whether i'm on my local server or on the real server. But you do need a working smtp access to that smtp mail server. Best would be to actually use the production mail server (the one that will be used by your application when it goes live). In this manner, you won't have last minute surprises when you discover that the mailserver messes up the reply-to field and little things like that.
You could use your gmail account and send your test emails via gmail's SMTP server.
You can use the phpmailer class (http://phpmailer.worxware.com/) to do this. There is a basic gmail example in the examples/ folder when you download this class.
I think the best solution is write all messages to file. So you just need to make own sendmail.
add to httpd.conf file this strings:
php_admin_value sendmail_path
"/Applications/MAMP/somefolder/mysendmail.sh"
In the file mysendmail.sh add following:
#!/bin/bash
while read line
do
echo "$line" >> ../mail_log.txt
done
echo "------------- next mail ----------------" >> ../mail_log.txt
exit 0
Do not forget to set privilegies: chmod 755 mysendmail.sh
Related
when sending newsletters through a SMTP server using PEAR's Mail package, is there any way to specify some kind of "connection reuse" so that the PHP script won't have to create a new socket to the SMTP server for each individual mail?
That is of course without putting the adress of each recipient in only one e-mail, so that the indvidual recipient's won't see each others adresses.
Or doesn't SMTP allow for this?
Well I think the best solution is to put each destinee in black carbon. This guarantees that who receives the mail does not see other mail addresses and is a better solution than sending a mail for each destinee
This is feasible with php pear Mail package.
PEAR Mail seems to be a hopeless case, but Zend's framework has addressed the issue and keeps the SMTP socket open for as long as the script runs (and the object exists): http://framework.zend.com/manual/en/zend.mail.multiple-emails.html
What you should do is set the 'persist' param. And then only use the factory method once - then you ensure that it is the same socket that is used.
something like this:
static $mail;
if (!is_object($mail)) {
$mail = Mail::factory($options['mail_method'], $params);
}
$res = $mail->send($to, $mime_headers, $body);
If you call the mail::factory every time then a new socket will be created. In the above way you only create one socket.
I am using php5.
Are there some settings or a simple php.ini directive that would redirect all the emails to a folder?
I want on the development machine to have all the emails generated by the system not sent to the actual receiver but put in a folder.
Thanks.
I used to have some code like this (kinda pseudocode):
define ('DEBUG', true);
function send_email($to, $subject, $body) {
if (DEBUG) {
file_put_contents('some_folder/' . $to . date('dmY-His') . '.html', $body);
}else{
// Actual code to send email
}
}
But i agree with others, it's easier/better to setup an development email account to receive those emails.
I don't think you will be able to do something like this. Mails are sent by a mail server so it must be your mail server that writes them to a file instead of sending them.
Why not simply send it to a special development email?
Sample:
define('DEBUG', true);
if(DEBUG)
{
// Override recipient
$recipient = 'development#domain.tld';
}
// Send mail...
No settings that I'm aware of in PHP itself. However, if you're using Postfix on your development server, here's a recipe I cooked up to redirect all outbound email to a single (local) address:
/etc/postfix/main.cf: (add this to the existing file, don't replace everything)
virtual_alias_maps = regexp:/etc/postfix/virtual
/etc/postfix/virtual:
/.*/ duskwuff#localhost
You can configure your mail server to accept SMTP messages as normal, but make it unable to forward them onto another mail server. If your mail server supports it, make it redirect all messages to a postmaster account, or any other address of your choice.
This means that PHP will behave as normal, everything will appear to work straight away with the message, but it just won't go to the 'intended' recipient.
It also means that you can inspect headers (pretty much as they would normally appear), to support debugging.
There are many ways to do this. Basically, you need to define the sendmail command in your php.ini to point to a program or script which will save the mail locally.
One solution is this:
Catch emails with php script
Another is this:
Mail catcher
xampp , and codeigniter , i want to send emails from my localhost .
in ubuntu i can create an Email server very easily by
$ sudo apt-get install sendmail
and update the configuration in application/frontend/config/email.php
$config['useragent'] = "CodeIgniter";
$config['mailpath'] = "/usr/bin/sendmail"; // or "/usr/sbin/sendmail"
$config['protocol'] = "mail";
$config['smtp_host'] = "localhost";
$config['smtp_user'] = "";
$config['smtp_pass'] = "";
$config['smtp_port'] = "25";
i want to setup sendmail in windows , how can i do this ?? please help . search a lot , but could not find a working solution .
It is possible to set up a mail server on Windows. You'll need a separate product for that, see e.g. here and here. XAMPP comes with a mail server bundled.
However, using a local mail server is rarely wise. Mails coming from a dynamic IP address tend to get swallowed by spam filters, as anybody can do this from any internet connection. It's better to use the SMTP server that is serving the domain name you want to use as the sender domain.
My favourite solution for that is SwiftMailer. It's a replacement for the mail() command and comes with many options. Here is an example on how to make it work with GMail.
SwiftMailer doesn't work with the mail() command though: You'll have to change your PHP code to make this work.
I remember using BLAT, a command line mailer for windows. Dead simple install and usage, providing that you have an SMTP account avalaible. I would recommend this over setting up your own server.
It does not however replace mail() directly, nor is a mail server per se, so YMMV.
Use a service like authsmtp.com or gridsend.com. I find that these work well for tracking outbound email activity, managing spam boxes, plus you don't have to worry about a different sending environment on your local machine than your production environment.
You can also try minirelay. Quite easy to use and works fine.
http://www.blat.net/miniRelay/
When I execute my email script via browser a timeout fatal error is returned (unless I drastically increase the execution time, then it will run ok, not the solution I'm looking for). The email is sent tho, but it takes forever (5 min. average) to arrive (at my inbox)!
(Considering that via command line it works perfectly I think that SMTP at php.ini is certainly well configured.)
So this is the code executed by browser request:
<?php
mail('amatos#example.com', 'test subject', 'test body', 'From: Andre Matos <amatos#example.com>');
?>
and when I run this same (is it really the same? I'm starting to doubt myself) code via command line:
php -r "mail('amatos#example.com', 'test subject', 'test body', 'From: Andre Matos <amatos#example.com>');"
it works perfectly! The script runs, it stop and the email arrives instantly (2/3 seconds).
So, what can cause this difference and how to fix it? Any ideas?
Thanks in advance.
[edit] some extra info:
- the machine is windows
- the server is localhost
- php.ini is the same for both the browser and the cli instance
[edit2]
Thank you all for trying to guess which was the problem. I placed the question hopping that someone had the problem before and knew of something specific. Given nothing specific showed up and none of the suggestions really worked, I've decided to accept the one that allowed me to reach more conclusions about the problem... +1 For all your helpful knowledge/thoughts (/guesses) :-)
I've hypothesised some couses, but I used to linux and on windows I can olny guess:
php_cli and mod_php are 2 different binaries, mod_php can be slightly damaged
php_cli and mod_php use 2 different users, the network profile of apache user can be the problem (dns, firewall, proxy...)
your php script is on "problematic" location or contains some problematic character, but your cli script is by param, try to execute same script: php -f z:\path\to\php\mail.php
Given this note from http://php.net/manual/en/function.mail.php, it seems very likely that the issue is with the MTA and not PHP directly:
The Windows implementation of mail() differs in many ways from the Unix implementation. First, it doesn't use a local binary for composing messages but only operates on direct sockets which means a MTA is needed listening on a network socket (which can either on the localhost or a remote machine).
Perhaps it has something to do with the way the MTA is responding to the particular user, or user-specific firewall rules for outgoing mail connections on your machine. Can you run the command-line as the web server user rather than yourself? If so, does that re-create the problem from the command-line?
How about having the web server execute the command-line PHP rather than the parsed PHP file? (For example, perhaps you can run a batch script via CGI.) Does that solve the problem?
(Sorry that these are more guesses than definite answers.)
Just to be clear: The php-instance used by the script is the same as the one used by the command line code?
Many web hosts use smtp-relay, which will gather a bunch of emails and send them all at once, so it won't be strange behaviour if your mail is late. However, the long execution time is not normal.
Before you send your mail in the script make sure to print out the ini_get() of the variables SMTP, smtp_port, and sendmail_from and be certain that these are working values. PHP running on Windows does not have the benefit of sending mail out via Sendmail, and whatever the PHP devs cobbled together for it is sketchy at best.
I always like to test mail via telnet so I can see if the server is giving an error that is not being passed back properly by the client:
c:\> telnet smtp.domain.com 25
220 smtp.domain.com ESMTP Postfix
helo mailtest
250 smtp.domain.com
mail from: user#local.com
250 2.1.0 Ok
rcpt to: user#remote.com
250 2.1.5 Ok
data
354 End data with <CR><LF>.<CR><LF>
from: user#local.com
to: user#remote.com
subject: test mail
this is a test message
.
250 2.0.0 Ok: queued as 42AD8364FE0E
quit
221 2.0.0 Bye
Try to set username and password to "From" mail id. so it can authenticate and sends the mail quickly.
Have you tried PHP mailer?
In my observation its sends mails within seconds. Below example will give you a quick look how to use php mailer class.
include "class.phpmailer.php";
$msg="Hello! This is a test..."
$mail=new PHPMailer();
$email="someone#friend.com"; //person who receives your mail
$mail->IsSMTP();
$mail->Host = "localhost";
$mail->SMTPAuth = true;
$mail->Username = "admin#example.com"; //your mail id
$mail->Password = "sdfsd441"; //password for your mail id
$mail->SetFrom('admin#example.com', 'admin'); //from address
$mail->AddAddress($email);
$mail->Subject ="Test Mail";
$mail->Body = $msg;
$mail->IsHTML(true);
$mail->MsgHTML($msg);
$mail->Send();
EDIT :
In PHP manual they stated like this,
The Windows implementation of mail() differs in many ways from the Unix implementation. First, it doesn't use a local binary for composing messages but only operates on direct sockets which means a MTA is needed listening on a network socket (which can either on the localhost or a remote machine).
so that may cause delay? I think this link might help you.
My first guess would be that the browser version of your mailing has already a context or connections ready for the sending.
On the contrary, the direct (php -r) execution has to load the mailing context.
To confirm this idea, you can make a loop for sending 10 mails and check wether the mails after the first are much quicker.
I'm developing a zend framework application that includes a simple email function. The development version is running on my computer, which is running Ubuntu. The production version is going to run on a production server.
When trying to send a test email to myself, I get an exception with the message: "Unable to send mail". I don't know if this is an environment issue, or a code issue. I'm not using a transport so I think it is defaulting to Zend_Mail_Transport_Sendmail. Here's my code:
public function sendtestAction()
{
$mail = new Zend_Mail();
$mail->setFrom('test#aol.com', 'Test Email');
$mail->addTo('my#email.com', 'My Name');
$mail->setSubject('This is just a test.');
$mail->setBodyText('This is only a test.');
$mail->send();
}
Update: I tried a different approach by setting the SMTP transport to use localhost:
transport = new Zend_Mail_Transport_Smtp('localhost');
Zend_Mail::setDefaultTransport($transport);
I got a different error this time: "Connection refused" Not sure what that means. Maybe I haven't set something up yet?
Update: I guess I didn't have an SMTP server installed/setup. This tutorial made it really easy for me to get an SMTP server up an running. Now both of the code samples above work.
It sounds like you need to configure an MTA, or find one that you can send to. Ubuntu desktop should set one up by default, probably either exim or postfix, but if you haven't configured it, it will unlikely to be running.
You don't want to set the default transport if you wish to use sendmail (it is the default) and SMTP is different.
That it doesn't send the emails suggests that sendmail or the MTA on your server is not installed/not setup correctly.