sawade Posted August 24, 2009 Share Posted August 24, 2009 This is driving me insane and I must get this done today. I have a self-processing PHP form, this form is supposed to take the info submitted and write it to a csv file and then send an email with the info in it and the csv as an attachment. I'm sure it is probably something small that I am not seeing. The info is currently being written to the csv, but email is not being sent. I get the following error which is not in my php file but in a pear pkg mail.php file. [24-Aug-2009 10:16:14] PHP Warning: Invalid argument supplied for foreach() in /Mail.php on line 123 [24-Aug-2009 10:16:14] PHP Warning: Invalid argument supplied for foreach() in /Mail.php on line 151 function _sanitizeHeaders(&$headers) { foreach ($headers as $key => $value) { $headers[$key] = preg_replace('=((<CR>|<LF>|0x0A/%0A|0x0D/%0D|\\n|\\r)\S).*=i', null, $value); } } foreach ($headers as $key => $value) { if (strcasecmp($key, 'From') === 0) { include_once 'Mail/RFC822.php'; $parser = &new Mail_RFC822(); $addresses = $parser->parseAddressList($value, 'localhost', false); if (PEAR::isError($addresses)) { return $addresses; }etc.... Here is my code: if (!empty($vistor_name) && !empty($email_address) && !empty($question_comment)) { $user_pass_phrase = $_POST['verify']; if ($_SESSION['pass_phrase'] == $user_pass_phrase) { //Validate Email Address include('EmailAddressValidator.php'); $validator = new EmailAddressValidator; if ($validator->check_email_address($email_address)) { // Send the Email require_once "/Mail.php"; $to = $_POST['email']; $headers["Subject"] = "CSV"; $smtp["host"] = "localhost"; $smtp["port"] = "26"; $smtp["auth"] = true; $smtp["username"] = "user"; $smtp["password"] = "pass"; $msg = "Code No.: $user_pass_phrase\n" . "\n" . "Name: $vistor_name\n" . "Phone Number: $phone_number\n" . "E-mail Address: $email_address\n" . "Question or Comment: $question_comment"; //Creates CSV file $cr = "\n"; $csvData = "Name" . ',' . "Phone" . ',' . "Email" . ',' . "Question/Comment" . $cr; $csvData .= $vistor_name . ',' . $phone_number . ',' . $email_address . ',' . $question_comment . $cr; //Open the file $fp = fopen("csvdemo.csv","a"); fwrite($fp,$csvData); // Write information to the file fclose($fp); // Close the file $attachments[] = Array( 'data' => $csvData, 'name' => 'csvdemo.csv', 'type' => 'application/vnd.ms-excel'); //Generate a boundary string $semi_rand = md5(time()); $mime_boundary = "==Multipart_Boundary_x{$semi_rand}x"; //Add the headers for a file attachment $headers = "MIME-Version: 1.0\n" . "From: contactus@medsolutionservices.com\n" . "Content-Type: multipart/mixed;\n" . " boundary=\"{$mime_boundary}\""; //Add a multipart boundary above the plain message $message = "This is a multi-part message in MIME format.\n\n" . "--{$mime_boundary}\n" . "Content-Type: text/html; charset=\"iso-8859-1\"\n" . "Content-Transfer-Encoding: 7bit\n\n" . $msg . "\n\n"; //Add sttachments foreach($attachments as $attachment){ $data = chunk_split(base64_encode($attachment['data'])); $name = $attachment['name']; $type = $attachment['type']; $message .= "--{$mime_boundary}\n" . "Content-Type: {$type};\n" . " name=\"{$name}\"\n" . "Content-Transfer-Encoding: base64\n\n" . $data . "\n\n" ; } $message .= "--{$mime_boundary}--\n"; // Sends the email $mail = Mail::factory('smtp', $smtp); $mail->send($to, $headers, $message) or die('Error while processing your submission.'); // Confirm success with the user echo '<p>Thank you for sending us your question or comment.<br />'; echo 'We will respond to you as quickly as possible.</p>'; echo '<p><br /></p>'; echo '<table id="contactusconfirm">'; echo '<tr>'; echo '<th class="confirmthcontact"><span class="contactconfirm">Name:</span></th>'; echo '<td>' . $vistor_name . '</td>'; echo '</tr>'; echo '<tr>'; echo '<th class="confirmthcontact"><span class="contactconfirm">Phone Number:</span></th>'; echo '<td>' . $phone_number . '</td>'; echo '</tr>'; echo '<tr>'; echo '<th class="confirmthcontact"><span class="contactconfirm">E-mail Address:</span></th>'; echo '<td>' . $email_address . '</td>'; echo '</tr>'; echo '<tr>'; echo '<th class="confirmthcontact"><span class="contactconfirm">Question or Comment:</span></th>'; echo '<td>' . $question_comment . '</td>'; echo '</tr>'; echo '</table'; } else { // Email not valid echo '<p class="error">Please input a VALID EMAIL ADDRESS.</p>'; $output_form = true; } } else { echo '<p class="error">Please enter the VERIFICATION PASS-PHRASE exactly as shown.</p>'; $output_form = true; } } Also, is it possible to clear the csv file at the end of each session? I don't want information to be stored in the file. Just written to it, emailed and erased. Thanks for the extra set of eyes and a clear mind. Quote Link to comment https://forums.phpfreaks.com/topic/171658-solved-invalid-argument-supplied-for-foreach/ Share on other sites More sharing options...
mikesta707 Posted August 24, 2009 Share Posted August 24, 2009 Well that error happens when you put a non array into the foreach statement. make sure that you are indeed supplying an array into the foreach. Perhaps try doing a print_r before you execute the foreach and see if you are indeed passing an array into the foreach (which it would appear you are not) Quote Link to comment https://forums.phpfreaks.com/topic/171658-solved-invalid-argument-supplied-for-foreach/#findComment-905152 Share on other sites More sharing options...
sawade Posted August 24, 2009 Author Share Posted August 24, 2009 I think I see what the issue is. It looks like the headers aren't right for mail::send(). Any ideas how to convert? Quote Link to comment https://forums.phpfreaks.com/topic/171658-solved-invalid-argument-supplied-for-foreach/#findComment-905166 Share on other sites More sharing options...
mikesta707 Posted August 24, 2009 Share Posted August 24, 2009 I'm not sure how your specific mail method is set up, but the standard PHP mail function takes the $headers argument as the 4th parameter I think. Here is how it should be set up bool mail ( string $to , string $subject , string $message [, string $additional_headers [, string $additional_parameters ]] ) but your mail function seems different. From what I can tell from your errors, your header variable should be an array. try making each line an entry in the array IE instead of $headers = "MIME-Version: 1.0\n" . "From: contactus@medsolutionservices.com\n" . "Content-Type: multipart/mixed;\n" . " boundary=\"{$mime_boundary}\""; try $headers = array("MIME-Version: 1.0\n", "From: contactus@medsolutionservices.com\n", "Content-Type: multipart/mixed;\n", " boundary=\"{$mime_boundary}\""); Quote Link to comment https://forums.phpfreaks.com/topic/171658-solved-invalid-argument-supplied-for-foreach/#findComment-905174 Share on other sites More sharing options...
sawade Posted August 24, 2009 Author Share Posted August 24, 2009 Right that is for the mail() function. I use mail::send() function. Pear. Quote Link to comment https://forums.phpfreaks.com/topic/171658-solved-invalid-argument-supplied-for-foreach/#findComment-905177 Share on other sites More sharing options...
sawade Posted August 25, 2009 Author Share Posted August 25, 2009 I think I see what the issue is. It looks like the headers aren't right for mail::send(). Any ideas how to convert? Anyone? How to make $headers = blah; to $headers['blah'] = blah; Quote Link to comment https://forums.phpfreaks.com/topic/171658-solved-invalid-argument-supplied-for-foreach/#findComment-905959 Share on other sites More sharing options...
mikesta707 Posted August 25, 2009 Share Posted August 25, 2009 look at my post... It won't be an associative array, but it will become an array Quote Link to comment https://forums.phpfreaks.com/topic/171658-solved-invalid-argument-supplied-for-foreach/#findComment-905979 Share on other sites More sharing options...
sawade Posted August 25, 2009 Author Share Posted August 25, 2009 I tried it. Still have the same error. Quote Link to comment https://forums.phpfreaks.com/topic/171658-solved-invalid-argument-supplied-for-foreach/#findComment-905980 Share on other sites More sharing options...
sawade Posted August 27, 2009 Author Share Posted August 27, 2009 I made some changes in the code. Tried rewriting the headers. But I still get stuck on the foreach() in mail.php file. Which is a pear file. Basically I know it doesn't like the $headers variable strings, but am not sure how to fix them. // Send the Email require_once "Mail.php"; require_once "ContactConstants.php"; $to = $email_address; $subject = "CSV"; $smtp["host"] = SMTP_HOST; $smtp["port"] = SMTP_PORT; $smtp["auth"] = true; $smtp["username"] = SMTP_USERNAME; $smtp["password"] = SMTP_PASSWORD; $msg = "Code No.: $user_pass_phrase\n" . "IP: $client_ip_address\n" . "Date: $date\n" . "Name: $visitor_name\n" . "Phone Number: $phone_number\n" . "E-mail Address: $email_address\n" . "Question or Comment: $question_comment"; //Creates CSV file $cr = "\n"; $csvData = "Name" . ',' . "Phone" . ',' . "Email" . ',' . "Question/Comment" . $cr; $csvData .= $visitor_name . ',' . $phone_number . ',' . $email_address . ',' . $question_comment . $cr; //Open the file $filehandler = fopen("csvdemo.csv","a") or die("Can't write file."); //change to "w" later fwrite($filehandler,$csvData); // Write information to the file fclose($filehandler); // Close the file $attachments[] = Array( 'data' => $csvData, 'name' => 'csvdemo.csv', 'type' => 'application/vnd.ms-excel'); //Generate a boundary string $semi_rand = md5(time()); $mime_boundary = "==Multipart_Boundary_x{$semi_rand}x"; //Add the headers for a file attachment $headers = 'From: CONTACT_US' . "\r\n"; $headers .= 'MIME-Version: 1.0' . "\r\n"; $headers .= 'Content-Type: multipart/mixed; boundary=\"{$mime_boundary}\"' . "\r\n"; //Add a multipart boundary above the plain message $message = "--{$mime_boundary}\n" . "Content-Type: text/csv; charset=\"iso-8859-1\"\n" . "Content-Transfer-Encoding: 8bit\n\n" . "Content-Disposition: attachment; filename=\"csvdemo.csv\"\n\n" . $msg . "\n\n"; //Add attachments foreach($attachments as $attachment){ $data = chunk_split(base64_encode($attachment['data'])); $name = $attachment['name']; $type = $attachment['type']; $message .= "--{$mime_boundary}\n" . "Content-Type: {$type};\n" . " name=\"{$name}\"\n" . "Content-Transfer-Encoding: base64\n\n" . $data . "\n\n" ; } $message .= "--{$mime_boundary}--\n\n"; // Sends the email $mail = Mail::factory('smtp', $smtp); $mail->send($to, $subject, $message, $headers) or die('Error while processing your submission.'); Quote Link to comment https://forums.phpfreaks.com/topic/171658-solved-invalid-argument-supplied-for-foreach/#findComment-907734 Share on other sites More sharing options...
akitchin Posted August 27, 2009 Share Posted August 27, 2009 this is a question concerning PEAR - i don't know specifically what format PEAR expects your headers to be in (beyond requiring that it's an array), but i would assume that they are expecting it in the format: 'header_name' => 'header_value' in that case, your headers should be: $headers['From'] = 'CONTACT_US'; // note that this is invalid - if you want to use the constant CONTACT_US, drop the quotes $headers['MIME-Version'] = '1.0'; $headers['Content-Type'] = 'multipart/mixed; boundary=\"{$mime_boundary}\"'; // note that $mime_boundary won't be replace here, as you're using single quotes to delimit the string do you have documentation on the format PEAR requires? Quote Link to comment https://forums.phpfreaks.com/topic/171658-solved-invalid-argument-supplied-for-foreach/#findComment-907746 Share on other sites More sharing options...
sawade Posted August 27, 2009 Author Share Posted August 27, 2009 Thank you. That fixed the header issue. So I don't get any error messages. But the email that I receive is blank. It shows that there is an attachment, but I can't get to it. require_once "/Mail.php"; require_once "/ContactConstants.php"; //Creates CSV file $cr = "\n"; $csvData = "Name" . ',' . "Phone" . ',' . "Email" . ',' . "Question/Comment" . $cr; $csvData .= $visitor_name . ',' . $phone_number . ',' . $email_address . ',' . $question_comment . $cr; //Open the file $filehandler = fopen("csvdemo.csv","a") or die("Can't write file."); //change to "w" later fwrite($filehandler,$csvData); // Write information to the file fclose($filehandler); // Close the file $attachments[] = Array( 'data' => $csvData, 'name' => 'csvdemo.csv', 'type' => 'application/vnd.ms-excel'); //Generate a boundary string $semi_rand = md5(time()); $mime_boundary = "==Multipart_Boundary_x{$semi_rand}x"; $to = $email_address; $headers['Subject'] = "CSV"; $headers['From'] = CONTACT_US; //Headers for a file attachment $headers['MIME-Version'] = '1.0'; $headers['Content-Type'] = 'multipart/mixed; boundary=\"{$mime_boundary}\"'; $smtp["host"] = SMTP_HOST; $smtp["port"] = SMTP_PORT; $smtp["auth"] = true; $smtp["username"] = SMTP_USERNAME; $smtp["password"] = SMTP_PASSWORD; $msg = "--{$mime_boundary}\n" . "Content-Type: text/csv; charset=\"iso-8859-1\"\n" . "Content-Transfer-Encoding: base64\n" . "Content-Disposition: attachment; filename='csvdemo.csv'\n\n" . "Code No.: $user_pass_phrase\n" . "IP: $client_ip_address\n" . "Date: $date\n" . "Name: $visitor_name\n" . "Phone Number: $phone_number\n" . "E-mail Address: $email_address\n" . "Question or Comment: $question_comment\n" . "\n\n"; //Add attachments foreach($attachments as $attachment){ $data = chunk_split(base64_encode($attachment['data'])); $name = $attachment['name']; $type = $attachment['type']; $msg .= "--{$mime_boundary}\n" . "Content-Type: $type name= $name\n" . "Content-Transfer-Encoding: base64\n" . $data . "\n\n" ; } $msg .= "--{$mime_boundary}--\n\n"; // Sends the email $mail = Mail::factory('smtp', $smtp); $mail->send($to, $headers, $msg) or die('Error while processing your submission.'); Quote Link to comment https://forums.phpfreaks.com/topic/171658-solved-invalid-argument-supplied-for-foreach/#findComment-907829 Share on other sites More sharing options...
sawade Posted August 28, 2009 Author Share Posted August 28, 2009 Also, is it possible to clear the csv file at the end of each session? I don't want information to be stored in the file. Just written to it, emailed and erased. I think I have this figured out. I added in code that unlinks the file after it is emailed. I also made some more adjustments to the code. But I am still getting the same results. What it CAN do: 1- Create and write data to the file 2- Create and send the email 3- Received email is BLANK but does show an attachment, however attachment can not be opened. 4- Complete the echo confirm on the website What is is FAILING at: 1- Successfully attaching to the email message 2- Showing the actual email message I am getting so close to completing this. I'm sure it is something small that I am missing. Here is the new code: // Send the Email require_once "/Mail.php"; require_once "/ContactConstants.php"; //Creates CSV file $cr = "\n"; $csvData = "Name" . ',' . "Phone" . ',' . "Email" . ',' . "Question/Comment" . $cr; $csvData .= $visitor_name . ',' . $phone_number . ',' . $email_address . ',' . $question_comment . $cr; //Open the file $filehandler = fopen("csvdemo.csv","a") or die("Can't write file."); //change to "w" later fwrite($filehandler,$csvData); // Write information to the file fclose($filehandler); // Close the file $attachments[] = Array( 'data' => $csvData, 'name' => 'csvdemo.csv', 'type' => 'application/vnd.ms-excel'); //Generate a boundary string $semi_rand = md5(time()); $mime_boundary = "==Multipart_Boundary_x{$semi_rand}x"; $to = $email_address; $headers['Subject'] = "CSV"; $headers['From'] = CONTACT_US; //Headers for a file attachment $headers['MIME-Version'] = '1.0'; $headers['Content-Type'] = 'multipart/mixed; boundary=\"{$mime_boundary}\"'; $smtp["host"] = SMTP_HOST; $smtp["port"] = SMTP_PORT; $smtp["auth"] = true; $smtp["username"] = SMTP_USERNAME; $smtp["password"] = SMTP_PASSWORD; $msg = "This is a multi-part message in MIME format.\n\n" . "--{$mime_boundary}\n" . "Content-Type: text/csv; charset=\"iso-8859-1\"\n" . "Content-Transfer-Encoding: 7bit\n\n" . "Code No.: $user_pass_phrase\n" . "IP: $client_ip_address\n" . "Date: $date\n" . "Name: $visitor_name\n" . "Phone Number: $phone_number\n" . "E-mail Address: $email_address\n" . "Question or Comment: $question_comment\n" . "\n\n"; //Add attachments foreach($attachments as $attachment){ $data = chunk_split(base64_encode($attachment['data'])); $name = $attachment['name']; $type = $attachment['type']; $msg .= "--{$mime_boundary}\n" . "Content-Type: {$type};\n" . " name=\'{$name}\'\n" . "Content-Disposition: attachment;\n" . "filename=\'{$name}\'\n" . "Content-Transfer-Encoding: base64\n" . $data . "\n\n" . "--{$mime_boundary}--\n"; } // Sends the email $mail = Mail::factory('smtp', $smtp); $mail->send($to, $headers, $msg) or die('Error while processing your submission.'); //Delete Created File if (unlink($name)) { echo '<p class="error">FILE DELETED</p>'; } else { echo '<p class="error">FILE NOT DELETED</p>'; } // Confirm success with the user Quote Link to comment https://forums.phpfreaks.com/topic/171658-solved-invalid-argument-supplied-for-foreach/#findComment-907988 Share on other sites More sharing options...
sawade Posted August 29, 2009 Author Share Posted August 29, 2009 Figured it out. Quote Link to comment https://forums.phpfreaks.com/topic/171658-solved-invalid-argument-supplied-for-foreach/#findComment-908935 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.