WhileLoop through a mysql db list - php

Ok so long story short, I have a simple mailto function I want to apply/run for every name on a db list. Since it's not working, I removed all the mail stuff from it and to test to make sure the while loop was working with the db, did this
<?php
$connect2db = mysqli_connect('127.0.0.1','root','pass','dbnamehere');
if(!$connect2db){
die("Sorry but theres a connection to database error" . mysqli_error);
}
$sn_query = "SELECT * FROM email_list";
$sn_queryResult = mysqli_query($connect2db, $sn_query) or die("Sorry but theres a connection to database error" . mysqli_error);
$sn_rowSelect = mysqli_fetch_array($sn_queryResult);
$to = $sn_rowSelect;
?>
<br/><br/>
////lower part on page //////<br/><br/>
<?php
while($sn_rowSelect = mysqli_fetch_array($sn_queryResult) ) {
echo "hello there" . " " . $sn_rowSelect['firstname'] . " <br/>";
}
?>
Now this works, it goess through my db and prints out all my first names from the database list. In my noob brain, id think that if i remove the echo lines, and enter the appropriate mailto information, that it would loop just like before, but send mail to each name. so i did this:
<?php
$sn_query = "SELECT email FROM email_list";
$sn_queryResult = mysqli_query($connect2db, $sn_query) or die("Sorry but theres a connection to database error" . mysqli_error);
$sn_rowSelect = mysqli_fetch_array($sn_queryResult);
$to = implode(",",$sn_rowSelect);
$from = $_POST['sender'];
$subject = $_POST['subj'];
$mssg = $_POST['message'];
$headers = "MIME-Version: 1.0rn";
$headers .= "From: $from\r\n";
$mailstatus = mail($to, $subject, $mssg, $headers);
?>
<br/><br/>
//////////<br/><br/>
<?php
while($sn_rowSelect = mysqli_fetch_array($sn_queryResult) ) {
$mailstatus;
if($mailstatus) {
echo "Success";
}else{
echo "There was a problem sending the mail. Check your code and make sure that the e-mail address $to is valid\n";
}
}
?>
now this emails the first name on my list, but not the rest.
I don't get any errors so not sure what the problem is. I was going to try an if statement with num_rows but somewhere else, on StackOverflow, someone said that didn't help since the while loop took care of it by itself. (I tried it either way and it still emailed only the first name) I'm trying here but to no avail.

You have not called the mail() function inside your loop. You call it once outside. Instead try something like the following.
Assuming you have retrieved the $to address from your database query (like you did with the firstname in testing), pull it from the rowset, and use it in mail():
while($sn_rowSelect = mysqli_fetch_array($sn_queryResult) ) {
// Get the $to address:
$to = $sn_rowSelect['email'];
// Call mail() inside the loop.
$mailstatus = mail($to, $subject, $mssg, $headers);
if($mailstatus) {
echo "Success";
}else{
echo "There was a problem sending the mail. Check your code and make sure that the e-mail address $to is valid\n";
}
}
Note also, that since you call mysql_fetch_array() at the top of your script, your while loop will start with the second row. You should remove the first call to mysql_fetch_array() that occurs before the loop.
$sn_queryResult = mysqli_query($connect2db, $sn_query) or die("Sorry but theres a connection to database error" . mysqli_error);
// Don't want this...
//$sn_rowSelect = mysqli_fetch_array($sn_queryResult);

Related

Foreach function gives 503 Service Unavailable

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

php Mail sending double content

I am working on a massmail script which sends an e-mail to every e-mail id present in a particular database.
But there is some issue.
Like I have following database:
id email link
1 a#bc.com bc.com
2 b#cd.com cd.com
And suppose the mail content is : 'Testing this script'
The scripts sends email to a#bc.com perfectly but second time it sends the email, i.e to b#cd.com the content gets doubled.
I mean the second recipient receives an e-mail like this :
Testing this script
Testing this script
The third recipient receives an e-mail with the content repeat three times and the fourth one receives it with four times and so on.
The script grabs e-mail addresses from the email field in the database and sends e-mail to them.
My Code:
<?
include "header.php";
include "config2.php";
$subject="Massmail";
$headers .= "Content-type:text/html;charset=iso-8859-1" . "\r\n";
mysql_connect($server, $db_user, $db_pass)
or die ("Database CONNECT Error");
$resultquery = mysql_db_query($database, "select * from $table");
while ($query = mysql_fetch_array($resultquery))
{
$mailto=$query[$table_email];
$domain=$query[$table_link];
$domain2 = str_replace(array('http://','HTTP://','Http://'), '',$domain);
$handle = fopen("http://$domain2","r") or die("Unable to open link ( $domain ). <a href='javascript:history.go(-1);'>Go back</a> and please try again ");
$contents = '';
while (!feof($handle)) {
$contents .= fread($handle, 8192);
$contents = str_replace('window.location = "/abc.html"','window.location = ""',$contents);
$contents = mb_convert_encoding($contents, "HTML-ENTITIES", "auto");
}
$i = md5(uniqid(rand(), true)) . '.' . html;
$fh = fopen("/home/host/public_html/content/$i", "w");
fwrite($fh, $contents);
fclose($fh);
$filename = '/files/$i';
$message1 .= "Testing Mail Script Version 2";
mail($mailto, $subject, $message1, $headers, "-f" . 'noreply#domain.com');
echo 'Mail sent to '.$mailto.'<br>';
sleep($seconds);
}
include "footer.php";
?>
I have tried to echo the mail that has to be sent and I get this:
To: a#bc.com
Subject: Massmail
Message:
Testing mail script
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
to: b#cd.com
Subject: Massmail
Message:
Testing mail scriptTesting mail script
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Your help will be greatly appreciated. Thanks in advance
In the code line: $message1 .= "Testing Mail Script Version 2"; the period is a concatenate, so each time you loop it, you duplicate the message another time.
Agreed. Sounds like your loop is not functioning correctly? If you can't post the full code, try to post an abstraction for us to diagnose your issue.
If you cant, I would look into looping based on the number of email address you have, not some arbitrary counter. That might help you out.
Suppose this is your table. With id, email, link, message structured as:
id email message
1 a#test.com hello, how are you doing..
2 b#test.com hey, dude this is me..
3 c#test.com we are sending you this...
Now, let's assume you have 100 records. What I would do is (assuming $result is a mysql array returning all the results from mysql ex SELECT * FROM mail...)
I would try:
for($i=0; $i <= count($result); $i++){
$send = mail($result['to'], $result['subject'],
$result['message'], $result['headers']);
if(!$send){
echo 'e-mail, sending has stopped';
break;
}
else{
echo 'all e-mails are sent successfully'; }
}
Never mind, I fixed it. #Pirion's post helped me. I changed
$message1 .= "Testing Mail Script Version 2";
to
$message = "Testing Mail Script Version 2";
And everything worked perfectly. Thank You So Much Guys For Helping Me Out.

storing variables within foreach loop

Hi I currently have some PHP code which will put previously selected timeslots from checkboxes on a previous page into my database, but I'm not sure how to store each one in a variable before I do this, so that I can use them to list the appointment slot's in my e-mail function
At the moment when I try to insert '$key' to my e-mail function it only retains the last selected value...
My code on the first page reads:
<?php
for ($i=0;$i<=31;$i++){ while ($myrow = mysql_fetch_row($result)) {
printf("<tr><td>%s</td><td>%s</td></tr>\n",
$myrow[0]);
}
echo "<td><input type='checkbox' name='$displayTime2' onclick='KeepCount()'></td>";
echo "<td>$pagetime</td>"; ?>
My code at the moment is as follows:
<?php
foreach ($_POST as $key=>$value)
{
echo $key; // show times selected on previous page
mysql_query("INSERT INTO appointment(Patient_ID, Appointment_Date, Appointment_Time
, Practice_ID, Appointment_ID)
VALUES('$patid','$insertdate','$key','$pracid','$apptype')");
}
?>
my mail function is as follows:
$to = "$pemail";
$subject = "Talking Teeth Check Up Booking Confrmation";
$message = "Hello! This e-mail is to confirm your ".$appname." appointment has been
booked for ".$insertdate. " at ".$key." at the ".$pracname." practice";
$from = "talkingteethdentists#talkingteeth.co.uk";
$headers = "From:" . $from;
mail($to,$subject,$message,$headers);
echo "Mail Sent.";
Although the comments above are right, let me help you out.
First off, you need to figure out which checkboxes were selected, so do some IF statements to figure that out on each of these inside of your foreach loop.
Try something like this:
<?php
$savedData = array();
foreach ($_POST as $key=>$value){
$key = mysql_real_escape_string($key);
echo($key. "<br>"); // show times selected on previous page
mysql_query("INSERT INTO appointment(Patient_ID, Appointment_Date, Appointment_Time
, Practice_ID, Appointment_ID)
VALUES('$patid','$insertdate','$key','$pracid','$apptype')");
//To save the variables for later:
$savedData[] = $key;
}
?>
And now you can access all of our KEYs with $savedData[0] .... $savedData[1] ... $savedData[2] .... etc....
So your email function might look like:
foreach($savedData as $time){
$to = "$pemail";
$subject = "Talking Teeth Check Up Booking Confirmation"; //mis-spelled confirmation =)
$message = "Hello! This e-mail is to confirm your ".$appname." appointment has been
booked for ".$insertdate. " at ".$time." at the ".$pracname." practice";
$from = "talkingteethdentists#talkingteeth.co.uk";
$headers = "From:" . $from;
mail($to,$subject,$message,$headers);
echo "Mail Sent.";
}
So this will send out an email for each piece inside $savedData - if that truly is the intent.

How Would I Return Two Multiple Select Values In HTML?

I have a mysql database table called "leads" with an id column, a name column, and an email column. I currently have users selecting a lead from a multiple select box, which is returned as an array from an html form with $_POST method. I have the value for the select box items as the email column, and what is shown to the user on the front end is the name column. However, I want to be able to return two values, the email and the name, for later use. I need to have the email value(s) able to be imploded with commas between them, so I can later send them emails using PHP's mail function. However, when a user looks at sent emails, I want to show them the name value(s). I have read that I can either parse the array, or use the id column set as the value, which seems more practical, however, I am not sure how I would go about this. Any ideas? Thanks in advance for any help!
*UPDATE*
Basically, the users that log into the site have their own leads in a mysql database. I need them to be able to go to a 'send email' page, where they can select a lead, or multiple leads, by name. Then there is a subject field, and a message field so they can write the email, and then I have a 'send email' form submit button. After they click 'send email' I want to get back the email addresses and names of the leads they selected, for later use. I need to have the email addresses separated by commas, so that I can send them through a php mail function... But the important thing is, I want the info from the form to be stored in a database table called 'PendingEmails', and I am going to run a cron job to run a script that finds what emails need to be sent, and sends them... After an email is sent, I need to put the names, subject, and message from the email in a separate database, called 'SentEmails'. On a different page on the site, I want the users to be able to see all the emails they sent, but I want them to see the names of who they sent it to, rather than the email addresses. This is why I need both the names and the emails. I need emails for the mail function, and names to be displayed back to the user. I like your idea of using the id and running the rest server side, I just dont know how I would do this. Hope this helped.
Here is the select box:
<select data-placeholder="Select Lead(s) To Email..." multiple="true" class="chzn-container-multi" name="selectleads[]"style="width:505px;">
<?php
do {
?>
<option value="<?php echo $row_rsAllLeads['Email']?>"><?php echo $row_rsAllLeads['FullName']?></option>
<?php
} while ($row_rsAllLeads = mysql_fetch_assoc($rsAllLeads));
$rows = mysql_num_rows($rsAllLeads);
if($rows > 0) {
mysql_data_seek($rsAllLeads, 0);
$row_rsAllLeads = mysql_fetch_assoc($rsAllLeads);
}
?>
</select>
And here is the actual form action:
$editFormAction = $_SERVER['PHP_SELF'];
if (isset($_SERVER['QUERY_STRING'])) {
$editFormAction .= "?" . htmlentities($_SERVER['QUERY_STRING']);
}
if ((isset($_POST["MM_insert"])) && ($_POST["MM_insert"] == "form")) {
$startcode = $_POST['messagefield'];
$replaced = preg_replace( '/\\\\(?="|\')/', '', $startcode );
$selected = $_POST['selectleads'];
$collectedleads = implode(", ", $_POST['selectleads']);
$to = $collectedleads;
$subject = $_POST['subjectfield'];
$body = $replaced;
$headers = "MIME-Version: 1.0\r\n";
$headers .= "Content-type: text/html; charset=iso-8859-1\r\n";
$headers .= "From: " . $row_rs_CurrentUser['FirstName'] . " " . $row_rs_CurrentUser['LastName'] . " <" . $row_rs_CurrentUser['Email'] . ">";
if (mail($to, $subject, $body, $headers)) {
} else {
echo("<p>Message delivery failed...</p>");
}
}
The code you gave me and I tried (and failed) to edit and make work:
$editFormAction = $_SERVER['PHP_SELF'];
if (isset($_SERVER['QUERY_STRING'])) {
$editFormAction .= "?" . htmlentities($_SERVER['QUERY_STRING']);
}
if ((isset($_POST["MM_insert"])) && ($_POST["MM_insert"] == "form")) {
$startcode = $_POST['messagefield'];
$replaced = preg_replace( '/\\\\(?="|\')/', '', $startcode );
mysql_select_db($database_myBackOfficeConn, $myBackOfficeConn);
$collectedleads = implode(", ", $_POST['selectleads']);
//arrays to store email addresses and names
$emails = array();
$names = array();
foreach ($collectedleads as $id) {
mysql_query("SELECT Email, FullName FROM Leads
WHERE Id = " . mysql_real_escape_string($id));
while ($row = mysql_fetch_assoc()) {
$emails[] = $row['Email'];
$names[] = $row['FullName'];
}
}
$to = $collectedleads;
$subject = $_POST['subjectfield'];
$body = $replaced;
$headers = "MIME-Version: 1.0\r\n";
$headers .= "Content-type: text/html; charset=iso-8859-1\r\n";
$headers .= "From: " . $row_rs_CurrentUser['FirstName'] . " " . $row_rs_CurrentUser['LastName'] . " <" . $row_rs_CurrentUser['Email'] . ">";
if (mail($to, $subject, $body, $headers)) {
} else {
echo("<p>Message delivery failed...</p>");
}
}
?>
I think it would make more sense to do the retrieving of data on the server-side. Instead of the email addresses, set the <option> values to your database's id column values.
EDIT: Changed most of the answer after discussing with OP
Bearing in mind that the code you posted was just a snippet, and so I have no way of testing this, you could try something along these lines:
<select data-placeholder="Select Lead(s) To Email..." multiple="true"
class="chzn-container-multi" name="selectleads[]"style="width:505px;">
<?php
/* I think while is better, in case there are no results.
do...while would attempt to echo the first result in a set even
if there were no results, which would give an error, methinks. */
//Use the id field of your database when you populate the select
while ($row_rsAllLeads = mysql_fetch_assoc($rsAllLeads)) { ?>
<option value="<?php echo $row_rsAllLeads['id']?>">
<?php echo $row_rsAllLeads['FullName']?></option>
<?php
}
/* What is this block used for? */
$rows = mysql_num_rows($rsAllLeads);
if($rows > 0) {
mysql_data_seek($rsAllLeads, 0);
$row_rsAllLeads = mysql_fetch_assoc($rsAllLeads);
}
?>
</select>
I'm uncertain as to the purpose of the code block at the end so I just left it. I assume you do something else with that data...?
So now your <select> is exactly the same as before, but instead of actual email addresses it will hand back the corresponding database ids instead.
Now, on submitting the data, we change our tack slightly:
<?php
$editFormAction = $_SERVER['PHP_SELF'];
if (isset($_SERVER['QUERY_STRING'])) {
$editFormAction .= "?" . htmlentities($_SERVER['QUERY_STRING']);
}
if ((isset($_POST["MM_insert"])) && ($_POST["MM_insert"] == "form")) {
$startcode = $_POST['messagefield'];
$replaced = preg_replace( '/\\\\(?="|\')/', '', $startcode );
$selected = $_POST['selectleads'];
/* NEW CODE */
/*selectleads[] is now an array of your database's ids.
You can now run a query to get whatever information you
need. In this case, you want the email addresses, so:
*/
$collectedleads = $_POST['selectleads'];
$emailaddylist = array();
foreach ($collectedleads as $id) {
$x = mysql_query("SELECT `Email` FROM `leads` WHERE `id` = " .
mysql_real_escape_string($id));
$x_assoc = $x->fetch_assoc();
$emailaddylist[] = $x['Email'];
}
/*Now you have an array of email addresses that correspond to
the ids you were sent via $_POST.
*/
$emailaddystring = implode(", ", $emailaddylist);
$to = $emailaddystring;
/*If you want to use any other data from the database,
you still have an array of ids in $collectedleads.
Just run another query to get the data you want.*/
/* END OF NEW CODE */
$subject = $_POST['subjectfield'];
$body = $replaced;
$headers = "MIME-Version: 1.0\r\n";
$headers .= "Content-type: text/html; charset=iso-8859-1\r\n";
$headers .= "From: " . $row_rs_CurrentUser['FirstName'] . " " . $row_rs_CurrentUser['LastName'] . " <" . $row_rs_CurrentUser['Email'] . ">";
if (mail($to, $subject, $body, $headers)) {
} else {
echo("<p>Message delivery failed...</p>");
}
}
?>
Because we are handed the ids in an array, we can use them to get whatever information we want from the database. In this case we're just getting the email addresses. If you want to retrieve any other information, you can use the same technique - the list of ids still exists in $collectedleads, so you can run another query to get whatever data you need.
After an email is sent, I need to put the names, subject, and message
from the email in a separate database, called 'SentEmails'
In that case, use the id data in $collectedleads to run a SELECT query on leads to get the information you need (name, email address, whatever), and run an INSERT query on the SentEmails table to copy that information.
Hope this helps.
CAVEAT:
The use of mysql is discouraged in favour of mysqli. To quote the page:
If you are using MySQL versions 4.1.3 or later it is strongly
recommended that you use the mysqli extension instead.
It works almost exactly the same; in most cases all you need to do is to put the i in front of it. Some functions don't work with it, or have better alternatives. You should check it out.
What I would do, I would add a hidden field named something along the lines of "lead_name" and fill it with jQuery or just plain JS on an onblur event with the value of the selected lead.
$("#lead_name").val($("#lead option:selected").text());

send email to multiple recepients

I'm trying to send an e-mail to multiple e-mail address in my database. Here is my current code. It is only working when I specify a single e-mail address, however, I need to have them query my database and send the e-mail to each e-mail address. Where am I going wrong here?
$elist = $database->getRows("SELECT * FROM `emails`");
if ($elist) {
foreach ($elist as $elist_result) {
$frm = 'rdsyh#gmail.com';
$sub = 'Weekly Work Report';
ob_start(); // start output buffering
include_once('mail_content.php');
$mail_body = ob_get_contents(); // get the contents from the buffer
ob_end_clean();
$to = $elist_result['email'];
$mailstatus = l_mail('', '', $to, $elist_result['firstname'] . ' ' . $elist_result['lastname'], $frm, 'HR', $sub, $mail_body);
}
}
if ($mailstatus == 'ok') {
echo '<center><font color=red style="font-size:14px">Message has been sent Succesfully.....!</font></center><br>';
} else {
echo $mailstatus;
}
Well, there's a lot of abstraction here that we know nothing about from your code. Things to check:
Are you certain that your database query is returning all of the results you're looking for (is $elist populated properly)?
Are you certain that the query is returning data in the format that you're trying to access it in (is $to populated properly)?
Are you certain your l_mail() function is behaving (is it possible it exit's or otherwise terminates script execution in the middle of the first pass)?
Based on what I see here, if everything else was working properly, you should successfully be sending a bunch of emails, one to each email in your list.
Now, if instead you're trying to send a single email that is sent to all of the addresses at once, then you need to group the email addresses in the for loop and then run your mail function afterwards:
<?
$tos = array();
foreach ($elist as $elist_result) {
$tos[] = $elist_result['email'];
}
$frm = 'rdsyh#gmail.com';
$sub = 'Weekly Work Report';
ob_start(); // start output buffering
include_once('mail_content.php');
$mail_body = ob_get_contents(); // get the contents from the buffer
ob_end_clean();
$to = implode(', ', $tos);
$mailstatus = l_mail('', '', $to, $elist_result['firstname'] . ' ' . $elist_result['lastname'], $frm, 'HR', $sub, $mail_body);
?>
What does l_mail() do? If its a web service, then it might have limit for mass emails.

Categories