PHP Mysql получить статистику за диапазон дат - PullRequest
0 голосов
/ 30 ноября 2011

Я получаю количество сканирований в базе данных. Поле времени - это отметка времени mysql (2011-10-20 14:15:12). У меня есть функция, которая позволяет мне устанавливать временные рамки, например, 30 дней, 60 дней и т. Д., Это работало в течение нескольких недель Тогда я просто заметил, что это сломалось.

function getScans($timeframe = 0)
{
    if ($timeframe != 0) { 
        $query = 'SELECT COUNT( * ) 
            FROM stats 
            WHERE time <= curdate( )+1 
            AND time >= curdate( )-' . ($timeframe - 1);
    } else {
        $query = 'SELECT COUNT( * ) 
            FROM stats';
    }

    $result = mysql_query($query);
    $row = mysql_fetch_array($result);
    return $row[0];
}

Я знаю, что вы все слышали это раньше, но на прошлой неделе это полностью сработало. Я вернулся сегодня и заметил, что когда $ timeframe не равен 0, он больше не работает. Любая помощь приветствуется.

Ответы [ 4 ]

1 голос
/ 30 ноября 2011

Проблема в следующем: curdate( )+1 дает 20111131 (на день 2011-11-30) не то, что, как я полагаю, вы ожидаете, 2011-12-01, то же самое верно и для последующего curdate() вызова. Вероятно, это работало нормально, потому что в начале месяца вызовы приводили к правильным датам, и MySQL принимает форматирование, но теперь он не может предупреждать о «невозможных» датах. Закрытие в следующем месяце, вещи начинают капризничать.

Запрос должен быть переписан так:

SELECT
  COUNT(*)
FROM `stats`
WHERE `stats`.`time` <= DATE_ADD(NOW(), INTERVAL 1 DAY)
  AND `stats`.`time` >= DATE_SUB(NOW(), INTERVAL $timeframe DAY)

Вы можете сделать что-то вроде этого:

function getScans($timeframe = 0)
{
    if ($timeframe != 0) { 
        $query = 'SELECT COUNT( * ) 
            FROM stats 
            WHERE time <= DATE_ADD(NOW(), INTERVAL 1 DAY) 
            AND time >= DATE_SUB(NOW(), INTERVAL ' . ($timeframe - 1) . ' DAY)';
    } else {
        $query = 'SELECT COUNT( * ) 
            FROM stats';
    }

    $result = mysql_query($query);
    $row = mysql_fetch_array($result);
    return $row[0];
}

Но это не самый безопасный подход, если пользователь может предоставить $timeframe или тому подобное. Скорее, вы должны рассмотреть возможность использования что-то вроде:

$query = sprintf ('SELECT
  COUNT(*)
FROM `stats`
WHERE `stats`.`time` <= DATE_ADD(NOW(), INTERVAL 1 DAY)
  AND `stats`.`time` >= DATE_SUB(NOW(), INTERVAL %d DAY)',
mysql_real_escape_string ($timeframe, $connection_handle));

или, что еще лучше, поищите в SO советы по дезинфекции пользовательского ввода перед добавлением его в оператор SQL.

0 голосов
/ 30 ноября 2011

Хм, я бы предпочел выполнить "всю логику" с PHP, а затем просто выполнить довольно простой запрос MySql.Например, вы можете легко получить временную метку (Ymd H: i: s) для дат в прошлом с помощью:

$dayago = date("Y-m-d", mktime(0, 0, 0, date("m"),date("d")-1,date("Y")));
$weekago = date("Y-m-d", mktime(0, 0, 0, date("m"),date("d")-7,date("Y")));
$monthago = date("Y-m-d", mktime(0, 0, 0, date("m"),date("d")-30,date("Y")));

То же самое относится и к будущим датам, например:

Так что я сделаю всю логику с PHP, получу 2 даты и затем выполню запрос Mysql.Что-то вроде:

$count = mysql_result(mysql_query("SELECT COUNT(*) as Num FROM stats WHERE date>='$weekago' AND date<='$tomorrow'"),0);
0 голосов
/ 30 ноября 2011

формат curdate и timeframe может не соответствовать ожидаемому, поэтому расчет не работает.напишите запрос в своем phpmyadmin или его аналоге и выясните, есть ли сначала синтаксические ошибки, и результат будет таким, как вы ожидаете

выводит значения и видит различия в PHPзатем используйте их в своем запросе.

правильный результат?

надеюсь, это поможет

0 голосов
/ 30 ноября 2011

Одиночная кавычка ниже не нужна и нарушает остальные функции.

.$timeframe - 1';
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...