Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在PHP中循环数组以更新MySQL中的记录,但不会得到所有结果_Php_Arrays_Loops_Date - Fatal编程技术网

在PHP中循环数组以更新MySQL中的记录,但不会得到所有结果

在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日的数据,

我正试图遍历存储在数组中的一些数据,然后更新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是一个获取所有站点的函数

在获取站点的循环中,我为我们正在使用的软件连接到一个单独的数据库,从每个站点的数据库中获取数据,进行一些计算,然后移动到下一个站点

然后,我调用一个函数,该函数将更新我的表,其中包含整个月的所有数据。目前,如上所述,我只得到一天的数据来插入

$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'];
}
或者最好还是使用foreach
foreach
,例如:


操作顺序也有一些问题,需要改进

第一个
$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