PHP mail function
Uniform Server 3.5-Apollo. |
You may be using Uniform Sever either as a test environment or for learning PHP what you will quickly discover is PHP’s mail() function does not work. Strictly no true it does work however because of its limitations may be prevented from working, for instance a host may require authentication, which the function does not support. Or it could simply be a case of not having it set-up correctly.
Starting point
I am assuming you are not running your own mail server and do not wish to install one. All you want to do is send emails to or via (relay) your ISP mail server using PHP, either to test your own scripts or to test third party ones. This write-up looks at ways to get you up and running.
Test Scripts
I try to make UniCenter as practical as possible hence provide scripts and when things go wrong throw in a few error messages. This write-up is no exception, I will be using two basic scripts these are shown below.
- mail.html --- Basic page containing a mail form.
- mail.php --- Script that processes the above form information
mail.html | mail.php | |
---|---|---|
<html> <head><title>Mail sender</title></head> <body> <form action="mail.php" method="POST"> <b>Email</b><br> <input type="text" name="email" size=40> <p><b>Subject</b><br> <input type="text" name="subject" size=40> <p><b>Message</b><br> <textarea cols=40 rows=10 name="message"></textarea> <p><input type="submit" value=" Send "> </form> </body> </html> |
<html> <head><title>PHP Mail Sender</title></head> <body> <?php # Retrieve the form data $email = $_POST['email']; $subject = $_POST['subject']; $message = $_POST['message']; # Sends mail and report success or failure if (mail($email,$subject,$message)) { echo "<h4>Thank you for sending email</h4>"; } else { echo "<h4>Can't send email to $email</h4>"; } ?> </body> </html> | |
Above php code The above basic code works however it is inconvenient to use. Every time you run the form (mail.htlm) all text fields require an entry. I am lazy and it becomes a choir especially if you only want one field changing and to ignore the others. I have modified this basic script, it inserts default values for empty form text boxes. This new version is the one downloadable using the above link. The modified script is shows below. |
A better mail.php script
A better mail.php test script, adds defaults values to empty text fields. After saving this script one minor change is required to personalise it for your own use.
Open the file mail.php and change it as follows:
|
|
|
Running the test Scripts
Start UniServer and type the following into your browser address bar: http://localhost/mail.html
There is no need to enter any data into the text boxes just click on Send with luck you will receive this error message:
error message |
---|
Warning: mail() [function.mail]: Failed to connect to mailserver at "localhost" port 25, verify your "SMTP" and "smtp_port" setting in php.ini or use ini_set() in W:\www\mail.php on line 24 Can't send email to fred123@xip.com Note: should display your real email address |
This error message was expected it highlights the problem we are trying to resolve. Our script produced the last line as for the warning that was produced by PHP.
PHP was looking for a mail server to use, can’t find one so gives up. The error message is very informative its telling us where the problem is and in what file .
php.ini
Open file php.ini located in folder *\Uniform Server\udrive\usr\local\php search for this section [mail function] (starts at around line 612)
php.ini section [mail function] | Comments |
---|---|
[mail function] ; For Win32 only. ;For Unix only. You may supply arguments as well (default: ;"sendmail -t -i"). ; Force the addition of the specified parameters to be passed as extra parameters |
These are the defaults settings, you can see PHP is looking for an SMTP server on the localhost machine and will use port 25 to communicate with it. There is no reason why this SMTP server should be local. In theory you can use anyone’s SMTP server for replaying your mail to the appropriate recipient. (It really is a shame but spammers have killed off this open-relay mechanism) ISP’s now disable open relaying and check you are a valid customer before allowing your email to be relayed through their SMPT servers. There are two methods they use for validation:
|
Solution 1
Since we are not running our own SMTP server and because of validation we are restricted to using our ISP’s SMTP server. To use this server all that is required is to point PHP to it. To do this you need to known the name of this server, a quick way to find it is to check what settings you have in Outlook Express (or the mail client you are using)
For Outlook Express use:
- On the top menu Click on Tools and select accounts
- This brings up a new form, select the Mail Tab and click on the default account name, Click on properties
- A new menu is opened, Click on the Servers Tab
- The text box named Outgoing mails (SMTP) contains the name of the server for example smtp.xip.com
Alternatively check your ISP’s web site and look for "how to set up an email client" the SMPT server name will found there.
php.ini section [mail function] | Comments |
---|---|
[mail function] ; For Win32 only. ;For Unix only. You may supply arguments as well (default: ;"sendmail -t -i"). ; Force the addition of the specified parameters to be passed as extra parameters |
SMTP: Replace localhost with your ISP's SMTP server name in this example I am using smtp.xip.com. smtp_port: Leave the port set to 25 sendmail_from: When a recipient reads their email this email address is displayed in their “from box”. If you expect a reply you should use a real email address. It does not have to be one provided by your ISP. Replace me@localhost.com with a real email address in this example I am using fred123@xip.com |
Test Solution 1
Test1:
Start UniServer and type the following into your browser address bar: http://localhost/mail.html
Again there is no need to enter any data into the text boxes just click on Send you will receive this message:
- A page is displayed with the following message:
- Thank you for sending email
Login to your mail account and check you received the message.
Test 2:
To check your ISP relays to other SMTP servers. Send an email to a friend or to another account you own, make sure your ISP is not hosting these accounts.
Run the test page http://localhost/mail.html this time you will need to fill in the text boxes. Confirm that the emails are received, that completes the tests.
Problems
In the real world things never run that smoothly something always throws a spanner in the works. If the above fails use this checklist to see it either resolves the problem or points to where the problem is:
- You need to be connected to the Internet (via your ISP) before running your PHP program.
- If your host requires authentication for outgoing mail you cannot use the PHP mail function it does not support it.
- Your service provider may be using an alternative port and not 25 (unlikely) Note: Check what you use in Outlook Express to confirm 2) and 3)
- Make sure your firewall or antivirus program is not blocking php.exe Internet access (port25).
I think that covers most causes you would be surprised 1) is the prime candidate especially when testing.
Summary
The above solution is quick to implement and allows you to test email scripts and any third party scripts that use PHP’s mail function.
One real drawback with this solution it cannot be used if your service provider requires SMTP authentication.
I noticed on the forum, to over come this problem Olajide recommends using fake sendmail for Windows. For completeness I cover this on the next page solution 2.
Ric |