Mail 函数

目录

add a note add a note

User Contributed Notes 9 notes

up
21
webmaster at weethet dot nl
17 years ago
As mentioned earlier, for Windows users there is a fake sendmail option. A bit more detailed description how to do this is:

If you have a test server in use running Windows and some kind of WAMP combo (XXAMP, WAMP Server, etc) then you'll notice that the PHP sendmail command (mail()) does not work. Windows simply does not provide the sendmail statement ...

There is a simple trick to get this to work though;

1) Download (or use the attached file) sendmail.zip from http://glob.com.au/sendmail/

2) Unzip this in a folder on your c: drive (preferably use a simple path, for example c:\wamp\sendmail -- long filenames could cause problems)

3) Edit your PHP.INI file (note: WAMP users should access their php.ini file from the WAMP menu). Go to the [mail function] section and modify it as such:

[mail function]
; For Win32 only.
;SMTP =

; For Win32 only.
;sendmail_from =

; For Unix only.  You may supply arguments as well (default: "sendmail -t -i").
sendmail_path = "C:\wamp\sendmail\sendmail.exe -t"

; Force the addition of the specified parameters to be passed as extra parameters
; to the sendmail binary. These parameters will always replace the value of
; the 5th parameter to mail(), even in safe mode.
;mail.force_extra_paramaters =

.. and save the changes.

4) Open the sendmail.ini and modify the settings to:

[sendmail]

; you must change mail.mydomain.com to your smtp server,
; or to IIS's "pickup" directory.  (generally C:\Inetpub\mailroot\Pickup)
; emails delivered via IIS's pickup directory cause sendmail to
; run quicker, but you won't get error messages back to the calling
; application.

smtp_server=mail.yourdomain.com

; smtp port (normally 25)

smtp_port=25

; the default domain for this server will be read from the registry
; this will be appended to email addresses when one isn't provided
; if you want to override the value in the registry, uncomment and modify

default_domain=yourdomain.com

; log smtp errors to error.log (defaults to same directory as sendmail.exe)
; uncomment to enable logging
; error_logfile=sendmail_error.log

; create debug log as debug.log (defaults to same directory as sendmail.exe)
; uncomment to enable debugging
; debug_logfile=sendmail_debug.log

; if your smtp server requires authentication, modify the following two lines

;auth_username=
;auth_password=

; if your smtp server uses pop3 before smtp authentication, modify the
; following three lines

pop3_server=mail.yourdomain.com
pop3_username=you@yourdomain.com
pop3_password=mysecretpassword

; to force the sender to always be the following email address, uncomment and
; populate with a valid email address.  this will only affect the "MAIL FROM"
; command, it won't modify the "From: " header of the message content

force_sender=you@yourdomain.com

; sendmail will use your hostname and your default_domain in the ehlo/helo
; smtp greeting.  you can manually set the ehlo/helo name if required

hostname=

The optional error and debug logging is recommended when trying this the first time, so you have a clue what goes wrong in case it doesn't work.
Force_sender is also optional, but recommended to avoid confusion on the server end.
Obviously mail.yourdomain.com, you@yourdomain.com, and mysecretpassword should be the relevant info for your SMTP server.
Now restart the WAMP services (mainly Apache so PHP re-reads it's config).

Now you're good to go and use the PHP mail() statement as if you're a Unix user ...
up
14
jcwebb at dicoe dot com
18 years ago
Corrupted Attachments ???
I spent many hours with corrupted attachments (of all types of files) - The answer: a blank line is needed after $msg.=$file \r\n \r\n [incredible but true].
Heres some useful code for sending an attachment, and display html OR text depending on the users email-reader.

i work with many different systems, so...

<?php # Is the OS Windows or Mac or Linux
if (strtoupper(substr(PHP_OS,0,3)=='WIN')) {
 
$eol="\r\n";
} elseif (
strtoupper(substr(PHP_OS,0,3)=='MAC')) {
 
$eol="\r";
} else {
 
$eol="\n";
}
?>

<?php
# File for Attachment
$f_name="../../letters/".$letter;    // use relative path OR ELSE big headaches. $letter is my file for attaching.
$handle=fopen($f_name, 'rb');
$f_contents=fread($handle, filesize($f_name));
$f_contents=chunk_split(base64_encode($f_contents));    //Encode The Data For Transition using base64_encode();
$f_type=filetype($f_name);
fclose($handle);
# To Email Address
$emailaddress="user@example.com";
# Message Subject
$emailsubject="Heres An Email with a PDF".date("Y/m/d H:i:s");
# Message Body
ob_start();
  require(
"emailbody.php");     // i made a simple & pretty page for showing in the email
$body=ob_get_contents(); ob_end_clean();

# Common Headers
$headers .= 'From: Jonny <jon@example.com>'.$eol;
$headers .= 'Reply-To: Jonny <jon@example.com>'.$eol;
$headers .= 'Return-Path: Jonny <jon@example.com>'.$eol;     // these two to set reply address
$headers .= "Message-ID:<".$now." TheSystem@".$_SERVER['SERVER_NAME'].">".$eol;
$headers .= "X-Mailer: PHP v".phpversion().$eol;           // These two to help avoid spam-filters
# Boundry for marking the split & Multitype Headers
$mime_boundary=md5(time());
$headers .= 'MIME-Version: 1.0'.$eol;
$headers .= "Content-Type: multipart/related; boundary=\"".$mime_boundary."\"".$eol;
$msg = "";

# Attachment
$msg .= "--".$mime_boundary.$eol;
$msg .= "Content-Type: application/pdf; name=\"".$letter."\"".$eol;   // sometimes i have to send MS Word, use 'msword' instead of 'pdf'
$msg .= "Content-Transfer-Encoding: base64".$eol;
$msg .= "Content-Disposition: attachment; filename=\"".$letter."\"".$eol.$eol; // !! This line needs TWO end of lines !! IMPORTANT !!
$msg .= $f_contents.$eol.$eol;
# Setup for text OR html
$msg .= "Content-Type: multipart/alternative".$eol;

# Text Version
$msg .= "--".$mime_boundary.$eol;
$msg .= "Content-Type: text/plain; charset=iso-8859-1".$eol;
$msg .= "Content-Transfer-Encoding: 8bit".$eol;
$msg .= "This is a multi-part message in MIME format.".$eol;
$msg .= "If you are reading this, please update your email-reading-software.".$eol;
$msg .= "+ + Text Only Email from Genius Jon + +".$eol.$eol;

# HTML Version
$msg .= "--".$mime_boundary.$eol;
$msg .= "Content-Type: text/html; charset=iso-8859-1".$eol;
$msg .= "Content-Transfer-Encoding: 8bit".$eol;
$msg .= $body.$eol.$eol;

# Finished
$msg .= "--".$mime_boundary."--".$eol.$eol;   // finish with two eol's for better security. see Injection.

# SEND THE EMAIL
ini_set(sendmail_from,'from@example.com');  // the INI lines are to force the From Address to be used !
 
mail($emailaddress, $emailsubject, $msg, $headers);
ini_restore(sendmail_from);
?>


I hope this helps.
Jon Webb [Madrid&London]

[EDITOR thiago NOTE: Code has a fix from o.straesser AT gmx DOT de]
up
0
Anonymous
9 months ago
I have limited space and don't want to deal with Apache-MySQL-PHP; I don't need the security nor the extra functionality. PHP has its own simple webserver now! I only need to test, on Windows, web forms for a website to be uploaded to a commercial host running Linux. Not everyone is developing an in-house mail application.

I thought pointing smtp dir to "fake sendmail" meant to use a directory as a "black hole", which is not the case, of course!You need either a) a "sendmail" or alternative program installed locally, or b) on Windows, an MTA (mail transfer agent) connecting to a real server where you have an account.

*Most* simple programs ("fake sendmail", "fake sendmail with TLS" + one more) weren't maintained for *years* and don't work. ("SmtpStub" says it's listening and so does my firewall, which is always a high random one, even though 25 is its default config, or I change it. However, PHP warning says no one's listening.)

I tried "MailHog" *last* because online tutorials configure it with blogs + imply "mhsendmail" is required. Turns out this *is a simple program usable by itself*! It's a *no-install Windows executable* that stores mail in memory or to disk, and has a GUI web interface to view, read + delete email live or from disk. Its CLI options *work*, including changing the port! (By default, it listens on 1025 for email and 8025 for HTTP requests by which it serves the webmail GUI.)

Using this with PHP's "mail()" function is easy as pie:
1) Download and save MailHog wherever you want, preferably a short path.
2) Create a folder for mail storage if you want to store mail.
3) I use MailHog default ports, but tested others worked via options. Edit your "php.ini" (MailHog automatically uses "user@example.com" for "to", so you don't need to configure in PHP):
SMTP = localhost
smtp_port = 1025
sendmail_from = test@example.com
4) Start PHP with its own webserver, with all requests interpreted relative to your website directory (using *forward slashes*), per the manual:
php -S localhost:8000 D:/sites/MySite
5) Change to the directory where you saved MailHog:
D:\SomeDir
6) Start MailHog (assume you saved the executable as "mailhog.exe") with options to bind to localhost, save mails to MAIL folder :
start mailhog -hostname localhost -storage maildir -maildir-path D:\MAIL

PHP will run in the current CLI, MailHog opens its own CLI. Now you can browse your site with "localhost:8000" or directly to your form like "localhost:8000/mail.html". Fill out a mail and send it. Use "localhost:8025" for the webmail (let JavaScript run on localhost); read and delete as desired. If *not* storing to disk, emails in memory are lost when you stop MailHog's server (close its CLI or press "Ctrl+C"). Stop PHP's webserver with "Ctrl+C" "y" 'Enter'.

If you save your binaries with version info, etc, just make a *shortcut* with *NO* ".ink" extension, named "mailhog", which can be run the same way. Better, you can open its Properties and put options in the "Target" box. (If you must quote the path to the executable because it has spaces, do *NOT* make options part of the quote, put them outside after a space!)

If all goes well, create a Windows batch script to run things and put your options there (or keep them in the shortcut, assuming you use it). You could even stick batch scripts in each site directory with different settings and servers.

My "runservers.bat" changes to the directory where MailHog is, starts MailHog via the shortcut (which has options), and starts PHP's web server:
cd /d D:\SomeDir
start mailhog
php -S localhost:8000 -t D:/sites/MySite

I can run this script (stored in D:) like:
cd /d D:
runservers.bat

NOTE, use "-storage memory" and *no* -maildir-path if you *don't* want mail saved to disk (these settings are *defaults* anyway):
start maildir -hostname localhost -storage memory
NOTE, to start PHP with links relative to current directory instead of specifying, "cd" to it and *don't* use -t D:/sites/MySite:
php -S localhost:8000

*THE MOST SIMPLE USAGE*
start maildir
php -S localhost:8000
up
-1
aweather88 at gmail dot com
18 years ago
I spent hours searching the web trying to figure out why I was getting a "WARNING: mail(): SMTP server response: 501 5.5.4 Invalid Address " every time I was using the mail() function on my server (Win2K3,IIS 6.0,PHP4.4.1).  I knew everything was setup properly for SMTP based on other non IIS 6.0 configurations.

Turns out that the IIS 6.0 SMTP service does not like formatting of the "From" field in mail headers.  For instance:
<?PHP
  
//This line DOES NOT send  mail message correctly
  
$headers .= "From: \"".$fromname."\" <".$fromaddress.">\n";
?>
However this works:
<?PHP
  
//This line sends mail message correctly
  
$headers .= "From: \"".$fromaddress."\"\n";
?>

The fix is in Microsoft Article ID 291828 ( http://support.microsoft.com/?id=291828 ).  Even though the "bug" workaround is for IIS 6.0 on Exchange 2003 communicating with a UNIX server, THIS SOLVES THE PROBLEM.  Just skip down to the last section for Exchange 2003 and follow the instructions to modify the IIS 6 MetaBase with the MetaBase Explorer found in the IIS 6 Resource Kit.
up
-2
anselm at netuxo dot co dot uk
18 years ago
In case you don't want to, or can't, configure sendmail for your server, a good alternative is esmtp - it's an smtp mailer with minimum configuration that can be used as a sendmail drop-in : http://esmtp.sourceforge.net/
up
-3
josh at sdfahrenheit dot com
20 years ago
For anyone having problems with attached files coming through garbled, make sure you have magic_quotes_runtime set to Off in your php.ini - it adds funky escape chars to your attached data and garbles the attachment.

This was giving me all kinds of grief.
up
-3
lawcd at ntlworld dot com
18 years ago
For those of you with the exim, if its not sending mail with the -i option and you cant easily change this, you might want to check out the imap_mail() function which works almost exactly the same and doesnt use exim, most web hosts provide this. If you using your own server then php needs to be compiled with imap libraries etc.

See http://php.net/manual/en/function.imap-mail.php
up
-15
martin dot felis at gmx dot de
18 years ago
If using a chroot environment and you don't want to have a full mailer in it, mini-sendmail (can be found at http://www.acme.com/software/mini_sendmail/) is very useful. It is just a small binary that sends mails over your local mta over port 25.

Martin
up
-32
derernst at gmx dot ch
18 years ago
Suggestion for methods checking form inputs for e-mail injection attempts.

Any inputs expected from single-line text fields can just be refused if they contain a newline character. The second function tries to minimize matches on non-evil inputs by matching suspect strings only if preceded by a newline character. (Anyway, if this is considered to be safe, it will of course do it for single-line inputs, too.)

<?php

/**
* Check single-line inputs:
* Returns false if text contains newline character 
*/
function has_no_newlines($text)
{
    return
preg_match("/(%0A|%0D|\\n+|\\r+)/i", $text) == 0;
}

/**
* Check multi-line inputs:
* Returns false if text contains newline followed by
* email-header specific string
*/
function has_no_emailheaders($text)
{
    return
preg_match("/(%0A|%0D|\\n+|\\r+)(content-type:|to:|cc:|bcc:)/i", $text) == 0;
}

?>
To Top