Hi I am wondering if someone could take a look at my code and see what error there is as I cant see any. what is happening is that it is not saving the emails I am sending it to the mysql, and instead I get a bounced email back.
When I run PHP test to see if it saves to the mysql table, it does not.
I have taken out the connect code as it has my username and password.
#!/usr/bin/php -q
<?php
mysql_connect("123.123.123.2", "abc_ard", "5555") or die(mysql_error());
mysql_select_db("55_servermail") or die(mysql_error());
chdir(dirname(__FILE__));
$fd = fopen("php://stdin", "r");
$email = "";
while (!feof($fd)) {
$email .= fread($fd, 1024);
}
fclose($fd);
if(strlen($email)<1) {
die();
}
// handle email
$lines = explode("\n", $email);
// empty vars
$from = "";
$to="";
$subject = "";
$headers = "";
$message = "";
$splittingheaders = true;
for ($i=0; $i < count($lines); $i++) {
if ($splittingheaders) {
// this is a header
$headers .= $lines[$i]."\n";
// look out for special headers
if (preg_match("/^Subject: (.*)/", $lines[$i], $matches)) {
$subject = $matches[1];
}
if (preg_match("/^From: (.*)/", $lines[$i], $matches)) {
$from = $matches[1];
}
if (preg_match("/^To: (.*)/", $lines[$i], $matches)) {
$to = $matches[1];
}
} else {
// not a header, but message
$message .= $lines[$i]."\n";
}
if (trim($lines[$i])=="") {
// empty line, header section has ended
$splittingheaders = false;
}
}
mysql_query("INSERT INTO mail
(`to`,`from`,`header`,`subject`,`msg`,`original`)
VALUES
('{$to}','{$from}', '{$headers}','{$subject}','{$message}','{$email}')") or die(mysql_error());;
?>
When adding information to mysql you have to account for characters used by mysql and PHP and address them as they can cause code to fail, and even allow people to insertand/or execute code on your site. The simplest method I have used is to have PHP "escape" the characters to allow them to insert into mysql properly as follows:
$email = "This isn't my first time 'round here";
This should insert fine as is, but let's presume that your SQL is like this:
$query = "INSERT INTO table (timestamp,email) VALUES (time(),'$email')";
the single quotes in the MySQL query will be jacked up by the single quotes in your data. In order to avoid this set your email variable to be escaped:
$email = "This isn't my first time 'round here";
$email = mysql_escape_string($email);
The caviat to using this is that now your database has extra escape characters (typically a backslash "/") in your data, so when you want to use these from the database you will have to remove them and PHP has a handy function just for this:
$query = "SELECT * FROM table WHERE id='the id you want'";
$result = mysql_query($query) or die(mysql_error());
while ($data = mysql_fetch_array($result)) {
$email = stripslashes($data['email']);
}
echo "This is your email text from the database: <br>\n".$email."<br>\n";
Hope that helps to clarify one possible solution (if that is indeed why the email is not inserting into the database as expected).
the only error that I could possibly see in this current code is the possibility of entering characters like apostrophe(') please verify that if you want it to be included on the message body or other fields make sure to use the backslash() e.g (\') so that mysql will analyze it as a charater and not a closing apostrophe, but do have a security measure on doing that to avoid sql injection. :)
Related
I have a strange issue. My SaaS receives leads from various third party companies via email (I know ... its old school). I use the pipe to a program feature in cpanel to send the email to a script that parses out the to from subject and message. In the message is a xml message. Here is the code for this (php):
$lines = explode("\n", $email_content);
// initialize variable which will assigned later on
$from = "";
$subject = "";
$headers = "";
$message = "";
$is_header= true;
//loop through each line
for ($i=0; $i < count($lines); $i++) {
if ($is_header) {
// hear information. instead of main message body, all other information are here.
$headers .= $lines[$i]."\n";
// Split out the subject portion
if (preg_match("/^Subject: (.*)/", $lines[$i], $matches)) {
$subject = $matches[1];
}
//Split out the sender information portion
if (preg_match("/^From: (.*)/", $lines[$i], $matches)) {
$from = $matches[1];
}
} else {
// content/main message body information
//$message .= $lines[$i]."\n";
$message .= $lines[$i];
}
if (trim($lines[$i])=="") {
// empty line, header section has ended
$is_header = false;
}
}
Then I just insert the variables into my MySQL database. For some of the emails this works perfect. But some emails the xml gets odd characters inserted. An example below
<?xml version=3D"1.0" encoding=3D"UTF-8"?>=0D=0A<?adf version=3D"1.0"?>==0D=0A<adf>
Notice the '3D' and '=0D=0A' .... I believe this may have to do with the encoding? Some are UTF 8, UTF 16 and the ones that work do not have a UTF assigned.
I am inserting the xml part into a 'TEXT' type as MySQL does not seem to have a XML option.
I've created a static website (clients request) and we have put a email form inside the contacts page. the form works well and sends the data but in the email that is received i get
sam\'s clover\'s (Test Data) how to cleans the data in a static website to remove the \'s and just leave it as 's in the email.
I've tried looking with my keywords not really finding any luck based on the static parts.
any help would be great thanks
This is the vars i'm using at the moment.
$to = STRIP_TAGS($_POST['remail']);
$from = STRIP_TAGS($_POST['semail']);
$phone = STRIP_TAGS($_POST['sphone']);
$subject = STRIP_TAGS($_POST['subject']);
$message = STRIP_TAGS($_POST['message']);
$headers = "From:" . $from;
Use stripslashes():
It unquotes a quoted string. So \' becomes '.
$to = stripslashes($_POST['remail']);
$from = stripslashes($_POST['semail']);
$phone = stripslashes($_POST['sphone']);
$subject = stripslashes($_POST['subject']);
$message = stripslashes($_POST['message']);
$headers = "From:" . $from;
You can also use it for arrays:
stripslashes_deep($array_name);
Read about it here: http://php.net/manual/en/function.stripslashes.php
What your after is stripslashes(), but if slashes are being added by PHP automatically from magic quotes then you should check for that, this way your script will run on any server, not just a server with magic quotes on.
Here is a callback function that will loop through all the effected Global vars and fix. You would add this as part of your initialization.
<?php
function process_gpc(&$value, $key){
//magic quotes fix
if (get_magic_quotes_gpc()) {
$key = stripslashes($key);
$value = stripslashes($value);
}
//null byte (string termination) protection
$key = str_replace(chr(0), '', $key);
$value = str_replace(chr(0), '', $value);
}
$inputs = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST, &$_FILES);
array_walk_recursive($inputs, 'process_gpc');
?>
I'm trying to parse emails sent to "parsethis#mysite.com" with PHP (I will use a cronjob, but for now I am just hitting mysite.com/cronJobs/parseMail in my browser).
This is my first time trying to parse emails .. so I'm just not sure how to go about troubleshooting this at all.
Here is the code I'm using, found it on a site and it seemed to be something I can work from. (Yes I have replaced all the placeholders)
$mailbox = imap_open("{mysite.com:143/notls}INBOX", "parsethis#mysite.com", "123password"); //connects to mailbox on your server
if ($mailbox == false) {
echo "<p>Error: Can't open mailbox!</p>";
echo imap_last_error();
}else{
//Check number of messages
$num = imap_num_msg($mailbox);
//if there is a message in your inbox
if( $num > 0 ) { //this just reads the most recent email. In order to go through all the emails, you'll have to loop through the number of messages
$email = imap_fetchheader($mailbox, $num); //get email header
$lines = explode("\n", $email);
// data we are looking for
$from = "";
$subject = "";
$to = "";
$headers = "";
$splittingheaders = true;
for ($i=0; $i < count($lines); $i++) {
if ($splittingheaders) {
// this is a header
$headers .= $lines[$i]."\n";
// look out for special headers
if (preg_match("/^Subject: (.*)/", $lines[$i], $matches)) {
$subject = $matches[1];
}
if (preg_match("/^From: (.*)/", $lines[$i], $matches)) {
$from = $matches[1];
}
if (preg_match("/^To: (.*)/", $lines[$i], $matches)) {
$to = $matches[1];
}
}
}
//We can just display the relevant information in our browser, like below or write some method, that will put that information in a database
echo "FROM: ".$from."<br>";
echo "TO: ".$to."<br>";
echo "SUBJECT: ".$subject."<br>";
echo "BODY: ".imap_qprint(imap_body($mailbox, $num));
//delete message
// imap_delete($mailbox,$num); // not while testing
// imap_expunge($mailbox); // not while testing
}else{
// echo "No more messages";
}
imap_close($mailbox);
}
Problem is : I get this when I hit it
FROM: "K.K.Smith"
TO: parsethis#mysite.com
SUBJECT: test subject
BODY: --50f9f846_140e0f76_3df1 Content-Type: // etc .. with the body of the email unformatted in a continuous string
// INTERESTING > I get the body twice .. doubled.. once as a long unformatted string, and then again with formatting
--50f9f846_140e0f76_3df1 Content-Type: text/html; // etc.. the rest of the body with formatting .. ie my signature is correctly formatted with spacing and line breaks unlike the first body output
/// ***and then this weird error at the end***
--50f9f846_140e0f76_3df1--
Fatal error: Exception thrown without a stack frame in Unknown on line 0
So I don't know what that means. I have googled and all results seem to indicate it is a "mysterious error". It looks like it is about to output the body for a third time (I don't really know what that weird string is.. an email id maybe?) .. but then it chokes where it didn't choke the two previous times.
.. can anyone give any ideas how I should move forward?
EDIT
so I reduced the parseMail function to just the minimum..
public function parseMail(){
$mailbox = imap_open("{mysite.com:143/notls}INBOX", "parsethis#mysite.com", "123password"); //connects to mailbox on your server
imap_close($mailbox);
}
and I still get the error when I hit it. Ideas?
SOLVED
It looks like it has something to do with Codeigniter interpreting errors/warnings thrown by the IMAP functions as exceptions.
My solution was to put this after my imap_close() function
imap_errors();
This got rid of the error notice for me.
Here is where i found my solution on the Kohana discussion board
I want to forward my bounced emails to a php script to deal with them. I am using.
#!/usr/bin/php -q
<?php
// read from stdin
$fd = fopen("php://stdin", "r");
$email = "";
while (!feof($fd)) {
$email .= fread($fd, 1024);
}
fclose($fd);
// handle email
$lines = explode("\n", $email);
// empty vars
$from = "";
$subject = "";
$headers = "";
$message = "";
$splittingheaders = true;
for ($i=0; $i < count($lines); $i++) {
if ($splittingheaders) {
// this is a header
$headers .= $lines[$i]."\n";
// look out for special headers
if (preg_match("/^Subject: (.*)/", $lines[$i], $matches)) {
$subject = $matches[1];
}
if (preg_match("/^From: (.*)/", $lines[$i], $matches)) {
$from = $matches[1];
}
} else {
// not a header, but message
$message .= $lines[$i]."\n";
}
if (trim($lines[$i])=="") {
// empty line, header section has ended
$splittingheaders = false;
}
}
?>
Works perfect! But how do I collect the "To" field in the bounced message? I've tried just adding a $to variable but it doesn't work.
Any help would be great,
thanks,
EDIT: Actually I need to get the "TO" field within the body of the message. - The email that it bounced back from. How do I pull apart the body of the message to take specific info? Should I create a special header with the person's email so that it is easier to get this info?
If you can create a custom header, that would be easiest. Otherwise, you need to match against your entire body for a particular pattern; and if your body text can vary, it could be difficult to make sure you are always matching the correct text.
Custom headers should begin with X-, so maybe do something like:
if (preg_match("/^X-Originally-To: (.*)/", $lines[$i], $matches)) {
$originallyto = $matches[1];
}
But with X- headers, they are non-standard, so it is best to pick a name that is either
Commonly used exclusively for the same purpose, or
Not likely to be used by anyone else at all
One other thing you should be aware of; lines in a message should always end in "\r\n", so you might want to split on both characters (instead of just "\n") to ensure more consistent behaviour.
I'm using PHP for sending an e-mail. The values in the e-mail are depending on the inputs of a form. But for some reason, the mail is suddenly not sending. It did before. What's wrong with my code?
Orders are placed correctly in the database, so no error there.
if ($order->addOrder($_DB)) {
$user = "SafetyCam.be";
$verzonden = FALSE;
$firstname = $_POST['firstname'];
$lastname = $_POST['lastname'];
$address = $_POST['address'];
$zip = $_POST['zip'];
$place = $_POST['place'];
$country = $_POST['country'];
$phone = $_POST['phone'];
$email = $_POST['email'];
$twogig = $_POST['vn_qty'];
$fourgig = $_POST['ja_qty'];
$total = $_POST['total'];
$totaal = (($twogig * 50) + ($fourgig *80) + 2.5);
$headers = 'From: info#something.be';
$to = 'me#gmail.com';
$subject = 'Bevestiging bestelling';
$message = 'Hello $firstname,
You placed the following order on our website.
- $twogig x 2GB SafetyCams ordered
- $fourgig x 4GB SafetyCams ordered
+ shippingcosts (2,5 EUR)
The total cost for this order amounts to $totaal EUR.
Your products will be delivered as quickly as possible after receipt of your payment.
Please transfer the order amount of $totaal EUR into account X.
After payment, the products will be sent to the following address:
$firstname $lastname
$address
$zip $place
$country
We hope you will be very happy with your purchase.
Sincerely yours";
if (mail($to, $subject, $message, $headers)) {
$verzonden = TRUE;
$feedback = '<div class="feedbackheader">Thanks</div><br / >';
} else {
$verzonden = FALSE;
$feedback = '<div class="feedbackheader">Error!</div>'; }
}
else {
$feedback = '<div class="feedbackheader">Error!</div>';
}
}
Why do you open your mail $message with a single quote and end it in a double quote.
You should open and end with both double quotes, especially since you use PHP variables inside.
$message = 'Hello $firstname"; //Wrong
$message = "Hello $firstname"; // Works
You've opened the "message" string with an apostrophe ' but tried to close it with a quotation mark ". The SO syntax highlighter gives it away!
You have started your variable $message = 'Hello $firstname, with single quote and end it with double quote, what you need to do is just make
$message = "Hello $firstname
if you put it in single quote php wont scan your variable content for varible like $firstname
Your $message variable starts the string with a ' but ends it with a ", so all the code after it is included in the variable until another ' which happens when your defining $feedback.
Basically you are not closing the string, and therefore your entire code is being changed. If you are using color coding you should have seen this (I can see it from your question).
Also, if you are using single quotes, you cannot use inline variables.
$var = 1;
echo '$var'; // ouput: $var;
echo "$var"; // output: 1
You start your message-string with a single quote (') and try to end it with a double quote, thus your logic is parsed incorrectly.
I use SwiftMailer:
require_once('../lib/swiftMailer/lib/swift_required.php');
function sendEmail(){
//Sendmail
$transport = Swift_SendmailTransport::newInstance('/usr/sbin/sendmail -bs');
//Create the Mailer using your created Transport
$mailer = Swift_Mailer::newInstance($transport);
$body="Dear $fname,\n\nYour job application was successful. \n\nYours,\n\nEamorr\n\n\n\n\n\n\n";
//Create a message
$message = Swift_Message::newInstance('Subject goes here')
->setFrom(array($email => "no-reply#yourdomain.com"))
->setTo(array($email => "$fname $lname"))
->setBody($body);
//Send the message
$result = $mailer->send($message);
}