Предполагая, что записи для каждого $updateDate
уже существуют в базе данных, в противном случае вам нужно будет выполнить запрос INSERT
вместо UPDATE
.
Основная проблема, которую я вижу с вашим кодом, заключается в цикле for
на $getSites
.
for ($x=0; $x < $getSites; $x++) {
$getSites[$x]['site_id'];
}
Что означает, что $getSites
является массивом, а не целым числом. Пример: https://3v4l.org/AK8ka
Вы хотели бы изменить его на Пример: https://3v4l.org/0qbWf
$l = count($getSites);
for ($x=0; $x < $l; $x++) {
$getSites[$x]['site_id'];
}
или, что еще лучше, использовать foreach
, пример: https://3v4l.org/FTOCI.
foreach ($getSites as $site) {
$site['site_id'];
}
Есть также несколько проблем с порядком операций, которые должны быть улучшены.
Первый $dateImport
не определен до тех пор, пока после начального цикла это не приведет к отправке нулевого значения в базу данных на первой итерации.
Кроме того, поскольку $y
начинается с 0
, это создаст дату, подобную 2019-01-0
, которая будет интерпретироваться PHP как последний день предыдущего месяца; 2018-12-31
и может привести к неожиданным результатам. Пример: https://3v4l.org/TiHtu.
Кроме того, кажется, $dexpl
может не быть определено, если не установлено $_GET['importDate']
, что приведет к созданию даты, такой как --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++;
}
Во-вторых, вам нужно всего лишь один раз вызвать prepare
и bindParam
для выполнения определенной операции запроса. Я предлагаю объявить подготовленный оператор свойству объекта и переключиться на использование PDOStatement::bindValue()
. Это связано с тем, что PDOStatement::bindParam()
будет использовать ссылку на связанную переменную для получения значения, которое вы не используете в данном контексте updateStats()
.
Например, обратите внимание на порядок примененных операций, при котором bindParam
вызывается до изменения значения $v
.
$v = 1;
$stmt->bindParam(':v', $v);
$v = 2;
$stmt->execute(); //results in sending 2 to the DB as the `:v` placeholder value
Тогда вам просто нужно разделить проблемы в вашем 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')
использовать DatePeriod()
. Что даст вам полное представление о днях, которые повторяются. В отличие от итерации по количеству дней указанного $importDate
, которое будет включать дни до указанного $importDate
и дни в будущем.
Редактировать: После прочтения вашего вопроса я понял, что вы хотите импортировать весь данный месяц. Не только с указанной даты до текущей даты. Но также остановиться на максимуме текущей даты. Поэтому я обновил логику, чтобы отразить желаемое поведение.
//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')
);
}
}
Я хотел бы отметить, что понятия не имею, где $total_sessions
,
$count_guests
, $count_unique_guests
, $total_minutes
приходят,
так что это может представлять дополнительные проблемы, которые, возможно, необходимо решить.
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