【问题标题】:Building Indexed PHP Array in While Loop在 While 循环中构建索引 PHP 数组
【发布时间】:2019-12-06 23:45:24
【问题描述】:

我正在尝试将我自己的数据(目前仅显示在各种表格和 KPI 指标块中)格式化为图形框架所需的格式。本质上,我希望我的一些值成为图形生成脚本的 X 和 Y 数据。

这是期望的结果(一个可以从中生成图形/图形点的数组示例):

$dataPoints = array(
        array("x"=> 1, "y"=> 41, label=> "18/07/19"),
        array("x"=> 2, "y"=> 35, label=> "19/07/19"),
        array("x"=> 3, "y"=> 50, label=> "20/07/19"),
        array("x"=> 4, "y"=> 45, label=> "21/07/19"),
        array("x"=> 5, "y"=> 52, label=> "22/07/19"),
        array("x"=> 6, "y"=> 68, label=> "23/07/19")
);

我有以下代码可以提取我需要的相关信息:

//Build Graph Data Points
//
$daysmax=31;
$daycounter=0;
while($daysmax > $daycounter) {
  $sql_get_day_total_events="SELECT COUNT(*),date_sub(curdate(),INTERVAL $daycounter day) as date1 FROM tblticketlog
    WHERE DATE(date) = date_sub(curdate(),INTERVAL $daycounter day)
    AND ((action = 'New Support Ticket Opened')
    OR (action LIKE 'Status changed to Pending%')
    OR (action LIKE 'Status changed to In Progress%')
    OR (action LIKE 'New Ticket Response made by%'))";
  $get_day_total_events_result=mysqli_query($db,$sql_get_day_total_events);
  if(mysqli_num_rows($get_day_total_events_result) > 0) {
    while($row = $get_day_total_events_result->fetch_assoc()) {
      $day_result_date=strtotime($row['date1']);
      $day_result_value=$row['COUNT(*)'];
    }
  }
  $sql_get_day_escs="SELECT COUNT(*) FROM escalations
    WHERE DATE(esc_at) = date_sub(curdate(), INTERVAL $daycounter day)
    AND escalated = 1";
  $get_day_escs_result=mysqli_query($db2,$sql_get_day_escs);
  if(mysqli_num_rows($get_day_escs_result) > 0) {
    while($row = $get_day_escs_result->fetch_assoc()) {
      $day_escs_value=$row['COUNT(*)'];
    }
  }
  $day_slas_met = $day_result_value - $day_escs_value;
  $day_kpi_pcnt = round((($day_slas_met / $day_result_value) * 100),0);
  $daycounter=$daycounter + 1;
}

总结一下,我从 $db 中提取 30 天(滚动)每天的总事件,我从 $db2 中提取 30 天(滚动)每天“升级事件”的数量。我也从 $db 查询中获取日期。

对于我的图表:
X = $daycounter(只是数据点的增量数字 ID,从 0 开始到 30
Y = 使用 $day_kpi_pcnt 中的简单数学计算得出的 KPI 百分比
LABEL = 纯文本格式的日期对象

我想做什么
我在循环之前初始化了 $datapoints 数组:

$datapoints = array();

然后就在循环底部的 $daycounter+1 行之前,我尝试将我的值推送到数组中的索引:

$datapoints[x] = $daycounter;
$datapoints[label] = date("d-m-Y",$day_result_date);
$datapoints[y] = $day_kpi_pcnt;

但是,这只是以一个空图结束。如果我 var_dump 数组,我似乎将结果的最后一行放在一个空数组中:

**Day: 30 -- 29-06-2019 - 6/6 - 100%**
array(3) { ["x"]=> int(30) ["label"]=> string(10) "29-06-2019" ["y"]=> float(100) } 

老实说,PHP 数组以及如何使用它们可能是我最薄弱的主题。我真的很挣扎,并且希望得到一些指导,甚至是一些关于我哪里出错的基本提示。谢谢。

【问题讨论】:

  • “然后就在循环底部的 $daycounter+1 行之前,我尝试将我的值推送到数组中的索引”-您在代码中的哪个位置执行此操作?您可能会一次又一次地在循环中覆盖数组。一个很常见的错误。
  • @PaulSpiegel,你说得对,根据您在下面接受的答案,我将 3 个索引中的每一个设置为循环迭代中的数据值,使用“=”,因此覆盖所有以前的数据每次该索引。您的答案清晰正确,目前正在使用代码。谢谢。

标签: php mysql arrays indexing


【解决方案1】:

你所做的大概是这样的:

$datapoints = [];
while (...) {
    ...
    $datapoints[x] = $daycounter;
    $datapoints[label] = date("d-m-Y",$day_result_date);
    $datapoints[y] = $day_kpi_pcnt;
    ...
}

您将在每次循环迭代中用新的行值覆盖$datapoints 数组。因此,只会保留最后一行的值。相反,您需要将行追加到数组中:

$datapoints = [];
while (...) {
    ...
    $datapoints[] = [
        'x' => $daycounter,
        'label' => date("d-m-Y",$day_result_date),
        'y' => $day_kpi_pcnt,
    ];
    ...
}

【讨论】:

  • 这是对您提出的问题的正确答案,但是一旦您得到它的工作,您应该将它交给Code Review 以获得进一步的帮助。在循环中构建数组,从业务代码中调用 php 的内置 mysql 函数,以及在if 语句中引入变量都是危险信号,应该有更好的方法。 (SQL 作为业务代码中的字符串也是如此,但分离出来的难度更大。)
  • @ShapeOfMatter 我绝对支持你。还有很多工作要做。关于 SO 的一个问题太多了。
  • 谢谢@PaulSpiegel,这个答案奏效了,尽管我后来发现数组在图表中是倒退的,所以使用了array_reverse(),现在一切都好了。答案标记为已接受。
  • @ShapeOfMatter,老实说,我完全同意,我从未接受过任何正式的 PHP 培训,也从未与真正的 PHP 开发团队合作过。这完全是我自己在小项目上自学的。我 100% 感激并意识到我不太了解 PHP。另外,我觉得 CodeReview 只会毁了我,哈哈。堆栈对新手来说已经够残酷了!
  • @ShapeOfMatter 我确实点击了 codereview,并发布了我的大部分工作代码。得到了一些反馈,并设法将我的处理时间从 9 秒以上缩短到 488 毫秒。所以谢谢你的提醒
【解决方案2】:

您需要一个数组数组。首先为所有结果创建一个数组(您已经拥有它)和一个临时数组(这是在循环之外)。

$datapoints = $temp_datapoint = array();

然后用你的数据创建一个临时数组,就像你做的那样(这是在循环内):

$temp_datapoint['x'] = $daycounter;
$temp_datapoint['label'] = date("d-m-Y",$day_result_date);
$temp_datapoint['y'] = $day_kpi_pcnt;

然后将整个数组附加到循环内的 datapoints 数组中:

$datapoints[] = $temp_datapoint;

【讨论】:

  • 为了完整起见,我尝试了这个,它也有效,但是接受的答案更简洁(并且可能更正确)。感谢您的意见。
猜你喜欢
  • 2018-05-21
  • 2021-06-22
  • 2020-07-02
  • 2012-02-21
  • 1970-01-01
  • 2016-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多