I'm trying to parse an email that is partially written in English and partially written in Japanese using PHP. Here's the code I have so far:
if ($mbox = imap_open($mailbox, $username, $password)) {
$inbox = imap_check($mbox);
$total = (int) $inbox->Nmsgs;
$min = max(1, $total - 10);
// fetch 10 most recent emails
if ($total > 0 && ($emails = imap_fetch_overview($mbox, "{$min}:{$total}"))) {
foreach ($emails as $email) {
$body = imap_body($mbox, $email->uid, FT_UID);
// for testing purposes
echo $body;
// parsing logic here
}
}
}
So as you can see I'm just echoing out the plaintext body of the email, just to test things, and here's part of the echoed response I get when I run this script:
Your Japanese word of the day is: ç”·ã®å
However, the following is what I should see in place of that, based on what's actually in the email:
Your Japanese word of the day is: 男の子
So clearly something's being lost in translation (pun intended). I'm using some simple string manipulation to try and parse the Japanese characters, and then insert them into a MySQL database. However, it's currently inserting those gobbledygook characters instead. What am I missing?
Edit: I'm using PHP version 5.4.45
So I'm not really sure how to get this working in PHP 5. I decided to try upgrading my server to PHP 7 and suddenly all of the code just started working.
Related
I have a PhpMailer working code as follow: (short version)
(the variable already defined before hand)
// Sender and recipient settings
$mail->setFrom($pengirim_email, $pengirim_nama);
$mail->addAddress($untuk_email, $untuk_nama);
$mail->addReplyTo($pengirim_email, $pengirim_nama);
Next, I add multiple email address for CC mail:
$mail-->addCC('aaa#gmail.com','Abdul');
$mail-->addCC('bbb#gmail.com','Borat');
It work as expected.
Now since I'm planning that the email address will come from the SQL query, so for the time being I want to know how do I have to fill the SQL 'CarbonCopy' column table with multiple email addresses - by trying to make a "hardcoded" variable value. So I try like this as the replacement for the addCC above:
$tembusan="'aaa#gmail.com','Abdul';'bbb#gmail.com','Borat'"; //not working
$CC = explode(';', $tembusan); //not working
for ($i = 0; $i < count($CC); $i++) {$mail->addCC($CC[$i]);} //not working
But it throw me an error like this :
Error in sending email. Mailer Error: Invalid address: (cc):
'aaa#gmail.com','Abdul'
So I change the $tembusan into like this:
$tembusan="aaa#gmail.com,Abdul;bbb#gmail.com,Borat"; //not working
It gives me almost the same like the error before:
Error in sending email. Mailer Error: Invalid address: (cc):
aaa#gmail.com,Abdul
Next, I try also this kind of code :
$tembusan="'aaa#gmail.com','Abdul';'bbb#gmail.com','Borat'"; //not working
$CC = explode(';', $tembusan); //not working
foreach($CC as $CCemail){$mail->AddCC($CCemail;} //not working
And it also throw the same error:
Error in sending email. Mailer Error: Invalid address: (cc):
'aaa#gmail.com','Abdul'
If I echo the last code like this foreach($CC as $CCemail){echo $CCemail. '<br/>';}, it give me a result like this :
'aaa#gmail.com','Abdul'
'bbb#gmail.com','Borat'
In my real code, I have a valid email address. The email address in the code above is just for an example.
Where did I do wrong ?
PS
btw, if I remove the "name" for the email address:
$tembusan="aaa#gmail.com;bbb#gmail.com"; //working
$CC = explode(';', $tembusan); //working
foreach($CC as $CCemail){$mail->AddCC($CCemail;} //working
it runs as expected (but in the gmail, the CC name is aaa and bbb).
Please do a further explode . try
$tembusan="aaa#gmail.com,Abdul;bbb#gmail.com,Borat";
$CC = explode(';', $tembusan);
for ($i = 0; $i < count($CC); $i++) {
$DD = explode(',', $CC[$i]);
$mail->addCC($DD[0], $DD[1]);
}
Please note that I have removed the ' characters . (you may use str_replace of PHP to eliminate these characters)
I'm trying to write a PHP program that uses the IMAP PHP extension to run through a very large inbox (greater than 70,000 emails), and move all emails that fall within a specified date range into a folder. I keep running into problems trying to get the mail that falls within the desired range.
First I tried using the SINCE and BEFORE criteria in imap_search() to place all of the desired ID numbers into an array, and then created a string listing these ID numbers to feed into imap_mail_move(). But the problem I keep running into is that imap_search() never actually returns all of the emails within the specified range. For instance, I ran the following code:
echo "Beginning search. \n";
$mail = imap_search($this->mbox,
'SINCE "$startDate" BEFORE "$endDate"');
echo "Search complete. \n";
if (!$mail){echo "The inbox is empty. \n"; die();}
$count = 0;
foreach($mail as $i)
{
$count = $count + 1;
}
echo "Found $count emails. \n";
while specifying a date range that I know to hold 600ish emails, and imap_search() only listed 259 of them. When I expanded the range to encompass the entire inbox of about 75,000 emails, imap_search() only returned 25,112 of them.
When this didn't work, I tried a different, slower way to get all emails within the desired date range. I used imap_search() to collect ALL emails in the inbox, then I iterated through each email, compared the date contained in the emails header to the dates definining my interval, and added the ID to a string if it was in range. I ran the following code:
// Get all mail in the INBOX
$mail = imap_search($this->mbox, "ALL");
if (!$mail){echo "The inbox is empty. \n"; die();}
// Create a string list of all message IDs
//that fall in the specified range
$processed = 0;
$IDsequence = '';
foreach($mail as $messageID)
{
$date = imap_headerinfo($this->mbox, $messageID)->date;
try {$dateObject = new DateTime($date);}
catch (Exception $e) {echo $e->getMessage(); echo "\n";}
$dateObject->setTimezone($TimeZone);
if ($dateObject <= $IntervalEndDate && $dateObject >=
$IntervalStartDate)
{
$IDsequence = $IDsequence . "," . strval($messageID);
}
$processed = $processed + 1;
if ($processed % 100 == 0)
{ echo "Processed $processed emails. \n"; }
}
// If we got at least one message, cut off the first comma.
if (strlen($IDsequence) > 1){
$IDsequence = substr($IDsequence, 1, strlen($IDsequence)-1);
}
else
{
echo "No e-mail to move. \n";
die();
}
echo "Beginning copy. \n";
imap_mail_copy($this->mbox, $IDsequence, $TargetFolder);
echo "Copy complete. \n";
//imap_expunge($this->mbox);
imap_close($this->mbox);
After iterating through just over 25,000 emails, it began to print the error message 'object does not exist' referencing the line of code where I collect the date from the email header. I notice here that the breakdown still occurs somewhere around 25,000 emails, so perhaps both methods break for the same reason. I suspect that I am doing something wrong with the message IDs (for instance, I am assuming that the message IDs for the 75,000 emails are '1' through '75,000').
What is going wrong? Is there a way to collect a large number of emails that fall within a date range and move them?
Perhaps there are only 25,112 messages in the mailbox, and the other ~50,000 are in another mailbox. I know GMail, for example, may report a rough total for the Inbox, but a good percentage of those messages are actually archived.
You might want to do a sanity check at this point. :)
I am pulling down an email which has english, chinese and japanese in the email.
I was using PHP/EZComponents to do this, but a certain japanese char was just not coming through so I am switching to php imap_* funcs to see if they will work.
This is what I have below, and the output I am getting. I need to decode this somehow... I know this has been well (read:overly/chaotically) documented all over the web, but I dont have time to earn a PHD in this right now. Any help is greatly appreciated.
$hn='{imap.gmail.com:993/imap/ssl}INBOX';
$inbox = imap_open($hn,$username,$password,CL_EXPUNGE);
foreach($emails as $email_number) {
$ov = imap_fetch_overview($inbox,$email_number,0);
$msg = imap_fetchbody($inbox,$email_number,2);
var_dump($msg);
// doesnt work... .. but right idea?
// var_dump( utf8_decode($msg) );
}
PARTIAL OUTPUT:
<font face=3D"Arial"><span lang=3D"EN-US" style=3D"font-size:10.5pt"><br></=
span></font><font color=3D"navy" face=3D"MS Gothic"><span lang=3D"JA" style=
=3D"font-size:10.5pt">=CC=EC=9A=DD=A4=AC=A4=A4=A4=A4=A4=AB=A4=E9=A1=A2</spa=
n></font></p><p style=3D"margin-right:0pt;margin-bottom:12pt;margin-left:0p=
t">
<font color=3D"navy" face=3D"MS Gothic"><span lang=3D"JA" style=3D"font-siz=
e:10.5pt"><br></span></font></p><p style=3D"margin-right:0pt;margin-bottom:=
12pt;margin-left:0pt"><font color=3D"navy" face=3D"MS Gothic"><span lang=3D=
"JA" style=3D"font-size:10.5pt">xxend</span></font></p>
I also met this problem employed imap_fetchbody function to get the mail body.
I found that the string get from imap_fetchbody was converted to quoted-printable string automatically.
I resolved this issue by using imap_qprint function to convert the fetched string body into correct one.
I trying to send SMS via RoutoMessaging PHP API. I readed all documentation and examples what i was able to find.
They have PHP example script for sending SMS in unicode format:
<?php
// include RoutoSMS class
include("RoutoTelecomSMS.php");
// creating object
$sms = new RoutoTelecomSMS;
// setting login parameters
$sms->SetUssms->SetOwnNum("44792838383838");
$sms->SetType("unicode");
// get values entered from FORM
$sms->SetNumber($number);
$message="04220432043E04580435002004370435043B0435043D04350020043E0
44704380020044104430020043C04380020043F0430043C043504420020043F043E
043C044304420438043B0435002E002E002E";
$sms->SetMessage($message);
// send SMS and print result
$smsresult = $sms->Send();
print $smsresult;
?>
What i not understand is how i can transform text from submited string to this code needed for including in $message.
Can anyone suggest function to convert text for $message please?
I currently work with PHP version 5.3.3.
The message you are sending is a Cryllic text. It's probably in Serbian. It reads as "Твоје зелене очи су ми памет помутиле..."
Decoding
header('Content-Type: text/html; charset=utf-8');
$str = "04220432043E04580435002004370435043B0435043D04350020043E044704380020044104430020043C04380020043F0430043C043504420020043F043E043C044304420438043B0435002E002E002E";
foreach(str_split($str, 4) as $char) echo "&#x{$char};";
And this is how you would encode the message
$string = "Твоје зелене очи су ми памет помутиле...";
$string = mb_convert_encoding($string, 'UCS-2', 'utf8');
for($i =0; $i < strlen($string); $i++)
echo strtoupper(bin2hex($string[$i]));
I have the following problem. I have a script that gets the Airdate of TV Shows and i alter it before I save it to my database. Locally on my localhost it works perfect, but when I tried it online and uploaded it to my web server it shows a different behavior. I have no idea why it is so.
Here are some examples:
The Data I get: Aired 1/22/12
What the outcome of my script should be: 2012-01-22
What I get online: 2022/12--
The Data I get: Aired 8/29/11
What the outcome of my script should be: 2011-08-29
What I get online: 2029/11--
The Data I get: Airs 2/12/12
What the outcome of my script should be: 2012-02-12
What I get online: 2012/12--
Here is my PHP script:
if(strstr($serie['airdate'], 'Airs')) {
$date = substr($serie['airdate'], 5);
}
if(strstr($serie['airdate'], 'Aired')) {
$date = substr($serie['airdate'], 6);
}
$mm = strstr($date, "/", true);
$mmStrLen = strlen($mm);
if((strlen($mm)) == "1") {
$mm = "0".$mm;
}
$dd = substr($date, $mmStrLen+1);
$dd = strstr($dd, "/", true);
$ddStrLen = strlen($dd);
if((strlen($dd)) == "1") {
$dd = "0".$dd;
}
$yy = substr($date, $mmStrLen+1+$ddStrLen+1);
if((strlen($yy)) == "1") {
$yy = "0".$yy;
}
$serie['date'] = "20".$yy."-".$mm."-".$dd;
$serie['airdate'] is the data I get and $serie['date'] is where the altered value should be saved.
The PHP Version I use locally is 5.3.8 and the one of my webhoster is 5.2.17. But I guess this is not the root of the problem.
Can't format a comment as code, so I must write it as an answer.
Please try this on both sides
$x=explode(' ',$serie['airdate']);
if (sizeof($x)!=2) die("Error in step 1");
$x=explode('/',$x[1]);
if (sizeof($x)!=3) die("Error in step 2");
$serie['date']=sprintf("20%02d-%02d-%02d",$x[2],$x[0],$x[1]);
Take a look at the raw date string you are splitting locally vs at the server. I'm willing to bet that the OS date format is different locally than on the server, and your string splitting code is not designed to handle the different format the server is using.
Thats an awful lot of code to handle dates. Have tried using the strtotime() function? You can pair it with the date() function to easily reformat dates in PHP.