I'm cycling through my emails using imap and for some reason (possibly a timeout) it reaches about 130 out of the 170 emails and cuts off.
function pop3_login($hostz,$portz,$userz,$passz,$folderz,$sslz){
$sslz=($sslz==false)?"/novalidate-cert":"";
return (imap_open("{"."$hostz:$portz/pop3$sslz"."}$folderz",$userz,$passz));
}
$msg_int = 1;
$connection = pop3_login("mail.***","110","me#me.com","***","INBOX",false);
$inbox_msg_count = imap_num_msg($connection);
while($msg_int <= $inbox_msg_count) {
echo "$msg_int OF $inbox_msg_count <br>";
$header = imap_header($connection, $msg_int);
$from = $header->reply_to;
$subject = $header->subject;
foreach ($from as $id => $object) {
$fromname = $object->personal;
$fromaddress = $object->mailbox . "#" . $object->host;
$date1 = $header->date;
$date2 = strtotime($date1);
$senddate = date("Y-m-d", $date2);
$emaildatetime = (int)date("U", $date2);
echo "Current email Scanned: ". $fromaddress . "<br>";
}
$msg_int++;
}
imap_expunge($connection);
imap_close($connection);
I was thinking it might be a timeout connection issue because it's actually running fine but just not finishing, so I've set my php.ini timeouts and waits to an absurd amount, along with imap_timeout(1,999) and imap_timeout(2,999) but it's still cutting off short (and not necessarily in the same exact position, but between 128-132ish of 170).
Any thoughts are appreciated. Thanks
Related
It is 1 AM and I am struggling for 3-4 hours to see what's wrong with my script...
My database has ~400 emails. I set $ChunkSize as counter for the loop and also to count which is the next chunk to be processed.
I've set some echo() to debug
echo "This is the " . $GLOBALS["ChunkSize"] . " chunk. <br>";
It should output what chunk is processed at that time.
If I disable mail() then I don't get 503 Service Unavailable but every echo() displays at the same time, not in the order of processing.
I also found out that some emails arrive, but not to everyone. Also, if some emails are sent, that means foreach() should have processed at least one chunk, that means it should display at least one echo().
I've set break 1; so every time it breaks out of foreach() it should display the echo() with the chunk number processed by foreach() but it doesn't.
What I am doing wrong?
$connection = mysql_connect($hostname, $username, $password);
mysql_select_db($dbname, $connection);
$result = mysql_query("SHOW COLUMNS FROM `Emails`");
while($row = mysql_fetch_array($result)){
$Addresses[] = $row['Field'];}
$Subject = "Test";
$Message = "
Test
";
$Headers = array( EMPTY FOR SECURITY REASONS );
$Headers = implode( "\r\n" , $Headers );
$ChunkAddresses = 50;
$EmailChunkArray = array_chunk($Addresses, $ChunkAddresses);
$ArraySize = count ($EmailChunkArray);
$ChunkSize = 0;
ChunkLoop: {
$EmailChunkArrayLoop = $GLOBALS["EmailChunkArray"];
foreach ($EmailChunkArrayLoop[$GLOBALS["ChunkSize"]] as $ToChunkLoop) {
if ($GLOBALS["ChunkSize"] <= $GLOBALS["ArraySize"]) {
mail($ToChunkLoop,$GLOBALS["Subject"],$GLOBALS["Message"],$GLOBALS["Headers"]);
echo "This is the " . $GLOBALS["ChunkSize"] . " chunk. <br>";
} else if ($GLOBALS["ChunkSize"] == $GLOBALS["ArraySize"]){
exit();}
$GLOBALS["ChunkSize"]++;
break 1;}
}
if ($GLOBALS["ChunkSize"] != $GLOBALS["ArraySize"]){
echo "Test. <br>";
goto ChunkLoop;
} else {
echo "Finished! <br>";}
Create script that will only do one thing - send mail.
sendMail.php
<?php
// Get recipient from the argv array
$recipient = $_SERVER['argv'][1];
// Mail args
$subject = 'HELLOOOOOOO';
$message = 'BLablabla';
$headers = [...]; // optional or not
// Send it
mail($recipient, $subject, $message, $headers);
And inside of Your code where You do:
mail($ToChunkLoop,$GLOBALS["Subject"],$GLOBALS["Message"],$GLOBALS["Headers"]);
Replace with:
$recipient = escapeshellarg($ToChunkLoop);
exec("php /path/to/sendMail.php ".$recipient." > /dev/null &"); // that will call mail script and will not wait when execution will end
Feel free to adapt my code examples as You wish
P.S. this solution is for cases when You don't want to pay for normal batch mail sending, mail subscription or dedicated, vps services and have just small web hosting. (:
P.S.. it's not a brilliant solution, but done for requirements provided by question author
I'm trying to make a program that takes e-mails from the post.
Everything is nice, beautiful. Almost..
Unfortunately, the problem is when the mail is "unseen". The script changes its status to "seen".
And I don't want this.
I tried to do that: at the beginning I check that emails are unseen, and at the end I'd like them to restore the status "unseen".
However, I met only with "imap_setflag_full" and it doesn't have that option.
public function pop_mails(){
$message_count = imap_num_msg($this -> _inbox);
$date = date('Y-m-d');
mkdir("./$date", 0777);
for($i=1; $i<=$message_count; $i++){
$overview = imap_fetch_overview($this->_inbox, $i);
$seen = $overview[0] -> seen;
$name = imap_utf8($overview[0]->subject);
$named = strtr($name, ":", ".");
$headers = imap_fetchheader($this->_inbox, $i, FT_PREFETCHTEXT);
$body = imap_body($this->_inbox, $i);
file_put_contents($date.'/'.$named. '.eml', $headers . "\n" . $body);
if($seen =="0") {
imap_setflag_full($this->_inbox, $seen, "\\Seen");
}
}
}
Can you help me?
You just have to clear the \\Seen Flag at the end of your process :
$status = imap_clearflag_full($this->_inbox, "$email_number", " \\Seen");
I am facing a problem with sending bulk emails to all my recipients (approx 10,000) It sends about 600 - 800 mails and then just stops without any reason. I am using a shared server.
Here is My Code.
<?php
#session_start();
if(!isset($_SESSION['uid'])){
echo "<html><head>";
echo "<script language=javascript>function load25(){
alert('........................You Must Login .........................');
window.location='email_login.html';}</script>";
echo "</head><body onload=load25()></body></html>";
die();
}
include "connection.php";
$uid=$_SESSION['uid'];
//var_dump($uid);
require_once('mail.message.php');
require_once('mail.info.php');
$email_id=uniqid();
$m="<html><body>";
$m.= $_POST['content'];
$subject= $_POST['subject'];
$m.="<img src='http://emailpro.in/mail/trackerimage.php?utm_source=gmail&utm_medium=email&utm_content=image&utm_campaign=services&campaignID=1&subscriberID=".$email_id."&subject=".$subject."' border='0' alt='' style='height:1px;width:1px' />";
$to1=$_POST['to'];
$username=$_POST['usid'];
$passwd=$_POST['ppwd'];
$replymailid=$_POST['repmid'];
$campname=$_POST['campname'];
//echo" $replymailid <BR> $campname";
$timezone = new DateTimeZone("Asia/Kolkata" );
$date = new DateTime();
$date->setTimezone($timezone );
$date1= $date->format( 'y/m/d H:i:s');
//echo $date1;
//$datetimee= date('y/m/d - H:i:s') ;
//date('l jS \of F Y h:i:s A');
//echo "Time Is $date ";
function nowhitespace($data)
{
return preg_replace('/\s/', '',$data);
}
$to2=nowhitespace($to1);
$b=rtrim($to2,',');
//Print_r($b);
$s=array();
$s=explode(",","$b");
$n=$_POST['no'];
//echo "The number of emails u have selected is $n<br />";
$s=array();
$s=explode(",","$b");
$s1=implode(",", $s);
$Email = new Email();
$Email->sender = $replymailid;
$Email->recipient=$s1;
$Email->subject =$subject;
$Email->message_text = "Hello!";
$Email->message_html = $m;
// send the email
$Courier = new Courier();
$sent = $Courier->send($Email);
$result=mysql_query("INSERT INTO sentmails VALUES('','$uid','$campname','$subject','$b','$n','$date1')");
/*if(isset($_POST['no'])!=" ")*/
if($n!="")
{
$rec = mysql_query("SELECT * from clientmailid where userid='$uid' limit $n");
$count = mysql_num_rows($rec);
// echo $count;
if($n!=0 && $count!=0 && $n<=$count)
{
// echo $n;
$recipients = mysql_query("SELECT * from clientmailid where userid='$uid' limit $n");
while($row = mysql_fetch_array($recipients))
{
$addresses[]= $row['emailid'];
//echo $addresses;
}
$to = implode(",", $addresses);
// print_r($to);
/* $Tos=array();
$Tos=explode(",","$to");
$Tos1=implode(",", $Tos);
*/ $Email->recipient=$to;
} else
{
echo '<html>';
echo '<head></head>';
echo '<body onload=load30()>';
echo '</body>';
echo'</html>';
echo "**Sorry You Don't have enough Email Credits**";
}
}
if ($sent != Courier::SEND_OK) {
echo "Mailer Error" ;
}
else {
if($n!=0 && $count!=0){
$n=$_POST['no'];
$recipients = mysql_query("SELECT * from clientmailid where userid='$uid' limit $n");
while($row = mysql_fetch_array($recipients))
{
$addresses[]= $row['emailid'];
$mid=$row['mid'];
$result13 = mysql_query("delete FROM clientmailid where mid='$mid' limit $n");
//echo $addresses;
}
}
echo"<script>alert('Thank u for using emailpro Your mails will be processed and will be sent shortly');</script>";
echo '<script> window.location="./dashboard.php";</script>';
}
?>
<script type="text/javascript">
function load30()
{
alert("Sorry u don't have enough email credits");
window.location='./tofill.php';
}
</script>
I know that we can send send unlimited mails through a shared server and I am sure there is something wrong either with my code or something with the server. Please guide me accordingly....
Thanks
I don't think there is anything wrong with your code, not because I can read it (please put clearer code on SO) but that it sends a random amount between 600-800 successfully. The following problems are most likely and one of them or both will solve the problem:
1) One of the potential reasons can be PHP timing out the script. Every script gets to run for a limited amount of time. If your script takes more time than that then PHP will simply kill the script. Typically that should cause an error being reported in the error logs. Check your apache error log messages - they might contain a hint.
Just add ini_set('max_execution_time', 0); in the top of your mailing script to test if this is the problem.
2) Could this be being caused by your local mail server? If you're sending out 10.000 emails in a short space of time, it might be assuming that it's spamming, and stop once you reach a certain amount. Try creating a mailing queue and sending in periodically.
Currently I have an old script that parses emails, as seen here:
// Accessing the mailbox
$mailbox = imap_open("{imap.gmail.com:993/imap/ssl/novalidate-cert}INBOX", $mailbox, $mailboxPassword);
// Retrieving only unread messages
$mail = imap_search($mailbox, 'UNSEEN');
// If no new messages found aborting the script
if(empty($mail)) die('No unread emails found!');
$total_found = 0;
$skipped = 0;
// Now we loop through messages
foreach ($mail as $key => $val) {
// process everything
}
This works fine other than some encoding issues with Russian (Cyrillic) characters and a few other issues. While I could hunt down all these issues individually, it seems like there are already great mail parsing classes out there. I found this, which I'd like to use as it sounds like this gets suggested often.
The example code provided is with the parser is below.
<?php
require_once('MimeMailParser.class.php');
$path = 'path/to/mail.txt';
$Parser = new MimeMailParser();
$Parser->setPath($path);
$to = $Parser->getHeader('to');
$from = $Parser->getHeader('from');
$subject = $Parser->getHeader('subject');
$text = $Parser->getMessageBody('text');
$html = $Parser->getMessageBody('html');
$attachments = $Parser->getAttachments();
?>
However it seems to need a reference to $path which is confusing me as the emails are not stored in a folder, there pulled from IMAP. Would I add $path = $mail; in the foreach block? If not, what format do I supply the email to the parser in? Do I have to use the same script I already have and save it to a folder?
All the emails are being retrieved from Gmail. I used IMAP but could use POP instead if IMAP wont work.
Based on the suggested answer i tried this code but its just looping through x unread emails and displaying blank data for everything, headers and body?
// Accessing the mailbox
$mailbox = imap_open("{imap.gmail.com:993/imap/ssl/novalidate-cert}INBOX", $mailbox, $mailboxPassword);
// Retrieving only unread messages
$mail = imap_search($mailbox, 'UNSEEN');
// If no new messages found aborting the script
if(empty($mail)) die('No unread emails found!');
$total_found = 0;
$skipped = 0;
// Now we loop through messages
foreach ($mail as $email) {
$Parser = new MimeMailParser();
$Parser->setText($mail);
echo "-----------------------------Start Of Email---------------------------------";
echo "<br /><br /><br /><br />";
$to = $Parser->getHeader('to');
echo "To: " . $to . "<br />";
$from = $Parser->getHeader('from');
echo "From: " . $from . "<br />";
$subject = $Parser->getHeader('subject');
echo "Subject: " . $subject . "<br /><br /><br />";
//$text = $Parser->getMessageBody('text');
$html = $Parser->getMessageBody('html');
echo "Body: " . "<br /><br />" . $html . "<br />";
//$attachments = $Parser->getAttachments();
echo "<br /><br /><br /><br />";
echo "-----------------------------End Of Email---------------------------------";
}
That class has another function to set the message content directly. Just call $Parser->setText($mail) where $mail is the message content in your IMAP foreach loop.
I am using the following script to read emails.
<?php
//Fetch users from table
$sql_users=mysql_query("select userName, realpass,userID from users ");
while($row = mysql_fetch_assoc($sql_users)){
$username=$row['userName'].'#example.com'; // Email address is username#domain.com
$password=$row['realpass'];
$hostname = '{example.com:995/pop3/ssl/novalidate-cert}';
$username = $username; $password = $password;
$imap = imap_open($hostname,$username,$password) or die('Cannot connect: ' . imap_last_error());
for ($i = 1; $i <= $message_count; ++$i){
$header = imap_header($imap, $i);
// fetch message body and mark it as read
$body = imap_fetchbody($imap, $i,2,FT_PEEK);
$prettydate = date("jS F Y", $header->udate);
if (isset($header->from[0]->personal)) {
$personal = $header->from[0]->personal;
} else {
$personal = $header->from[0]->mailbox;
}
$subject=$header->Subject;
//display email content
$email = "$personal <{$header->from[0]->mailbox}#{$header->from[0]->host}>";
echo "On $prettydate, $email said \"$body\".\n";
echo '<br><br>';
}
print_r(imap_errors());
imap_close($imap);
}
The problem is the email message returns from extra characters with it which need to be removed. Also I need to mark the emails as read.
Here is a sample message:
"
On 20th March 2013, Joe said "email prayer content.
This =A0is a test email for example.com. It should be converted into
a n= ew prayer request.
Thanks, Joe ". "
In the PHP reference, there is a comment with a similar issue to yours. In that comment he reads the content this way:
$text = trim( utf8_encode( quoted_printable_decode(
imap_fetchbody( $this->inbox, $emailNo, $section ) ) ) );
Try adjusting that example to your code and give it a try.