在PHP中循环数组以更新MySQL中的记录,但不会得到所有结果
我正试图遍历存储在数组中的一些数据,然后更新MySQL中整整一个月的记录。我可以检索一天的正确数据,但不能检索整个月的数据 我有一个带有日历的表单,用户可以在其中选择日期。目前,我对它进行了编码,以便用户可以选择任何日期(月、日、年),并确定该月的日期(我相信有一种更有效的方法来实现这一点)。例如,如果选择2019年1月18日,则返回31天(因为1月份有31天) 但实际情况是,所选日期的数据仅插入表中1月1日的数据(例如,如果我从日历中选择2019年1月18日,则插入2019年1月18日的数据,但插入2019年1月1日的数据。不插入其他数据)。我需要做的是将整个月的数据(直到当天为止存在的任何数据)插入到当月的正确日期中。如果我更改从日历中选择的日期,则会插入该日期的数据,但同样会插入1月1日的数据 我需要能够循环通过一个月的几天,获得所有有数据的站点(这是有效的),然后获得每个站点在一个月的每一天的数据(这是有效的每一天,但我需要一次整个月) importDate是日历中选择的日期。如果我回显,它将返回我选择的日期 这就是我如何确定是否设置了importDate以及如果设置了importDate或未设置importDate该怎么办,以及获取所选月份的天数(例如,选择2019年1月18日返回1月31天) 然后我循环浏览一个月中的几天(可能没有在正确的地方这样做),然后循环浏览我的站点。所有站点都将返回。getSites是一个获取所有站点的函数 在获取站点的循环中,我为我们正在使用的软件连接到一个单独的数据库,从每个站点的数据库中获取数据,进行一些计算,然后移动到下一个站点 然后,我调用一个函数,该函数将更新我的表,其中包含整个月的所有数据。目前,如上所述,我只得到一天的数据来插入在PHP中循环数组以更新MySQL中的记录,但不会得到所有结果,php,arrays,loops,date,Php,Arrays,Loops,Date,我正试图遍历存储在数组中的一些数据,然后更新MySQL中整整一个月的记录。我可以检索一天的正确数据,但不能检索整个月的数据 我有一个带有日历的表单,用户可以在其中选择日期。目前,我对它进行了编码,以便用户可以选择任何日期(月、日、年),并确定该月的日期(我相信有一种更有效的方法来实现这一点)。例如,如果选择2019年1月18日,则返回31天(因为1月份有31天) 但实际情况是,所选日期的数据仅插入表中1月1日的数据(例如,如果我从日历中选择2019年1月18日,则插入2019年1月18日的数据,
$y = 0;
while ($y <= $mthDays) {
// Loop to get all sites
for($x=0; $x < $getSites; $x++)
{
// Code here for connecting to database for software we are using, get the data from that db for each site, do some calculations...
// The variables being passed into the function in the code directly below are the site, the date, plus calculated items not shown here.
$updateManualStatsDaily = $statsDao->updateStats($getSites[$x]['site_id'],$total_sessions,$count_guests,$count_unique_guests,$total_minutes,$dateImport);
}
$y++;
$dateImport = date('Y-m-d',strtotime($dexpl[0]."-".$dexpl[1]."-".$y));
}
注意:我也有这个代码运行一天(从日历中选择),这是有效的。它得到了一个月中的几天,并试图为每一天添加数据,这给我带来了麻烦
如果有人能帮忙,我将不胜感激!谢谢。假设数据库中已经存在每个
$updateDate
的记录,否则您将需要执行插入
查询,而不是更新
我在代码中看到的主要问题是$getSites
上的for
循环
for ($x=0; $x < $getSites; $x++) {
$getSites[$x]['site_id'];
}
或者最好还是使用foreachforeach
,例如:
操作顺序也有一些问题,需要改进 第一个
$dateImport
直到初始循环之后才定义,这将导致在第一次迭代时将null发送到数据库
由于$y
从0
开始,这将创建一个类似于2019-01-0
的日期,PHP将其解释为上个月的最后一天<代码>2018-12-31并可能产生意外结果。示例:
此外,如果未设置$\u GET['importDate']
,则可能无法定义$dexpl
,这将创建一个类似--0
的日期,PHP将其解释为1970-01-01
//consolidated conditional logic
$importTimestamp = strtotime(isset($_GET['importDate']) ? $_GET['importDate'] : 'yesterday');
$importDate = date('Y-m-d', $importTimestamp);
//declare dexpl and mthDays
$dexpl = explode('-', $importDate);
$mthDays = date('t', $importTimestamp);
//start at day 1, since we know mthDays will always be 28 to 31
$y = 1;
while ($y <= $mthDays) {
//null would be sent to the database initially otherwise
$dateImport = date('Y-m-d', strtotime($dexpl[0]."-".$dexpl[1]."-".$y));
$l = count($getSites);
for ($x=0; $x < $l; $x++) {
$updateManualStatsDaily = $statsDao->updateStats($getSites[$x]['site_id'],$total_sessions,$count_guests,$count_unique_guests,$total_minutes,$dateImport);
}
$y++;
}
然后,您只需要在
updateStats
方法中分离关注点,以便仅在尚未准备语句时准备语句
protected function prepareStats()
{
if (!isset($this-statsStmt)) {
$this-statsStmt = $this->dbSt->prepare('UPDATE table SET sessions_wifi = :sessions, wifi_users = :wifiUsers, wifi_unique_users = :wifiUniqueUsers, wifi_time = :wifiTime
WHERE site_id = :siteId and circ_date = :statsDate');
}
return $this->statsStmt;
}
public function updateStats($hz_site_id,$total_sessions,$count_guests,$count_unique_guests,$total_minutes,$updateDate)
{
try {
$stm = $this->prepareStats();
$stm->bindValue(':sessions', $total_sessions);
$stm->bindValue(':wifiUsers', $count_guests);
$stm->bindValue(':wifiUniqueUsers', $count_unique_guests);
$stm->bindValue(':wifiTime', $total_minutes);
$stm->bindValue(':siteId', $hz_site_id);
$stm->bindValue(':statsDate', $updateDate);
if ($stm->execute()) {
return true;
}
//no need for else, since we return on success already
echo $stm->errorInfo();
}catch (PDOException $e) {
echo $e->getMessage();
}
return false;
}
最后,我强烈建议不要使用
date('t')
。这将为您提供迭代天数的完整表示。而不是按指定的$importDate
的天数进行迭代,这将包括指定的$importDate
之前的天数和将来的天数
编辑:在更彻底地阅读了您的问题后,我意识到您想要导入整个给定月份。不仅仅是从指定日期到当前日期。但也会在当前日期的最大值处停止。因此,我更新了逻辑以反映所需的行为
例子:
你能检查一下这个吗?
$l = count($getSites);
for ($x=0; $x < $l; $x++) {
$getSites[$x]['site_id'];
}
foreach ($getSites as $site) {
$site['site_id'];
}
//consolidated conditional logic
$importTimestamp = strtotime(isset($_GET['importDate']) ? $_GET['importDate'] : 'yesterday');
$importDate = date('Y-m-d', $importTimestamp);
//declare dexpl and mthDays
$dexpl = explode('-', $importDate);
$mthDays = date('t', $importTimestamp);
//start at day 1, since we know mthDays will always be 28 to 31
$y = 1;
while ($y <= $mthDays) {
//null would be sent to the database initially otherwise
$dateImport = date('Y-m-d', strtotime($dexpl[0]."-".$dexpl[1]."-".$y));
$l = count($getSites);
for ($x=0; $x < $l; $x++) {
$updateManualStatsDaily = $statsDao->updateStats($getSites[$x]['site_id'],$total_sessions,$count_guests,$count_unique_guests,$total_minutes,$dateImport);
}
$y++;
}
$v = 1;
$stmt->bindParam(':v', $v);
$v = 2;
$stmt->execute(); //results in sending 2 to the DB as the `:v` placeholder value
protected function prepareStats()
{
if (!isset($this-statsStmt)) {
$this-statsStmt = $this->dbSt->prepare('UPDATE table SET sessions_wifi = :sessions, wifi_users = :wifiUsers, wifi_unique_users = :wifiUniqueUsers, wifi_time = :wifiTime
WHERE site_id = :siteId and circ_date = :statsDate');
}
return $this->statsStmt;
}
public function updateStats($hz_site_id,$total_sessions,$count_guests,$count_unique_guests,$total_minutes,$updateDate)
{
try {
$stm = $this->prepareStats();
$stm->bindValue(':sessions', $total_sessions);
$stm->bindValue(':wifiUsers', $count_guests);
$stm->bindValue(':wifiUniqueUsers', $count_unique_guests);
$stm->bindValue(':wifiTime', $total_minutes);
$stm->bindValue(':siteId', $hz_site_id);
$stm->bindValue(':statsDate', $updateDate);
if ($stm->execute()) {
return true;
}
//no need for else, since we return on success already
echo $stm->errorInfo();
}catch (PDOException $e) {
echo $e->getMessage();
}
return false;
}
//use !empty to prevent conflict of from today to today
if (!$start = date_create(!empty($_GET['importDate']) ? $_GET['importDate'] : 'yesterday')) {
die('Invalid Date Supplied');
}
$today = date_create();
if ($start > $today) {
die('Dates set in the future are not permitted');
}
//start at the first day of the month
$start->modify('first day of this month')->setTime(0,0,0);
//validate the current year and month to prevent exceeding current date
if ($start->format('Y-m') === $today->format('Y-m')) {
$end = date_create('yesterday')->setTime(23,59,59);
if ($end < $start) {
//yesterday was previous month - use current start date
$end = clone $start;
}
} else {
$end = clone $start;
$end->modify('last day of this month');
}
//always end at end of day
$end->setTime(23,59,59);
$importDates = new \DatePeriod($start, new \DateInterval('P1D'), $end);
//we can use foreach on $getSites which is faster
//switched order of operations, since if there are no sites, we don't need to continue.
foreach ($getSites as $site) {
foreach ($importDates as $importDate) {
//logic to calculate site data to UPDATE...
//...
$statsDao->updateStats(
$site['site_id'],
$total_sessions,
$count_guests,
$count_unique_guests,
$total_minutes,
$importDate->format('Y-m-d')
);
}
}
Import Dates: "2019-01-18"
Dates set in the future are not permitted
Import Dates: "2019-01-01" (current day)
2019-01-01
Import Dates: "2018-12-01", "2018-12-20", ""
2018-12-01
2018-12-02
2018-12-03
2018-12-04
2018-12-05
2018-12-06
2018-12-07
2018-12-08
2018-12-09
2018-12-10
2018-12-11
2018-12-12
2018-12-13
2018-12-14
2018-12-15
2018-12-16
2018-12-17
2018-12-18
2018-12-19
2018-12-20
2018-12-21
2018-12-22
2018-12-23
2018-12-24
2018-12-25
2018-12-26
2018-12-27
2018-12-28
2018-12-29
2018-12-30
2018-12-31