简体   繁体   中英

How can I run while loop inside other while loop in PHP?

I'm trying to make PHP code which will automatically send email every night to all customers which have email send activated in MySQL. Email will contain PDF file which will have delivery data from MySQL.

I have sorted out how to send mail every night and how to create PDF from MySQL data. Problem is when I run script it will only send email to first customer which have email send activated (sendEmail = 1). So it seems that PHP is running first while loop only once. There is second while loop when data is collected from MySQL to PDF file. But it seems that PHP will also stop first loop after second loop has been ran.

Here is while loops. I have took away all PDF file creator and email code:

// Check if Email is activated
try {
  $resultsCustomerEmail = $db->query("
            SELECT id, name, email
            FROM customer
            WHERE sendEmail = 1
            ");
} catch (Exception $e) {
  echo "Data could not be retrieved from the database - customer table";
  exit;
}

while ($tempDBCustomerEmail = $resultsCustomerEmail->fetch(PDO::FETCH_ASSOC)) {

  $startdate = date('Y-m-d');
  $enddate = date('Y-m-d');

  try {
    $results = $db->query("
              SELECT delivery.id, date_format(delivery.timestamp,'%d.%m.%Y %H:%i:%s') as timestamp
              FROM delivery
              WHERE delivery.customer = " . $tempDBCustomerEmail['id'] . " AND
                date(delivery.timestamp) BETWEEN '" . $startdate . "' AND '" . $enddate . "'
              ORDER BY delivery.id ASC
              ");
  } catch (Exception $e) {
    echo "Data could not be retrieved from the database";
    exit;
  }

  // Data
  while ($tempDB = $results->fetch(PDO::FETCH_ASSOC)) {
    $timestamp = $tempDB['timestamp'];
    $deliveryId = $tempDB['id'];

  }
}

?>

Does anyone have any suggestions what I should change so that first while loop is ran as many times as first MySQL query is true. Thanks!

One loop

Well the good news is that you don't need two loops here

SELECT customer.id, customer.name, customer.email,
  delivery.id, date_format(delivery.timestamp,'%d.%m.%Y %H:%i:%s') as timestamp
          FROM delivery INNER JOIN customer ON
          delivery.customer = customer.customer

          WHERE  AND
            date(delivery.timestamp) BETWEEN :strt AND :end
            AND customer.id = :id
          ORDER BY delivery.id ASC

This join will get you the results in one query with just one loop and probably save your database from getting hit with a large number of queries and bringing it it's knees.

Prepared statement

The server can be brought to it's knees in another way, by SQL injection which your code currently allows. That's why I have re written it to use place holders. Now you need to prepare it and then execute it by passing parameters

$stmt = $db->prepare($sql);
$stmt->execute( array("id"=>$customer_id, "strt"=>$startdate, "end"=>$enddate));

Normalize

Not quite sure why you are storing customer which I assume to be customer name or customer email in the product table. You should be saving the customer id here to avoid redundancy and possibly faster queries.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM