【问题标题】:Logic Error PHP Looped Array逻辑错误 PHP 循环数组
【发布时间】:2016-09-05 12:09:33
【问题描述】:

这解释起来有点复杂,尤其是在标题中 - 所以这里是:

我正在制作一个包含 12 个索引的 PHP 数组,每个月一个 - 每个月都会显示当月记录的页面浏览量,为了获得月份,我使用当前的 UNIX 时间并采取离开 2629743 秒(一个月),每次循环进行时,都会增加 2629743 秒 - 这应该生成数组,例如 (1, 4, 5, 9) 1 月的 1 个视图,2 月的 4 个视图,等等。

如果没有视图,我需要它类似于 (null, null, 9) 所以 1 月没有视图,2 月没有视图,3 月 9 日没有视图 - 但索引完全混乱,视图顺序错误.

循环代码:

$Month = 1; // Start with January
$MonthTimestamp = 2629743; // Start with the time of ONE month from current time
$ArrayTimeStamp = array();
while ($Month <= 12): // Go from January to February 

$Value1 = $now - $MonthTimestamp;
$ViewsThisMonth = mysqli_fetch_object(mysqli_query($db, "SELECT SUM(Views) AS NumberFinalViews FROM BlogViews WHERE TimeRecord >= '$Value1' AND TimeRecord < '$now'"));
$ArrayTimeStamp[] = $ViewsThisMonth->NumberFinalViews;
$MonthTimestamp = $MonthTimestamp + 2629743;
$Month++;
endwhile;

重申一下,数组需要存储每个月的页面浏览量,这些页面浏览量存储在数据库中,所有页面浏览量都带有时间戳,这些时间戳需要分成 12 个月,然后放入数组。

2 月的 4 个视图需要在第二个索引中,并且时间戳会大于 1 月的时间戳但小于 3 月。

感谢所有帮助!

编辑: $now 是以秒为单位的当前 UNIX 时间。

【问题讨论】:

  • $now 来自哪里?
  • 你有什么理由使用神秘的endwhile 而不是简单的while (...) { ... }
  • 警告:使用mysqli 时,您应该使用parameterized queriesbind_param 将用户数据添加到您的查询中。 不要使用字符串插值或连接来完成此操作,因为您创建了一个严重的SQL injection bug
  • 为什么是null?让它0[0,0,9]
  • 0 也可以。 $now 是当前的 UNIX 时间,应该注意。

标签: php mysql arrays logic


【解决方案1】:
  1. 您应该确保包含时间相关数据的列是DATETIMETIMESTAMP 列。这将使基于时间的查询更容易。

  2. 您可以将您在 PHP 中实现的逻辑移动到查询本身:

      SELECT SUM(Views) AS NumberFinalViews,
             EXTRACT(YEAR_MONTH FROM TimeRecord) AS YearMonth
        FROM BlogViews
       WHERE TimeRecord BETWEEN '$startMonth' AND '$endMonth'
    GROUP BY YearMonth
    

    如果TimeRecord只是一个表示UNIX时间戳的整数,则需要进行转换:

     ...
     EXTRACT(YEAR_MONTH FROM FROM_UNIXTIME(TimeRecord)) AS YearMonth
    

    这将返回一个结果,其中包含字段 YearMonth 的值,例如 201609(2016 年 9 月),以及该期间 Views 的数量,已经预先分组。您只需将$startMonth$endMonth 设置为您查询的整个期间的绝对分隔符,无需为每个月单独设置。

【讨论】:

  • $startMonth 和 $endMonth 会是一整年的值吗?所以 $startMonth 将是当前时间 - 一年,而结束时间将是当前时间加上一年?是逻辑害死我。
  • 是的,它们将是您尝试查询的一整年。如果您对整个日历年感兴趣,也许您甚至可以将其简化为 WHERE YEAR(FROM_UNIXTIME(TimeRecord)) = 2016
  • 不是一个可行的选择 - 查询绝对破坏了服务器速度
  • 是的,因为您必须对数据库中的每个值调用FROM_UNIXTIME。这可以通过 a) 使用 DATETIMETIMESTAMP 列来解决,这允许 MySQL 使用现有值“本地”工作,b) 使用适当的 indexes
  • 已经使用 DATETIME 列并将它们存储为适当的时间戳,TimeRecord 是一个索引 - 仍然是相同的速度问题,表中只有一行...这是代码on Pastebin
猜你喜欢
  • 1970-01-01
  • 2016-05-17
  • 2016-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-04
  • 1970-01-01
相关资源
最近更新 更多