Php SELECT语句可以';找不到在同一http请求中刚刚插入的记录
我有一个简单的类,它有两个方法:add和processPhp 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;
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.";