PHP mail not working in one script, but does in another - php

I have a small php mailer script within a php file that works fine and sends mail fine:
$subject = "subject";
$mail_body = "mail body";
$name = "noreply";
$email = "noreply#domain.com";
$recipient = "somebody#domain.com";
$header = "From: ". $name . " <" . $email . ">\r\n";
mail($recipient, $subject, $mail_body, $header);
However, if I take this out and make it its own file, or put it into a different file, it doesn't work. There are no error messages and email is not sent.
There are no php ini set commands and no included php files.
Any ideas on why it works in the larger php script, but doesn't work on its own?

Everything is OK with your code. I tested it by only replacing the email address in $recipient with my address and it worked fine (I tested it with my corporate email - Outlook on Exchange server and another test with an Hotmail address - both worked fine and reached my inbox).
But make sure that new lines in $mail_body are "\n" and not "\r\n". As you can read in the docs about the message parameter:
Each line should be separated with a
LF (\n). Lines should not be larger
than 70 characters.
Make sure $name and $email does not contain forbidden characters like <, >, and new lines (\r, \n, or \r\n). As Michael points out new lines in there can lead to email injection attacks. You don't want your contact form to be used as a mail platform by spammers!
You should consider using an email library like PHPMailer which will ease your development since mail() is quite tricky for advanced mailing. Most of these libraries already cover these attacks and standards...

Related

imap_open function in PHP sometimes see blank message body

I am using imap_open function in PHP to download emails and insert them into a mysql database
Here is my code to get the headers and body message etc:
$emails = imap_search($inbox,'ALL');
//if emails are returned, cycle through each...
if($emails)
{
//begin output var
$output = '';
//put the newest emails on top
rsort($emails);
//for every email...
foreach($emails as $email_number)
{
//get information specific to this email
$header=imap_headerinfo($inbox,$email_number);
$structure = imap_fetchstructure($inbox,$email_number);
$from = $header->from[0]->mailbox . "#" . $header->from[0]->host;
$toaddress=$header->to[0]->mailbox."#".$header->to[0]->host;
$replyto=$header->reply_to[0]->mailbox."#".$header->reply_to[0]->host;
$datetime=date("Y-m-d H:i:s",$header->udate);
$subject=$header->subject;
$message = quoted_printable_decode(imap_fetchbody($inbox,$email_number,1.1));
if($message == '')
{
$message = quoted_printable_decode(imap_fetchbody($inbox,$email_number,1));
}
}
}
but it doesnt seem to get the body of all emails. For example, when it receives Read Receipts the body is just blank and the same with some other emails people send.
sometimes, the email body looks like:
PGh0bWw+DQo8aGVhZD4NCjxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0i dGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04Ij4NCjwvaGVhZD4NCjxib2R5IHN0eWxlPSJ3b3JkLXdy YXA6IGJyZWFrLXdvcmQ7IC13ZWJraXQtbmJzcC1tb2RlOiBzcGFjZTsgLXdlYmtpdC1saW5lLWJy ZWFrOiBhZnRlci13aGl0ZS1zcGFjZTsgY29sb3I6IHJnYigwLCAwLCAwKTsgZm9udC1zaXplOiAx NHB4OyBmb250LWZhbWlseTogQ2FsaWJyaSwgc2Fucy1zZXJpZjsiPg0KPGRpdj4NCjxkaXY+DQo8 ZGl2PnJlcGx5PC9kaXY+DQo8ZGl2Pg0KPHAgc3R5bGU9ImZvbnQtZmFtaWx5OiBDYWxpYnJpOyBt YXJnaW46IDBweCAwcHggMTJweDsiPjxiPktpbmQgUmVnYXJkcyw8YnI+DQo8YnI+DQpDaGFybGll IEZvcmQgfCZuYnNwOzwvYj48c3BhbiBzdHlsZT0iY29sb3I6IHJnYigyNTIsIDc5LCA4KTsiPjxi PlRlY2huaWNhbCBNYW5hZ2VyJm5ic3A7PC9iPjwvc3Bhbj48Yj58Jm5ic3A7SW50ZWdyYSBEaWdp dGFsPC9iPjxmb250IGNvbG9yPSIjNTk1OTU ... continued
How can i convert the whole message body to be plain text
Here's what I use, in general. $email refers to one of the objects from the return of eg imap_fetch_overview:
$structure = imap_fetchstructure($email->msgno);
$body = imap_fetchbody($email->msgno, '1');
if (3 === $structure->encoding) {
$body = imap_base64($body);
} else if (4 === $structure->encoding) {
$body = imap_qprint($body);
}
Note there are 6 possible encodings (ranging from 0 to 5), and I'm only handling 2 of them (3 and 4) -- you might want to handle all of them.
Also note I'm also getting only the 1st part (in imap_fetchbody) -- you might want to loop over the pieces to get them as needed.
Update
One other thing I noticed about your code. You're doing imap_fetchbody($inbox,$email_number,1.1). That third argument should be a string, not a number. Do this instead:
imap_fetchbody($inbox, $email_number, '1.1')
The code given handles only simple text messages having at most one sub-part and no encoding. This is basically the simplest kind of email there is. The world used to be that simple, sadly no more!
To handle more email, your code must be expanded to handle:
Multi-parts
Encodings
Multi-part is the concept that a single email message (a bunch of data) can be divided into multiple, logically-separate pieces. In the simplest case, there is only one part: the text of the message. In the next simplest case, there is message text with a single attachment. The next simplest case is message text plus multiple attachments. Then it starts to get hard, when the text of the message refers inline or embeds the attachments (think of an HTML message with an image -- that image could be an attachment that's linked with "local" CSS or embedded as eg base64 data url).
Encoding is the idea that email needs to accommodate the lowest common denominator of SMTP servers on the Internet. From 1971 to the early 1990s, most email messages were plain text using 7-bit US ASCII character set -- and SMTP mailers in the middle relied on this 7-bit framework. As the need for character sets became more apparent, simultaneously with the need to send binary data (eg images), 8-bit SMTP mailers cropped up as did various methods to shoe-horn 8-bit clean data into 7-bits. These include quoted-printable and base64. While 7-bit is virtually dead, we still have all the hoops of this history to jump through.
Rather than re-invent the wheel, there is a good piece of code on PHP.net that handles multi-part encoded messages. See the comment by david at hundsness dot com. You would use that code like this:
$mailbox = imap_open($service, $username, $password) or die('Cannot open mailbox');
// for all messages
$emails = imap_fetch_overview($mailbox, '1:1'/* . imap_check($mbox)->Nmsgs*/);
foreach ($emails as $email) {
// get the info
getmsg($mailbox, $email->msgno);
// now you have info from this message in these global vars:
// $charset,$htmlmsg,$plainmsg,$attachments
echo $plainmsg; // for example
}
imap_close($mailbox);
(Side note: his code has three parse errors, where he does ". =" to mean ".=". Fix those and you're good to go.)
Also, if you're looking for a good blog on doing this "from the ground up", check out this: http://www.electrictoolbox.com/php-imap-message-parts/

E-mail stored usernames and passwords via automated PHP script

I have more than 200 usernames, passwords, and e-mails within an excel sheet as well as a MySQL database. I would like to create a PHP automated script that appends the username and password to a strip of general text and sends it to the e-mail address in the same row.
Is this possible via PHP? I'm brand new to this and was hoping someone could point me in the right direction.
Any tips would be most appreciated!
You retrieve the data form the database and then send emails using PHP's mail function.
From the PHP Manual:
Using mail() to send a simple email:
<?php
// The message
$message = "Line 1\r\nLine 2\r\nLine 3";
// In case any of our lines are larger than 70 characters, we should use wordwrap()
$message = wordwrap($message, 70, "\r\n");
// Send
mail('caffeinated#example.com', 'My Subject', $message);
?>

CodeIgniter SMTP email message - characters replaced with equal signs

I'm using the CodeIgniter email library to send emails using our Exchange server. The problem I get is that the content of the email gets messed up.
There are some words that get replaced with equal signs "=", I tried 2 different Exchange servers (they are in different locations and have no relation what so ever) and I still get the same issue. If I use any other server as an SMTP server to send emails everything works fine and the content stays intact and unchanged.
Content before sending:
Dear Customer
Please find attached a comprehensive explanation of how to get our brochure of Angola. This has been sent to you at the request of Alex.
The information has been taken from www.example.co.uk "Company name" is one of the leading tile and marble companies in the UK.
Content after sending it through the Microsoft Exchange:
Dear Customer
Please find attached a comprehensive explanation of how to get our brochure of A=gola. This has been sent to you at the request of Alex.
The information has been taken from www.example.co.uk "Company name" is one of the leadi=g tile and marble companies in the UK.
As you can see for some reason some of the "n" characters were replaced with equal signs "=" (Example: Angola > A=gola)
My email configuration:
$this->load->library('email');
$config['charset'] = 'utf-8';
$config['mailtype'] = 'html';
// SMTP
$config['protocol'] = 'smtp';
$config['smtp_host'] = 'exchange.example.com'; //ssl://
$config['smtp_user'] = 'email#example.com';
$config['smtp_pass'] = 'password';
$config['smtp_port'] = 25;
$this->email->set_newline( "\r\n" );
$this->email->initialize( $config );
$this->email->clear();
......
$this->email->from( $frome, $fromn );
$this->email->to( $email );
$this->email->subject( $subject );
$this->email->message( $send_message );
$this->email->send();
Does anyone know why is the Microsoft exchange behaving this way? or is there some sort of setting I should use?
That's odd, specially since not all the ns are transliterated and not at a specific position.
Try calling $this->email->set_crlf( "\r\n" ); as well. Look up the message details in Exchange and inspect the Content-Type and Charset / Encoding - post the raw thing here so we can inspect it.
I found this in Microsoft Knowledgebase:
Microsoft Exchange uses an enhanced character set. The default MIME
character set for Microsoft Exchange is ISO 8859-1. Some gateways do
not support the way this character set issues a soft return for line
feeds. When this occurs, each line is terminated with an equal sign
showing the line break where the gateway's line-length support ends.
I solved this (kinda) by setting $charlim = '998' in the _prep_quoted_printable function.
When I set $crlf = "\r\n" the resulting email was completely garbled for some reason. But I noticed that the = signs were appearing at regular intervals which was caused by the line length being limited to 76 characters. So increasing the max characters per line (998 is the RFC2822 limit) solves the problem, as long as you don't have really long lines.

mail() works while mb_send_mail() does not in multi-byte environment

Lately, we have transitioned our environment over to use UTF-8 encoding. Everything seemed to be working perfectly. Pages were being served up correctly in UTF-8 and email sent with PHP's mail() function were also being sent with (in our case) French characters appearing properly.
This morning, I started substituting non-multi-byte string functions (e.g., strlen(), mail()) with their multi-byte counterpart (e.g., mb_strlen(), mb_send_mail()) and it appears to be working as expected in all cases, except for mb_send_mail(), where French characters appear as question marks. Oddly, they appear correctly when using mail(). I also have the charset set to utf-8 in the email's headers in both cases, and checking it in my email client confirms that it is sent as such.
I should add that I am not using the Function Overloading feature, because I was concerned it would interfere with third-party extensions we are using, which is why I have chosen to replace the functions manually.
EDIT
These lines were modified/added in php.ini:
default_charset = "utf-8"
mbstring.language=Neutral
mbstring.internal_encoding=utf-8
mbstring.http_input=UTF-8
mbstring.http_output=UTF-8
mbstring.encoding_translation=On
My PHP files are also all saved in UTF-8 encoding, without BOM.
The code when calling the mb_send_mail() function looks like this:
$to = "person#email.com";
$subject = "Assigné";
$body = "La demande suivante vous a été assigné : "
$headers .= 'From: ' . $from . "\r\n";
$headers .= 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-Type: text/html; charset="utf-8"' . "\r\n";
$headers .= 'Content-Transfer-Encoding: quoted-printable' . "\r\n";
if (!(#mb_send_mail($to, $subject, $body, $headers))) {
//Error message
}
As indicated in my original post, when using the mb_send_mail() function, all my e acute (é) characters, including the email's subject and bosy, appear as question marks (?), but when using the mail() function, they appear as intended.
Keep the mail() function it works better as far as I have noticed.
See PHP manual for mb_send_mail() others recommend it to.

Sending cross platform emails with PHP, how to handle line breaks?

When creating a script to send emails using the PHP mail() function I'm coming across issues with new lines. PHP on Unix systems expect headers to be separated with a LF character, despite what the docs say, sendmail then replaces these with the correct CRLF. However on Windows the message and headers are sent as provided. This was described in a long running PHP bug report.
So I need a method of detecting whether the system is running the Unix version of sendmail in order to use LF and use CRLF on Windows. I'm aware of PHP_EOL but I'm wondering if there's a more elegant way of handling this.
Currently I'm building my message, as specified by the docs, like so.
<?php
$to = "example#website.com";
$subject = "Email Subject Here";
$message = "Hello this is a plaintext\n message with a line break.";
$headers = array(
"From: webmaster#example.com",
"Reply-To: webmaster#example.com",
"X-Mailer: PHP/" . phpversion()
);
$success = mail($to, $subject, $message, join("\r\n", $headers));
if ($success) {
echo "Mail Sent\n";
} else {
echo "Mail Failed\n";
}
On Unix systems this results in the following message being sent to sendmail (\r and \n have been replaced by textual representations):
To: example#website.comLF
Subject: Email Subject HereLF
X-PHP-Originating-Script: 501:mail.phpLF
From: webmaster#example.comCRLF
Reply-To: webmaster#example.comCRLF
X-Mailer: PHP/5.3.1LF
LF
Hello this is a plaintextLF
message with a line break.LF
When this is passed to sendmail all LF are replaced with CRLF resulting in duplicate carriage returns. Some mail servers then replace this additional CR with CRLF resulting in an additional line break and all headers, in this case after From:, are now part of the message body.
PHP actually inserts the X-PHP-Originating-Script header with incorrect line ending, which is a side issue but still annoying. – Actually a PHP 5.3 bug, now fixed.
Any ideas on an ideal way of handling this cross platform?
Thanks,
Aron
This was a rather transient defect in the early 5.3 releases see this bug notice
Upgrade your PHP

Categories