PDA

View Full Version : anyone here use phpmailer?



gnossos
03-11-2004, 10:17 AM
if so,
is there anything specific in phpmailer that needs to be configured to get it up and running. I looked at the class, and it looked like if you left things like, host, username, etc., etc,. blank then they would be left as defaults (which looked right to my eyes). Just want to check it out as I'm trying to identify why I can't get it working (e.g., it won't send any mail).
Thanks!

schsym
12-13-2007, 08:58 AM
I saw that you were a user of phpmailer and can't get my script up and running to send an attachment with an email. Would you (or anyone that is familiar with phpmailer) be kind enough to look at this script and let me know what is wrong here? (or be so kind as to copy me with something that worked?) I have an html page with a form on it and a submit button (btw, PHP and MySQL book by Ullman greatly helps out a beginner like me!). The three fields on the page are name, company and email which a visitor would fill out and submit. Upon submit, this php file would handle the form. All I get is blank screen with the php form address.

<?php # Script 3.13 variation from PHPand MySQL VQuickPro Guide
$page_title = 'formv01';
require("class.phpmailer.php");

// Check if form has been submitted.
if (isset($_POST['submitted']))
{
$errors = array(); //Initialize error array.

// Check for a name.
if (empty($_POST['name']))
{
$errors[] = 'Please enter a name.';
}

// Check for a company.
if (empty($_POST['company']))
{
$errors[] = 'Please enter a company name.';
}

// Check for an email address.
if (empty($_POST['emailaddr']))
{
$errors[] = 'Please enter an email address.';
}

// If everything is ok then send an email.
if (empty($errors))
{
$mail = new PHPMailer();
$mail->IsSMTP(); // telling the class to use SMTP
$mail->Host = "smtp.mywebsite.com"; // SMTP server
$mail->From = "support@mywebsite.com";
$mail->FromName = "mywebsite.com support team";
$mail->AddAddress($_POST['emailaddr']);
$mail->WordWrap = 50;
$mail->Subject = "your requested files.";
$mail->AddAttachment("/subfolder/importantfile.doc");
$mail->AddAttachment("/subfolfer2/coolfile.doc");
$mail->AddAttachment("/subfolder3/nice.bit");
$mail->Body = "Thanks for your interest.";

if(!$mail->Send())
{
echo 'Message was not sent.';
echo 'Mailer error: ' . $mail->ErrorInfo;
}
else
{
echo 'Message has been sent.';
}
}
}
?>

I have mod_PHP 5.0.5 installed, using roundcube, and spam assassin, Dada mail and IMAP Server installed.

Thanks for any help,
George

wildjokerdesign
12-13-2007, 12:06 PM
Is this really in your PHP script?

# Script 3.13 variation from PHPand MySQL VQuickPro Guide

In PHP comments are preceded by // not by #. Remove that from your PHP script and see if it helps. Also you can turn on error logging for the directory this script is in by placing a .htaccess file in the directory with this in it.

php_flag log_errors on
php_value error_log /var/www/html/php-error.log The above would write to a file called php-error.log in /var/www/html any errors that may occur in a script. The directory and name of the file can be changed if you want.

The only other thing I can see that may catch you up is your path to the attachments. I try to always use full paths to files. I would bet that you have those files located in /var/www/html/subfolder/

schsym
12-13-2007, 12:38 PM
first off, thanks for the debugging tool; I'm dying for some feedback of code I'm writing and I guess I'm learning the syntax as I go along, so I'm starting back with the printf() equivalent, echo. So far so good. A small form handler file works:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<title>Form Feedback</title>
</head>
<body>
<?php # Script 2.2 - handle_form.php

// Create a shorthand for the form data.
$name = $_REQUEST['name'];
$email = $_REQUEST['email'];
$comments = $_REQUEST['company'];

// Print the submitted information.
echo "<p>Thank you, <b>$name</b>, for working at:<br />
<tt>$comments</tt></p>
<p>We will reply to you at <i>$email</i>.</p>\n";

?>
</body>
</html>

**********************
This does send an email to my address (added lines in red):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<title>Form Feedback</title>
</head>
<body>
<?php # Script 2.2 - handle_form.php

// Create a shorthand for the form data.
$name = $_REQUEST['name'];
$email = $_REQUEST['email'];
$comments = $_REQUEST['company'];

// Print the submitted information.
echo "<p>Thank you, <b>$name</b>, for working at:<br />
<tt>$comments</tt></p>
<p>We will reply to you at <i>$email</i>.</p>\n";

$body = "Thank you for your interest in our fine company.\n
To get started with setting up hardware, please read the Users Guide.\n
blah, blah, blah";

mail ($email, 'Follow this link!', $body, 'From: support@mywebsite.com');
?>
</body>
</html>

Now that I've gotten this far, I will be adding the PHP Mailer scripts with debugging...
George

wildjokerdesign
12-14-2007, 08:35 AM
It looks like you are on the right track. At this point in the development of your script I think it is a good idea to look at security. Remember any input from the end user is dangerous! :) You always want to filter that input. You do some filtering of sorts in your original script but you need to take it a step further.

Here are two articles that should be very useful to you;
http://www.phpit.net/article/php-security-basic/
http://www.securephpwiki.com/index.php/Email_Injection

This first article mentions a function called valid_email(). You can get that function by following the PHPit Code Snippet Database link in the article. With a bit of modification it could be very useful to you.

Something I normally do with php scripts is assign $_POST, $_GET or $_REQUEST array variables I want to use to new variables. Using your script for example I would do this (I am includeding the PHP snippet of code from the first link I provided).

<?php
//Script 3.13 variation from PHPand MySQL VQuickPro Guide
$page_title = 'formv01';
require("class.phpmailer.php");
//Here we assign the $_POST array variables to new variables if they exist
$name = (isset($_POST['name']))? $_POST['name'] : '';
$company = (isset($_POST['company']))? $_POST['company'] : '';
$emailaddr = (isset($_POST['emailaddr']))? $_POST['emailaddr'] : '';
$submitted = (isset($_POST['submitted']))? $_POST['submitted'] : '';

// Check if form has been submitted.
// Also check to see that $submitted held a certian value
if (!empty($submitted) && $submitted == 'Some Value')
{
$errors = array(); //Initialize error array.

// Check for a name.
if (empty($name))
{
$errors[] = 'Please enter a name.';
}

// Check for a company.
if (empty($company))
{
$errors[] = 'Please enter a company name.';
}

// Check for an email address.
if (empty($emailaddr))
{
$errors[] = 'Please enter an email address.';
}
else
{
if (valid_email($emailaddr) == false)
{
$errors[] = 'Invalid email address.';
}
}

// If everything is ok then send an email.
if (empty($errors))
{
$mail = new PHPMailer();
$mail->IsSMTP(); // telling the class to use SMTP
$mail->Host = "smtp.mywebsite.com"; // SMTP server
$mail->From = "support@mywebsite.com";
$mail->FromName = "mywebsite.com support team";
$mail->AddAddress($emailaddr);
$mail->WordWrap = 50;
$mail->Subject = "your requested files.";
$mail->AddAttachment("/subfolder/importantfile.doc");
$mail->AddAttachment("/subfolfer2/coolfile.doc");
$mail->AddAttachment("/subfolder3/nice.bit");
$mail->Body = "Thanks for your interest.";

if(!$mail->Send())
{
echo 'Message was not sent.';
echo 'Mailer error: ' . $mail->ErrorInfo;
}
else
{
echo 'Message has been sent.';
}
}
}

//PHP code snippet posted by Dave Child at http://www.phpit.net/code/valid-email/
function valid_email($email) {

// First, we check that there's one @ symbol, and that the lengths are right
if (!ereg("^[^@]{1,64}@[^@]{1,255}$", $email)) {
// Email invalid because wrong number of characters in one section, or wrong number of @ symbols.

return false;
}
// Split it into sections to make life easier
$email_array = explode("@", $email);
$local_array = explode(".", $email_array[0]);
for ($i = 0; $i < sizeof($local_array); $i++) {
if (!ereg("^(([A-Za-z0-9!#$%&'*+/=?^_`{|}~-][A-Za-z0-9!#$%&'*+/=?^_`{|}~\.-]{0,63})|(\"[^(\\|\")]{0,62}\"))$", $local_array[$i])) {
return false;
}
}
if (!ereg("^\[?[0-9\.]+\]?$", $email_array[1])) { // Check if domain is IP. If not, it should be valid domain name
$domain_array = explode(".", $email_array[1]);
if (sizeof($domain_array) < 2) {
return false; // Not enough parts to domain
}
for ($i = 0; $i < sizeof($domain_array); $i++) {
if (!ereg("^(([A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9])|([A-Za-z0-9]+))$", $domain_array[$i])) {
return false;
}
}
}
return true;
}
?>

The code I use to assign the $_POST array variables means this: I placed the $_POST array variable inside of Parentheses () and followed it by a question mark ?. This is the same as if (isset($_POST['name'])). It is short hand when you want to assign a variable. After that you see two options of what to assign the variable to. The first option is assigned if there was a $_POST['name']. The second option which comes after the : is an empty string. There is more you can do with this method but I well leave it at that for now. :) Now you can use if (empty($name))
to check and make sure they entered data. It also makes it easier to run test on the variables I feel. The second link I provided above uses this method and actually takes a step further.

Hope all that helps you out some.

wildjokerdesign
12-14-2007, 08:42 AM
Thought I should mention one more thing. I notice in your second post you use $_REQUEST to retrive user input. I would stick with $_POST instead. $_REQUEST holds both $_POST and $_GET array variables and in this case you really want these to have come from the form which is $_POST array.

schsym
12-18-2007, 02:22 PM
Success!! (at least for me). After submittal of form, form handler will verify email, send email with requested files as attachments to requestor (if he put his own email address in the form), and send another email to specified users reporting requested files.
A few points on the script you copied above:
1. I don't quite understand the point of:

if (!empty($submitted) && $submitted == 'Some Value')
{

does this assume you have the form and submit button on the same page as the form handler and require this? I assumed that if the person entering the details is that sloppy or doesn't want to enter all info requested, or whatever, he should **** well be able to follow directions of clicking the back button to fix his mistakes :) ! I also am targetting the form handler to handle more request variations i.e. different files (I have no idea how yet, hint: maybe need help or a suggestion here. I'm assuming adding a field of item number and a PHP equivalent switch/case statement in the form handler.).

2. Thank you for the tip on email verification!! You were ahead of my plan, since that and URL verification are covered in the reference book I'm using (Uhllman's PHP & MySQL, chapter 10, script 10.7). I copied script you provided (seems to work fine).

3. An array of errors: I don't see where the script you provided actually notifies what the error in the form is anywhere other than just setting a flag that there is an error in an error checking statement (I couldn't get that array part to work, either) so I settled on:

$name = (isset($_POST['name']))? $_POST['name'] : '';
$company = (isset($_POST['companyname']))? $_POST['companyname'] : '';
$emailaddr = (isset($_POST['email']))? $_POST['email'] : '';

if (!$name || !$company || !(valid_email($emailaddr)))
{
...
which worked.

4. Do you think there is a more elegant way of sending two emails? I did not want to Bcc myself since I don't want all the attachments sent to me multiple times, I only need a report of who got sent what.

5. Westhost doesn't use SMTP, or rather I don't specify using it in setup, so I found the simple mail statement (required?). geez...
$mail->IsMail();

6. Don't understand POST vs. REQUEST and some others I've seen searching through scripts, but for now, I'll take your suggestion with the assumption it is more secure.

7. What editor do use? Love that syntax aware color coding.

So this is the script I finally think will be using since it satisfies (for now) what I need:

<?php
require ("class.phpmailer.php");

$name = (isset($_POST['name']))? $_POST['name'] : '';
$company = (isset($_POST['companyname']))? $_POST['companyname'] : '';
$emailaddr = (isset($_POST['email']))? $_POST['email'] : '';

if (!$name || !$company || !(valid_email($emailaddr)))
{
echo "<p>Errors in form!! Please click the browser back button. Either:\n<br />
1. Please fill in all fields, or\n<br />
2. make sure the email address you entered is valid.</p>";
}
else // all fields were filled in and mail determined to be valid so send an email.
{
$mail = new PHPMailer();
$mail->IsMail(); // telling the class to use Mail
$mail->From = "support@mywebsite.com";
$mail->FromName = "mywebsite.com support team";
$mail->AddAddress($emailaddr);
// $mail->AddBCC(toaddress,toname);
$mail->WordWrap = 80;
$mail->Subject = "Requested files from mywebsite.com";
$mail->AddAttachment("freedir/subdir1/filename.zip");
$mail->AddAttachment("freedir/subdir2/cool.pdf");

$mail->Body = "Thank you $name from $company for your interest in cool files.\n";

if(!$mail->Send())
{
echo 'Message was not sent.';
echo 'Mailer error: ' . $mail->ErrorInfo;
}
else
{
echo 'Message has been sent.';

// and send a report email to myself and coworker
$to = 'reporttoname@anywhereelse.com';
$subject = "filename and cool were downloaded";
$body = "filename and cool sent to:\n
$name \n
$company \n
$emailaddr \n";
$headers = "From: support@mywebsite.com\n";
$headers .= "Cc: someoneelse@anysite.com\n";
$headers .= "Content-Type: text/plain; charset=iso-8859-1\n";

mail ($to, $subject, $body, $headers);
}
}

wildjokerdesign
12-19-2007, 10:42 AM
1. I don't quite understand the point of:

if (!empty($submitted) && $submitted == 'Some Value')
{

That if statement is simply checking to make sure that the person submitted the form using the submit button. I use this method because in my scripts if they are not submitting information then it means I want to display the form. So in my case I add an else statement that well display the form. If someone where to access this php file without going useing the submit button you want it to do something even if it is to display a message that say's "Sorry you can not access the page directly. Please use the Form at ....".


3. An array of errors: I don't see where the script you provided actually notifies what the error in the form is anywhere other than just setting a flag that there is an error in an error checking statement (I couldn't get that array part to work, either) so I settled on:

Opps my bad! I use an else statement that cycles through the $error array and displays the the fields they missed and the form again. Why do I do this? To accommodate my user. Remember if you make them work too hard they well give up. Yes they could use the back button but why make them work that hard. I don't want them to become frustrated and leave my site.


4. Do you think there is a more elegant way of sending two emails? I did not want to Bcc myself since I don't want all the attachments sent to me multiple times, I only need a report of who got sent what.

Nope I think sending two emails is the best way and it is not that uncommon in a script like this. Forums like this one do it all the time. They would send one message to say the Admin when a person signs up and then another to the person who signed up. Like you mentioned you have no need to have the attachments sent to you and that would just increase the load on the email server and increase your bandwidth usage. Yep email is included in bandwidth totals. :)

6. Don't understand POST vs. REQUEST and some others I've seen searching through scripts, but for now, I'll take your suggestion with the assumption it is more secure.Using Post just helps to ensure that the person is really submitting via the form and not trying to abuse your script for their own purpose. It is not a complete guarantee but is one step in writing a good script.


7. What editor do use? Love that syntax aware color coding.

Well I use EditPlus (http://www.editplus.com/) for writing my scripts but that has nothing to do with the output you see here. :) I use the BBCode available for the forum to highlight the PHP code here. Look at the top of the post screen, the last icon is a sheet of paper with php on it. That well insert BBCode that looks like this:


I place all my PHP code between the tags and it shows up highlighted in the post. On this forum they call it vB Code and you can learn more about it here: http://forums.westhost.com/misc.php?do=bbcode

Edit Plus is free although there is a paid version of it that I use. I would suggest downloading it and giving it a try. It has some really cool features. :)

wildjokerdesign
12-19-2007, 10:46 AM
P.S. I don't have the time to explain at the moment but I just noticed a couple things about the code you posted. Nothing to extreme but a few things I want to point out. I don't have the time to go into it right now but well try to come back to this post and explain tomorrow.

wildjokerdesign
12-20-2007, 11:13 AM
The one thing I saw in your script that triggered an alarm for me is

echo 'Mailer error: ' . $mail->ErrorInfo;

It is always best to not echo such raw error information to the user. The reason is that it can often reveal information about your set up that could be used to hack your site. Now I am not 100% sure about the errors that are returned by the phpmailer class but better to be safe then sorry. :)

What you can do is write that information to a file on the server so you can access it latter to see what the problem may have been. Here is an example of the simplest of methods to do this:

$file_to_write_to = '/var/www/phpmailer_errors';
if ( $e_new = fopen($file_to_write_to, 'wt') )
{
fwrite($e_new, $mail->ErrorInfo);
fclose($e_new);
}
This would create a file called phpmailer_errors located at /var/www if it has not already been created. If it has already been created then it well open the file. It well then write the information contained in $mail->ErrorInfo or add it to it if there have been other errors to the file. It then closes the file.

Now you can logged into your site via FTP and navigate to /var/www (notice the file is written to a directory above where you place your public html files so it can not be accessed by the browser) and download the file phpmailer_errors that can then be viewed in EditPlus or another plain text editor.

I am actually working on writing up a tutorial of sorts on this subject with examples based on some code I already use. The example well give you a lot more flexibility in what you can do down the line i.e you mentioned you wanted to allow the user to choice what they would download. I am also going to show how you could re-use parts of the code on other pages if you wanted to.