Php SELECT语句可以';找不到在同一http请求中刚刚插入的记录

Php SELECT语句可以';找不到在同一http请求中刚刚插入的记录,php,mysql,mysqli,Php,Mysql,Mysqli,我有一个简单的类,它有两个方法:add和process require_once('MailQueue.config.php'); require_once('class.phpmailer.subclass.php'); class MailQueue { private $dbServer; private $dbName; private $dbUsername; private $dbPassword; private $mailLimit;

我有一个简单的类,它有两个方法:add和process

require_once('MailQueue.config.php');
require_once('class.phpmailer.subclass.php');

class MailQueue {
    private $dbServer;
    private $dbName;
    private $dbUsername;
    private $dbPassword;
    private $mailLimit;
    private $mailLimitTimeUnit;
    private $db;

    function __construct() {
        global $CONFIG;

        // Set database connection variables
        $this->dbServer = $CONFIG['dbServer'];
        $this->dbName = $CONFIG['dbName'];
        $this->dbUsername = $CONFIG['dbUsername'];
        $this->dbPassword = $CONFIG['dbPassword'];

        // Set app settings
        $this->mailLimit = $CONFIG['mailLimit'];
        $this->mailLimitTimeUnit = $CONFIG['mailLimitTimeUnit'];

        // Connect to database
        $this->db = new mysqli($this->dbServer, $this->dbUsername, $this->dbPassword, $this->dbName);

        if($this->db->connect_error) {
            die("Error connecting to MailQueue.<br />".$this->db->connect_error);
        }
    }

    function add($data) {
        $sqls = "";

        foreach($data as $d) {
            $sqls .= "INSERT INTO mailqueue (".
                        "desiredSendTime, ".
                        "fromName, ".
                        "fromAddress, ".
                        "toName, ".
                        "toAddress, ".
                        "subject, ".
                        "bodyHtml ".
                    ") VALUES (".
                        "'".$d['sendAt']."',".
                        "'".$d['fromName']."',".
                        "'".$d['fromAddress']."',".
                        "'".$d['toName']."',".
                        "'".$d['toAddress']."',".
                        "'".$d['subject']."',".
                        "'".$d['body']."'".
                    ");";
        }

        $insertIds = Array();

        if(!$this->db->multi_query($sqls)){
            die("Error adding emails to mailqueue: (".$this->db->errno.") ".$this->db->error);
        }

        // fetch insert ids
        do {
            $insertIds[] = $this->db->insert_id;
        } while($this->db->more_results() && $this->db->next_result());

        return $insertIds;
    }

    function processQueue($numberOfMessages, $preferredEmailIds="") {
        // Get number of emails already sent in this timeframe

        // Do not check for the last timeUnit, but for the timeUnit we're currently in, e.g.
        // if timeUnit = 'hour', count the processed emails in de current hour, not in the last 60 minutes.
        switch($this->mailLimitTimeUnit) {
            case 'year':
                $startOfCurrentTimeframe = date('Y-01-01 00:00:00');
                break;
            case 'month':
                $startOfCurrentTimeframe = date('Y-m-01 00:00:00');
                break;
            case 'day':
                $startOfCurrentTimeframe = date('Y-m-d 00:00:00');
                break;
            case 'hour':
                $startOfCurrentTimeframe = date('Y-m-d H:00:00');
                break;
            case 'minute':
                $startOfCurrentTimeframe = date('Y-m-d H:i:00');
                break;
            default:
                $startOfCurrentTimeframe = '';
        }

        if($startOfCurrentTimeframe != '') {
            $successCounter = 0;

            $sql =  "SELECT ".
                        "COUNT(*) AS currentCount ".
                    "FROM ".
                        "mailqueue ".
                    "WHERE ".
                        "actualSendTime BETWEEN '".$startOfCurrentTimeframe."' AND NOW()";

            if(!($stmt = $this->db->prepare($sql))) {
                die("Prepare failed: (".$this->db->errno.") ".$this->db->error);
            }

            if(!($stmt->execute())) {
                die("Execute failed: (".$stmt->errno.") ".$stmt->error);
            }

            $result = $stmt->get_result();
            $row = $result->fetch_assoc();
            $currentCount = $row['currentCount'];
            $spaceLeft = $this->mailLimit - $currentCount;

            // Don't exceed the mail limits!
            if($spaceLeft < $numberOfMessages){
                $numberOfMessages = $spaceLeft;
            }

            // In case of preferred emails, add an explicit filter to accomplish this
            if($preferredEmailIds!=""){
                $preferredEmailsOnly = "AND id IN (".implode(',', $preferredEmailIds).") ";
            } else {
                $preferredEmailsOnly = "";
            }

            // Process new emails
            $sql =  "SELECT ".
                        "* ".
                    "FROM ".
                        "mailqueue ".
                    "WHERE ".
                        "desiredSendTime < NOW() ".
                        "AND actualSendTime IS NULL ".
                        $preferredEmailsOnly.
                    "ORDER BY ".
                        "desiredSendTime, ".
                        "id ".
                    "LIMIT ?";

            if(!($stmt = $this->db->prepare($sql))) {
                die("Prepare failed: (".$this->db->errno.") ".$this->db->error);
            }

            if (!$stmt->bind_param("i", $numberOfMessages)){
                die("Binding parameters failed: (".$stmt->errno.") ".$stmt->error);
            }

            if (!$stmt->execute()) {
                die("Execute failed: (".$stmt->errno.") ".$stmt->error);
            }

            $result = $stmt->get_result();

            if($result->num_rows > 0) {
                $successCounter = 0;
                $sqls = "";

                while($row = $result->fetch_assoc()) {
                    $msg = new themedMailer();

                    $msg->From = $row['fromAddress'];
                    $msg->FromName = $row['fromName'];
                    $msg->Subject = $row['subject'];
                    $msg->Body = $row['bodyHtml'];

                    $msg->IsMail();

                    $msg->AddAddress($row['toAddress'], $row['toName']);

                    if($msg->Send()) {
                        $successCounter++;

                        // Save the time of sending to the email in the database
                        $sqls .= "UPDATE mailqueue SET actualSendTime = NOW() WHERE id = ".$row['id'].";";
                    } else {
                        die("Sending mail failed: ".$this->ErrorInfo);
                    }
                }

                // Update the sent emails
                if(!$this->db->multi_query($sqls)){
                    die("Failed updating records for sent emails; these emails will be sent again because of this error.");
                }
            }

            $stmt->close();
        }

        return $successCounter;
    }
}
HTTP请求2:

ERROR_REPORTING(E_ALL);

require_once('../MailQueue.class.php');

$try = 50;

$queue = new MailQueue();

echo "Trying to send ".$try." emails.<br />";

$counter = $queue->processQueue($try);

echo "Sent ".$counter." emails.";

if($counter < $try) {
    echo " Not all desired emails were sent, so the mail limit was probably reached. Please try again later.";
}

有人能解释为什么合并这两个功能不起作用吗?Autocommit为1,我尝试显式提交,但没有效果。

由于脚本中没有错误处理,添加
mysqli_报告(mysqli_report_STRICT | mysqli_report_ALL)时会发生什么数据库操作之前的某个地方?为了简单起见,我省略了错误处理。我既没有收到错误,也没有收到通知。我用
错误报告(E_ALL)处理测试脚本
并在类的顶部添加了建议的代码,但它不会改变输出。“为简单起见,我省略了错误处理。”-所以,这不是真正的代码?那我们怎么知道发生了什么事?对不起,我以为这会让回答更容易。我已经修改了这个问题,添加了类的完整代码。您可能需要检查web服务器和db服务器的时间是否相同。如果它们只差几秒钟,可能会导致你的问题?
ERROR_REPORTING(E_ALL);

require_once('../MailQueue.class.php');

$try = 50;

$queue = new MailQueue();

echo "Trying to send ".$try." emails.<br />";

$counter = $queue->processQueue($try);

echo "Sent ".$counter." emails.";

if($counter < $try) {
    echo " Not all desired emails were sent, so the mail limit was probably reached. Please try again later.";
}
ERROR_REPORTING(E_ALL);

require_once('../MailQueue.class.php');

$queue = new MailQueue();

$currentTime = date('YmdHis');
$try = 50;
$data = Array();

for($i=1; $i<=3; $i++) {
    $data[$i] = Array();
    $data[$i]['sendAt']      = date('Y-m-d H:i:s');
    $data[$i]['fromName']    = 'John Doe '.$i;
    $data[$i]['fromAddress'] = 'john@doe.com';
    $data[$i]['toName']      = 'Jane Doe';
    $data[$i]['toAddress']   = 'jane@doe.com';
    $data[$i]['subject']     = 'Test message MailQueue '.$currentTime;
    $data[$i]['body']        = 'Test message MailQueue '.$currentTime;
}

// Directly process the added messages
echo "Trying to send ".$try." emails.<br />";

$counter = $queue->processQueue($try, $queue->add($data));

echo "Added 3 new emails to be sent. ".$counter." emails were actually sent.";