Циклическая обработка массивов в PHP для обновления записей в MySQL, но не получение всех результатов

Для браузеров, реализующих метод Object.defineProperty(), приведенный ниже код генерирует и возвращает функцию, которую вы можете привязать к любому принадлежащему вам объекту.

Преимущество этого подхода заключается в том, что он не расширяется Object.prototype.

Код работает, проверяя, обладает ли данный объект свойством __objectID__, и определив его как скрытое (неперечислимое) свойство только для чтения, если оно отсутствует.

Итак, это защищен от любых попыток изменить или переопределить свойство obj.__objectID__ только для чтения, после того как оно определено, и последовательно генерирует приятную ошибку вместо молчания.

Наконец, в довольно экстремальном случае, когда некоторые другой код уже определил __objectID__ для данного объекта, это значение просто будет возвращено.

var getObjectID = (function () {

    var id = 0;    // Private ID counter

    return function (obj) {

         if(obj.hasOwnProperty("__objectID__")) {
             return obj.__objectID__;

         } else {

             ++id;
             Object.defineProperty(obj, "__objectID__", {

                 /*
                  * Explicitly sets these two attribute values to false,
                  * although they are false by default.
                  */
                 "configurable" : false,
                 "enumerable" :   false,

                 /* 
                  * This closure guarantees that different objects
                  * will not share the same id variable.
                  */
                 "get" : (function (__objectID__) {
                     return function () { return __objectID__; };
                  })(id),

                 "set" : function () {
                     throw new Error("Sorry, but 'obj.__objectID__' is read-only!");
                 }
             });

             return obj.__objectID__;

         }
    };

})();
0
задан Ole V.V. 21 January 2019 в 13:45
поделиться

1 ответ

Предполагая, что записи для каждого $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 может не быть определено, если не установлено

Предполагая, что записи для каждого [118] уже существуют в базе данных, в противном случае вам потребуется выполнить запрос [119] вместо [1110].

Основная проблема, которую я вижу с вашим кодом, заключается в цикле [1111] на [1112].

[110]

Что подразумевает, что [1113] является массивом, а не целым числом. Пример: https://3v4l.org/AK8ka

Вы хотели бы изменить его на Пример: https://3v4l.org/0qbWf

[111]

или, что еще лучше, используйте [1114], пример: https://3v4l.org/FTOCI .

[112]

Есть также несколько проблем с порядком операций, которые должны быть улучшены.

Сначала [1115] не определено до тех пор, пока после начального цикла это не приведет к отправке нулевого значения в базу данных на первой итерации.

Кроме того, поскольку [1116] начинается с [1117], это создаст дату, подобную [1118], которая будет интерпретироваться PHP как последний день предыдущего месяца; [1119] и может привести к неожиданным результатам. Пример: https://3v4l.org/TiHtu .

Кроме того, кажется, что [1120] может не быть определено, если не установлено [1121], что приведет к созданию даты, подобной --0, которая будет интерпретироваться PHP как 1970-01-01

//consolidated conditional logic
$importTimestamp = strtotime(isset(

Предполагая, что записи для каждого $updateDate уже существуют в базе данных, в противном случае вам потребуется выполнить запрос INSERT вместо UPDATE.

Основная проблема, которую я вижу с вашим кодом, заключается в цикле for на $getSites.

[110]

Что подразумевает, что $getSites является массивом, а не целым числом. Пример: https://3v4l.org/AK8ka

Вы хотели бы изменить его на Пример: https://3v4l.org/0qbWf

[111]

или, что еще лучше, используйте foreach, пример: https://3v4l.org/FTOCI .

[112]

Есть также несколько проблем с порядком операций, которые должны быть улучшены.

Сначала $dateImport не определено до тех пор, пока после начального цикла это не приведет к отправке нулевого значения в базу данных на первой итерации.

Кроме того, поскольку $y начинается с 0, это создаст дату, подобную 2019-01-0, которая будет интерпретироваться PHP как последний день предыдущего месяца; 2018-12-31 и может привести к неожиданным результатам. Пример: https://3v4l.org/TiHtu .

Кроме того, кажется, что $dexpl может не быть определено, если не установлено

Предполагая, что записи для каждого [118] уже существуют в базе данных, в противном случае вам потребуется выполнить запрос [119] вместо [1110].

Основная проблема, которую я вижу с вашим кодом, заключается в цикле [1111] на [1112].

[110]

Что подразумевает, что [1113] является массивом, а не целым числом. Пример: https://3v4l.org/AK8ka

Вы хотели бы изменить его на Пример: https://3v4l.org/0qbWf

[111]

или, что еще лучше, используйте [1114], пример: https://3v4l.org/FTOCI .

[112]

Есть также несколько проблем с порядком операций, которые должны быть улучшены.

Сначала [1115] не определено до тех пор, пока после начального цикла это не приведет к отправке нулевого значения в базу данных на первой итерации.

Кроме того, поскольку [1116] начинается с [1117], это создаст дату, подобную [1118], которая будет интерпретироваться PHP как последний день предыдущего месяца; [1119] и может привести к неожиданным результатам. Пример: https://3v4l.org/TiHtu .

Кроме того, кажется, что [1120] может не быть определено, если не установлено [1121], что приведет к созданию даты, подобной --0, которая будет интерпретироваться PHP как 1970-01-01

[113] < hr>

Во-вторых, вам нужно вызывать 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 и дни в будущем.

Редактировать: После более тщательного прочтения вашего вопроса я понял, что вы хотите импортировать весь данный месяц. Не только с указанной даты до текущей даты. Но также остановиться на максимуме текущей даты. Поэтому я обновил логику, чтобы отразить желаемое поведение.

Пример: https://3v4l.org/S0H6s

//use !empty to prevent conflict of from today to today
if (!$start = date_create(!empty(

Предполагая, что записи для каждого $updateDate уже существуют в базе данных, в противном случае вам потребуется выполнить запрос INSERT вместо UPDATE.

Основная проблема, которую я вижу с вашим кодом, заключается в цикле for на $getSites.

[110]

Что подразумевает, что $getSites является массивом, а не целым числом. Пример: https://3v4l.org/AK8ka

Вы хотели бы изменить его на Пример: https://3v4l.org/0qbWf

[111]

или, что еще лучше, используйте foreach, пример: https://3v4l.org/FTOCI .

[112]

Есть также несколько проблем с порядком операций, которые должны быть улучшены.

Сначала $dateImport не определено до тех пор, пока после начального цикла это не приведет к отправке нулевого значения в базу данных на первой итерации.

Кроме того, поскольку $y начинается с 0, это создаст дату, подобную 2019-01-0, которая будет интерпретироваться PHP как последний день предыдущего месяца; 2018-12-31 и может привести к неожиданным результатам. Пример: https://3v4l.org/TiHtu .

Кроме того, кажется, что $dexpl может не быть определено, если не установлено

Предполагая, что записи для каждого [118] уже существуют в базе данных, в противном случае вам потребуется выполнить запрос [119] вместо [1110].

Основная проблема, которую я вижу с вашим кодом, заключается в цикле [1111] на [1112].

[110]

Что подразумевает, что [1113] является массивом, а не целым числом. Пример: https://3v4l.org/AK8ka

Вы хотели бы изменить его на Пример: https://3v4l.org/0qbWf

[111]

или, что еще лучше, используйте [1114], пример: https://3v4l.org/FTOCI .

[112]

Есть также несколько проблем с порядком операций, которые должны быть улучшены.

Сначала [1115] не определено до тех пор, пока после начального цикла это не приведет к отправке нулевого значения в базу данных на первой итерации.

Кроме того, поскольку [1116] начинается с [1117], это создаст дату, подобную [1118], которая будет интерпретироваться PHP как последний день предыдущего месяца; [1119] и может привести к неожиданным результатам. Пример: https://3v4l.org/TiHtu .

Кроме того, кажется, что [1120] может не быть определено, если не установлено [1121], что приведет к созданию даты, подобной --0, которая будет интерпретироваться PHP как 1970-01-01

[113] < hr>

Во-вторых, вам нужно вызывать prepare и bindParam только один раз для данной операции запроса. Я предлагаю объявить подготовленный оператор свойству объекта и переключиться на использование PDOStatement::bindValue() . Это связано с тем, что PDOStatement::bindParam() будет использовать ссылку на связанную переменную для извлечения значения, которое вы не используете в данном контексте updateStats().

Например, обратите внимание на порядок примененных операций, который вызывается bindParam до изменения значения $v. ​​

[114]

Тогда вам просто нужно разделить проблемы в вашем методе updateStats, чтобы подготовить утверждение, только если оно еще не было.

[115]

Наконец, я настоятельно рекомендую вместо использования date('t') использовать DatePeriod() . Что даст вам полное представление о днях, которые повторяются. В отличие от итерации по количеству дней указанного $importDate, которое будет включать дни до указанного $importDate и дни в будущем.

Редактировать: После более тщательного прочтения вашего вопроса я понял, что вы хотите импортировать весь данный месяц. Не только с указанной даты до текущей даты. Но также остановиться на максимуме текущей даты. Поэтому я обновил логику, чтобы отразить желаемое поведение.

Пример: https://3v4l.org/S0H6s

[116]

Хочу отметить, что понятия не имею, где $total_sessions,
[ 1149] $count_guests, $count_unique_guests, $total_minutes, поэтому это может представлять дополнительные проблемы, которые, возможно, необходимо решить.

Результаты текущей даты «2019-01-01»: https://3v4l.org/ddQG0

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
GET['importDate']
, что приведет к созданию даты, подобной --0, которая будет интерпретироваться PHP как 1970-01-01

[113] < hr>

Во-вторых, вам нужно вызывать prepare и bindParam только один раз для данной операции запроса. Я предлагаю объявить подготовленный оператор свойству объекта и переключиться на использование PDOStatement::bindValue() . Это связано с тем, что PDOStatement::bindParam() будет использовать ссылку на связанную переменную для извлечения значения, которое вы не используете в данном контексте updateStats().

Например, обратите внимание на порядок примененных операций, который вызывается bindParam до изменения значения $v. ​​

[114]

Тогда вам просто нужно разделить проблемы в вашем методе updateStats, чтобы подготовить утверждение, только если оно еще не было.

[115]

Наконец, я настоятельно рекомендую вместо использования date('t') использовать DatePeriod() . Что даст вам полное представление о днях, которые повторяются. В отличие от итерации по количеству дней указанного $importDate, которое будет включать дни до указанного $importDate и дни в будущем.

Редактировать: После более тщательного прочтения вашего вопроса я понял, что вы хотите импортировать весь данный месяц. Не только с указанной даты до текущей даты. Но также остановиться на максимуме текущей даты. Поэтому я обновил логику, чтобы отразить желаемое поведение.

Пример: https://3v4l.org/S0H6s

[116]

Хочу отметить, что понятия не имею, где $total_sessions,
[ 1149] $count_guests, $count_unique_guests, $total_minutes, поэтому это может представлять дополнительные проблемы, которые, возможно, необходимо решить.

Результаты текущей даты «2019-01-01»: https://3v4l.org/ddQG0

[117]GET['importDate']) ?

Предполагая, что записи для каждого $updateDate уже существуют в базе данных, в противном случае вам потребуется выполнить запрос INSERT вместо UPDATE.

Основная проблема, которую я вижу с вашим кодом, заключается в цикле for на $getSites.

[110]

Что подразумевает, что $getSites является массивом, а не целым числом. Пример: https://3v4l.org/AK8ka

Вы хотели бы изменить его на Пример: https://3v4l.org/0qbWf

[111]

или, что еще лучше, используйте foreach, пример: https://3v4l.org/FTOCI .

[112]

Есть также несколько проблем с порядком операций, которые должны быть улучшены.

Сначала $dateImport не определено до тех пор, пока после начального цикла это не приведет к отправке нулевого значения в базу данных на первой итерации.

Кроме того, поскольку $y начинается с 0, это создаст дату, подобную 2019-01-0, которая будет интерпретироваться PHP как последний день предыдущего месяца; 2018-12-31 и может привести к неожиданным результатам. Пример: https://3v4l.org/TiHtu .

Кроме того, кажется, что $dexpl может не быть определено, если не установлено

Предполагая, что записи для каждого [118] уже существуют в базе данных, в противном случае вам потребуется выполнить запрос [119] вместо [1110].

Основная проблема, которую я вижу с вашим кодом, заключается в цикле [1111] на [1112].

[110]

Что подразумевает, что [1113] является массивом, а не целым числом. Пример: https://3v4l.org/AK8ka

Вы хотели бы изменить его на Пример: https://3v4l.org/0qbWf

[111]

или, что еще лучше, используйте [1114], пример: https://3v4l.org/FTOCI .

[112]

Есть также несколько проблем с порядком операций, которые должны быть улучшены.

Сначала [1115] не определено до тех пор, пока после начального цикла это не приведет к отправке нулевого значения в базу данных на первой итерации.

Кроме того, поскольку [1116] начинается с [1117], это создаст дату, подобную [1118], которая будет интерпретироваться PHP как последний день предыдущего месяца; [1119] и может привести к неожиданным результатам. Пример: https://3v4l.org/TiHtu .

Кроме того, кажется, что [1120] может не быть определено, если не установлено [1121], что приведет к созданию даты, подобной --0, которая будет интерпретироваться PHP как 1970-01-01

[113] < hr>

Во-вторых, вам нужно вызывать prepare и bindParam только один раз для данной операции запроса. Я предлагаю объявить подготовленный оператор свойству объекта и переключиться на использование PDOStatement::bindValue() . Это связано с тем, что PDOStatement::bindParam() будет использовать ссылку на связанную переменную для извлечения значения, которое вы не используете в данном контексте updateStats().

Например, обратите внимание на порядок примененных операций, который вызывается bindParam до изменения значения $v. ​​

[114]

Тогда вам просто нужно разделить проблемы в вашем методе updateStats, чтобы подготовить утверждение, только если оно еще не было.

[115]

Наконец, я настоятельно рекомендую вместо использования date('t') использовать DatePeriod() . Что даст вам полное представление о днях, которые повторяются. В отличие от итерации по количеству дней указанного $importDate, которое будет включать дни до указанного $importDate и дни в будущем.

Редактировать: После более тщательного прочтения вашего вопроса я понял, что вы хотите импортировать весь данный месяц. Не только с указанной даты до текущей даты. Но также остановиться на максимуме текущей даты. Поэтому я обновил логику, чтобы отразить желаемое поведение.

Пример: https://3v4l.org/S0H6s

[116]

Хочу отметить, что понятия не имею, где $total_sessions,
[ 1149] $count_guests, $count_unique_guests, $total_minutes, поэтому это может представлять дополнительные проблемы, которые, возможно, необходимо решить.

Результаты текущей даты «2019-01-01»: https://3v4l.org/ddQG0

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
GET['importDate']
, что приведет к созданию даты, подобной --0, которая будет интерпретироваться PHP как 1970-01-01

[113] < hr>

Во-вторых, вам нужно вызывать prepare и bindParam только один раз для данной операции запроса. Я предлагаю объявить подготовленный оператор свойству объекта и переключиться на использование PDOStatement::bindValue() . Это связано с тем, что PDOStatement::bindParam() будет использовать ссылку на связанную переменную для извлечения значения, которое вы не используете в данном контексте updateStats().

Например, обратите внимание на порядок примененных операций, который вызывается bindParam до изменения значения $v. ​​

[114]

Тогда вам просто нужно разделить проблемы в вашем методе updateStats, чтобы подготовить утверждение, только если оно еще не было.

[115]

Наконец, я настоятельно рекомендую вместо использования date('t') использовать DatePeriod() . Что даст вам полное представление о днях, которые повторяются. В отличие от итерации по количеству дней указанного $importDate, которое будет включать дни до указанного $importDate и дни в будущем.

Редактировать: После более тщательного прочтения вашего вопроса я понял, что вы хотите импортировать весь данный месяц. Не только с указанной даты до текущей даты. Но также остановиться на максимуме текущей даты. Поэтому я обновил логику, чтобы отразить желаемое поведение.

Пример: https://3v4l.org/S0H6s

[116]

Хочу отметить, что понятия не имею, где $total_sessions,
[ 1149] $count_guests, $count_unique_guests, $total_minutes, поэтому это может представлять дополнительные проблемы, которые, возможно, необходимо решить.

Результаты текущей даты «2019-01-01»: https://3v4l.org/ddQG0

[117]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,
[ 1149] $count_guests, $count_unique_guests, $total_minutes, поэтому это может представлять дополнительные проблемы, которые, возможно, необходимо решить.

Результаты текущей даты «2019-01-01»: https://3v4l.org/ddQG0

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
GET['importDate'], что приведет к созданию даты, подобной --0, которая будет интерпретироваться PHP как 1970-01-01

[113] < hr>

Во-вторых, вам нужно вызывать prepare и bindParam только один раз для данной операции запроса. Я предлагаю объявить подготовленный оператор свойству объекта и переключиться на использование PDOStatement::bindValue() . Это связано с тем, что PDOStatement::bindParam() будет использовать ссылку на связанную переменную для извлечения значения, которое вы не используете в данном контексте updateStats().

Например, обратите внимание на порядок примененных операций, который вызывается bindParam до изменения значения $v. ​​

[114]

Тогда вам просто нужно разделить проблемы в вашем методе updateStats, чтобы подготовить утверждение, только если оно еще не было.

[115]

Наконец, я настоятельно рекомендую вместо использования date('t') использовать DatePeriod() . Что даст вам полное представление о днях, которые повторяются. В отличие от итерации по количеству дней указанного $importDate, которое будет включать дни до указанного $importDate и дни в будущем.

Редактировать: После более тщательного прочтения вашего вопроса я понял, что вы хотите импортировать весь данный месяц. Не только с указанной даты до текущей даты. Но также остановиться на максимуме текущей даты. Поэтому я обновил логику, чтобы отразить желаемое поведение.

Пример: https://3v4l.org/S0H6s

[116]

Хочу отметить, что понятия не имею, где $total_sessions,
[ 1149] $count_guests, $count_unique_guests, $total_minutes, поэтому это может представлять дополнительные проблемы, которые, возможно, необходимо решить.

Результаты текущей даты «2019-01-01»: https://3v4l.org/ddQG0

[117]GET['importDate']) ?

Предполагая, что записи для каждого $updateDate уже существуют в базе данных, в противном случае вам потребуется выполнить запрос INSERT вместо UPDATE.

Основная проблема, которую я вижу с вашим кодом, заключается в цикле for на $getSites.

[110]

Что подразумевает, что $getSites является массивом, а не целым числом. Пример: https://3v4l.org/AK8ka

Вы хотели бы изменить его на Пример: https://3v4l.org/0qbWf

[111]

или, что еще лучше, используйте foreach, пример: https://3v4l.org/FTOCI .

[112]

Есть также несколько проблем с порядком операций, которые должны быть улучшены.

Сначала $dateImport не определено до тех пор, пока после начального цикла это не приведет к отправке нулевого значения в базу данных на первой итерации.

Кроме того, поскольку $y начинается с 0, это создаст дату, подобную 2019-01-0, которая будет интерпретироваться PHP как последний день предыдущего месяца; 2018-12-31 и может привести к неожиданным результатам. Пример: https://3v4l.org/TiHtu .

Кроме того, кажется, что $dexpl может не быть определено, если не установлено

Предполагая, что записи для каждого [118] уже существуют в базе данных, в противном случае вам потребуется выполнить запрос [119] вместо [1110].

Основная проблема, которую я вижу с вашим кодом, заключается в цикле [1111] на [1112].

[110]

Что подразумевает, что [1113] является массивом, а не целым числом. Пример: https://3v4l.org/AK8ka

Вы хотели бы изменить его на Пример: https://3v4l.org/0qbWf

[111]

или, что еще лучше, используйте [1114], пример: https://3v4l.org/FTOCI .

[112]

Есть также несколько проблем с порядком операций, которые должны быть улучшены.

Сначала [1115] не определено до тех пор, пока после начального цикла это не приведет к отправке нулевого значения в базу данных на первой итерации.

Кроме того, поскольку [1116] начинается с [1117], это создаст дату, подобную [1118], которая будет интерпретироваться PHP как последний день предыдущего месяца; [1119] и может привести к неожиданным результатам. Пример: https://3v4l.org/TiHtu .

Кроме того, кажется, что [1120] может не быть определено, если не установлено [1121], что приведет к созданию даты, подобной --0, которая будет интерпретироваться PHP как 1970-01-01

[113] < hr>

Во-вторых, вам нужно вызывать 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 и дни в будущем.

Редактировать: После более тщательного прочтения вашего вопроса я понял, что вы хотите импортировать весь данный месяц. Не только с указанной даты до текущей даты. Но также остановиться на максимуме текущей даты. Поэтому я обновил логику, чтобы отразить желаемое поведение.

Пример: https://3v4l.org/S0H6s

//use !empty to prevent conflict of from today to today
if (!$start = date_create(!empty(

Предполагая, что записи для каждого $updateDate уже существуют в базе данных, в противном случае вам потребуется выполнить запрос INSERT вместо UPDATE.

Основная проблема, которую я вижу с вашим кодом, заключается в цикле for на $getSites.

[110]

Что подразумевает, что $getSites является массивом, а не целым числом. Пример: https://3v4l.org/AK8ka

Вы хотели бы изменить его на Пример: https://3v4l.org/0qbWf

[111]

или, что еще лучше, используйте foreach, пример: https://3v4l.org/FTOCI .

[112]

Есть также несколько проблем с порядком операций, которые должны быть улучшены.

Сначала $dateImport не определено до тех пор, пока после начального цикла это не приведет к отправке нулевого значения в базу данных на первой итерации.

Кроме того, поскольку $y начинается с 0, это создаст дату, подобную 2019-01-0, которая будет интерпретироваться PHP как последний день предыдущего месяца; 2018-12-31 и может привести к неожиданным результатам. Пример: https://3v4l.org/TiHtu .

Кроме того, кажется, что $dexpl может не быть определено, если не установлено

Предполагая, что записи для каждого [118] уже существуют в базе данных, в противном случае вам потребуется выполнить запрос [119] вместо [1110].

Основная проблема, которую я вижу с вашим кодом, заключается в цикле [1111] на [1112].

[110]

Что подразумевает, что [1113] является массивом, а не целым числом. Пример: https://3v4l.org/AK8ka

Вы хотели бы изменить его на Пример: https://3v4l.org/0qbWf

[111]

или, что еще лучше, используйте [1114], пример: https://3v4l.org/FTOCI .

[112]

Есть также несколько проблем с порядком операций, которые должны быть улучшены.

Сначала [1115] не определено до тех пор, пока после начального цикла это не приведет к отправке нулевого значения в базу данных на первой итерации.

Кроме того, поскольку [1116] начинается с [1117], это создаст дату, подобную [1118], которая будет интерпретироваться PHP как последний день предыдущего месяца; [1119] и может привести к неожиданным результатам. Пример: https://3v4l.org/TiHtu .

Кроме того, кажется, что [1120] может не быть определено, если не установлено [1121], что приведет к созданию даты, подобной --0, которая будет интерпретироваться PHP как 1970-01-01

[113] < hr>

Во-вторых, вам нужно вызывать prepare и bindParam только один раз для данной операции запроса. Я предлагаю объявить подготовленный оператор свойству объекта и переключиться на использование PDOStatement::bindValue() . Это связано с тем, что PDOStatement::bindParam() будет использовать ссылку на связанную переменную для извлечения значения, которое вы не используете в данном контексте updateStats().

Например, обратите внимание на порядок примененных операций, который вызывается bindParam до изменения значения $v. ​​

[114]

Тогда вам просто нужно разделить проблемы в вашем методе updateStats, чтобы подготовить утверждение, только если оно еще не было.

[115]

Наконец, я настоятельно рекомендую вместо использования date('t') использовать DatePeriod() . Что даст вам полное представление о днях, которые повторяются. В отличие от итерации по количеству дней указанного $importDate, которое будет включать дни до указанного $importDate и дни в будущем.

Редактировать: После более тщательного прочтения вашего вопроса я понял, что вы хотите импортировать весь данный месяц. Не только с указанной даты до текущей даты. Но также остановиться на максимуме текущей даты. Поэтому я обновил логику, чтобы отразить желаемое поведение.

Пример: https://3v4l.org/S0H6s

[116]

Хочу отметить, что понятия не имею, где $total_sessions,
[ 1149] $count_guests, $count_unique_guests, $total_minutes, поэтому это может представлять дополнительные проблемы, которые, возможно, необходимо решить.

Результаты текущей даты «2019-01-01»: https://3v4l.org/ddQG0

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
GET['importDate']
, что приведет к созданию даты, подобной --0, которая будет интерпретироваться PHP как 1970-01-01

[113] < hr>

Во-вторых, вам нужно вызывать prepare и bindParam только один раз для данной операции запроса. Я предлагаю объявить подготовленный оператор свойству объекта и переключиться на использование PDOStatement::bindValue() . Это связано с тем, что PDOStatement::bindParam() будет использовать ссылку на связанную переменную для извлечения значения, которое вы не используете в данном контексте updateStats().

Например, обратите внимание на порядок примененных операций, который вызывается bindParam до изменения значения $v. ​​

[114]

Тогда вам просто нужно разделить проблемы в вашем методе updateStats, чтобы подготовить утверждение, только если оно еще не было.

[115]

Наконец, я настоятельно рекомендую вместо использования date('t') использовать DatePeriod() . Что даст вам полное представление о днях, которые повторяются. В отличие от итерации по количеству дней указанного $importDate, которое будет включать дни до указанного $importDate и дни в будущем.

Редактировать: После более тщательного прочтения вашего вопроса я понял, что вы хотите импортировать весь данный месяц. Не только с указанной даты до текущей даты. Но также остановиться на максимуме текущей даты. Поэтому я обновил логику, чтобы отразить желаемое поведение.

Пример: https://3v4l.org/S0H6s

[116]

Хочу отметить, что понятия не имею, где $total_sessions,
[ 1149] $count_guests, $count_unique_guests, $total_minutes, поэтому это может представлять дополнительные проблемы, которые, возможно, необходимо решить.

Результаты текущей даты «2019-01-01»: https://3v4l.org/ddQG0

[117]GET['importDate']) ?

Предполагая, что записи для каждого $updateDate уже существуют в базе данных, в противном случае вам потребуется выполнить запрос INSERT вместо UPDATE.

Основная проблема, которую я вижу с вашим кодом, заключается в цикле for на $getSites.

[110]

Что подразумевает, что $getSites является массивом, а не целым числом. Пример: https://3v4l.org/AK8ka

Вы хотели бы изменить его на Пример: https://3v4l.org/0qbWf

[111]

или, что еще лучше, используйте foreach, пример: https://3v4l.org/FTOCI .

[112]

Есть также несколько проблем с порядком операций, которые должны быть улучшены.

Сначала $dateImport не определено до тех пор, пока после начального цикла это не приведет к отправке нулевого значения в базу данных на первой итерации.

Кроме того, поскольку $y начинается с 0, это создаст дату,

0
ответ дан fyrye 21 January 2019 в 13:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: