PHP HelpPHP Help

Online Community that helps beginners learn PHP,
and webmasters solve PHP coding problems

since 1999

How To Generate and Send Mail From PHP

Talking to Sendmail

Of course, php let's you call the system mail program directly. You might want to do this in order to use a special feature only available in a certain mail program. Another reason to talk directly to sendmail is to create a From: header or other custom header in a more readable manner.

Talking to the mail program is like writing to a file. (Perl programmers will be familiar with this technique). Instead of opening a file, the (popen() function specifies a program to pipe (communicate in a standard Unix way) your message to. This makes a connection to the mail program. The puts() function is used to "print" the message headers and message body out to the mail program, connected through the file descriptor already opened with the popen() function. Because you may want to use a different mail program than sendmail, it's a good idea to store this path in variable. You can store the recipient address in a variable to make it easy to change. Here is a simple script to send a message by talking directly to the sendmail program.


popen("/usr/sbin/sendmail -t","w");
fputs($fd"To: myaddress@domain.tld");
fputs($fd"From: Me");
fputs($fd"Subject: Test message from my web site");
fputs($fd"X-Mailer: PHP3");
fputs($fd"Testing. ");


The popen() function opens a pipe to the mail program. To open the pipe, you must give the function the name of the program to pipe to and set the type of communication to make, the "w" standing for "write," which tells the open function to pipe the information from php to sendmail. If it said "r" it would open the pipe in the opposite direction, sending information to php from the application. The fputs() functions then write out each line of the message to sendmail. This function requires we give it a file descriptor and the string we want to output. The file descriptor, which we obtained when the file (in Unix, devices masquerade as files) was opened tells where to send the message. The message itself is contained in the string. When we are done, the pipe is closed with the pclose() function.

Note:  Specify the -t option when working directly with sendmail to reduce the chance of abuse. From the sendmail documentation: The '-t' option to 'sendmail' instructs 'sendmail' to parse the headers of the message, and use all the recipient-type headers (i.e. 'To:', 'Cc:' and 'Bcc:') to construct the list of envelope recipients. This has the advantage of simplifying the 'sendmail' command line, but makes it impossible to specify recipients other than those listed in the headers.

One reason to access the mail program directly is to set the envelope email address. If you operate a mailing hosted at another provider, you may find that when you send mail using the simple mail() function that the messages are rejected for not having a matching envelope address. This happens because the address you are sending from and the envelope address do not match. By directly accessing sendmail, we can alleviate this problem.

Use the -f switch to tell sendmail to set the envelope address:


Full code example:


// Configuration
$announce_subject "Message From Our Web Site";
$announce_from_email "";
$announce_from_name "Our Site";
$announce_to_email "";
$body "Announcement. Our site has a special offer today. Please visit. Thank you.";
$MP "/usr/sbin/sendmail -t";
$spec_envelope 1;

// Access Sendmail
  // Conditionally match envelope address
$MP .= " -f $announce_from_email";
$fd popen($MP,"w");
fputs($fd"To: $announce_to_email");
fputs($fd"From: $announce_from_name <$announce_from_email>");
fputs($fd"Subject: $announce_subject");
fputs($fd"X-Mailer: PHP3");


Sendmail Security

When calling the system mail program we must be careful of what characters we are sending to it. Becuase we are opening a Unix pipe, it is possible for malicious users to enter shell meta characters into form inputs that later are passed to sendmail. The results can be disastrous.

When creating a form handling script that eventually hands off user entered data to the mail program, you must screen user input carefully. Treat all user input as if it were hostile. Start by removing shell meta characters from any input used by sendmail, like the To: and From: inputs or even teh Subject: input of a feedback form.

One character that is important to remove is the period. Because the period is used for Unix shell commands such as to represent generic directory names.

While reading a discussion of Perl programming, an approach was suggested that has enough merit that it changed the way I look at user input. I want to share it here. The idea is to use a system of inclusion rather than exclusion when sanitizing input data. Instead of saying "give me the string that results after taking out these specific characters", I say "give me the string that results after taking out any characters that are not these specific characters". It seems safer and easier to identify what I know I want rather than attempt to identify every possible bad scenerio that could happen.

It was suggested that to process user input for saftey, use code like this:

$data =~ s/[^A-Za-z0-9_]//gs;

It removes all characters that are not letters, numbers or underscores.

You may use the Perl compatible regular expression feature (see function preg_replace()) of PHP to implement this.

Pages:  1   2   3   4   5Next:  Sending Mail from a Form »

Copyright © 2017