在 PHP 中循环获取数组值

Get Array values in a loop in PHP

我有一个数组 $data 组成如下:

$data[$k]['id'] = $row['iddevice'];
$data[$k]['temp_00'] = $row['temp_00'];
$data[$k]['temp_01'] = $row['temp_01'];
$data[$k]['temp_02'] = $row['temp_02'];
$data[$k]['temp_03'] = $row['temp_03'];
$data[$k]['temp_04'] = $row['temp_04'];

这个数组我只有两个元素,所以echo count($data);return2

我正在使用 Morris.js 创建折线图,下面是工作代码示例:

$(function() {

    Morris.Line({
  element: 'morris-area-chart',
    data: [
  { y: '00h', 1:57, 2:41},
  { y: '01h', 1:62, 2:98},
  { y: '02h', 1:44, 2:43},
  { y: '03h', 1:67, 2:84},
  ],
  xkey: 'y',
  parseTime:false,
  ykeys: [1,2,3],
  pointSize: 2,
  hideHover: 'auto',
  labels: ['Capteur X', 'Capteur Y']
});

我的问题是,一旦我尝试使用 PHP 来使用我的 $data 中的值,它就不起作用,图表不会加载任何值。

   Morris.Line({
  element: 'morris-area-chart',
    data: [
    { y: '00h', <?php $i = 0; while ($i <= count($data)-1) { echo $data[$i]['id'].":".round($data[$i]['temp_00'],2); $i++; }?>},
    { y: '01h', <?php $i = 0; while ($i <= count($data)-1) { echo $data[$i]['id'].":".round($data[$i]['temp_01'],2); $i++; }?>},
    { y: '02h', <?php $i = 0; while ($i <= count($data)-1) { echo $data[$i]['id'].":".round($data[$i]['temp_02'],2); $i++; }?>},
    { y: '03h', <?php $i = 0; while ($i <= count($data)-1) { echo $data[$i]['id'].":".round($data[$i]['temp_03'],2); $i++; }?>},

  ],

对我来说,算法很好:

我在想什么或做错了什么?

此外,当我将 $i 初始化为 1 而不是 0 时,我可以获得 $data 数组

中第二个条目的值

(我更愿意说我不是开发人员,所以这段代码可能不是我同意的最干净的代码)

编辑:

你的问题在循环中

while ($i <= count($data)-1)

这应该是

while ($i <= (count($data)-1))

或者

while ($i < count($data))

效果更好

你可以进一步优化它。

  Morris.Line({
  element: 'morris-area-chart',
    data: [
    <?php
        foreach($data as $sensor) {
            foreach($sensor as $key => $value) {
                if($key == 'id') {
                    $id = $value;
                } else {
                    $tempTime[$key][$id] = $value;
                }
            }
        }   
        $i = 0;
        foreach($tempTime as $time) {
            echo sprintf("{ y: '%02dh', ",$i);
            foreach($time as $key => $value) {
                echo sprintf("%d:%d, ",$key, round($value,2);
            }
            echo "},";
            $i++;
        }
    ?>
  ],
  xkey: 'y',
  parseTime:false,
  ykeys: [1,2,3],
  pointSize: 2,
  hideHover: 'auto',
  labels: ['Capteur X', 'Capteur Y']
});

这样,如果您的数组变大,您就不必重复自己。

说明 foreach 是一个遍历数组的函数。 第一个 foreach 循环只是对数组重新排序,以便在最后一个 foreach 循环中更容易使用(当您首先从 sql 创建数组时,您会适当地这样做,但是我从你的 post 看不出你是怎么做到的) 最后一个 foreach 循环只是打印出 Morris.line() 函数所需的字符串。希望这是有道理的。

这是我建议的另一种方法。它减少了重复代码,并最大限度地减少了 PHP/JS 混合。

首先,在从查询中获取行时,构建数组的方式略有不同:

while ($row = $results->fetch_assoc()) {
    // Loop over each of the temp_x columns
    for ($i=0; $i < 4; $i++) {
        $x = str_pad($i, 2, '0', STR_PAD_LEFT);
        // add the value for each temp_x to a temporary array, using time for a key
        $temp = is_null($row["temp_$x"]) ? 'null' : round($row["temp_$x"], 2);
        $times[$x][] = $row['iddevice'] . ':' . $temp;
    }
}

接下来,格式化临时数组中每个数组的值

foreach ($times as $time => $temps) {
    $data[] = "{ y: '{$time}h', " . implode(', ', $temps) . '}';
}

然后将$data数组转换为字符串:

$data = implode(",\n", $data);

这样,您在 JS 部分需要的所有 PHP 是:

Morris.Line({
  element: 'morris-area-chart',
  data: [ <?php echo $data ?> ]

使用 json_encode 可能有更好的方法。如果您稍微更改 while 循环中的代码,该循环从您的数据库中获取行:

for ($i=0; $i < 4; $i++) {
    $x = str_pad($i, 2, '0', STR_PAD_LEFT);
    $temp = is_null($row["temp_$x"]) ? null : round($row["temp_$x"], 2);
    $times[$x]['y'] = $x.'h';
    $times[$x][$row['iddevice']] = $temp;
}

然后用json_encode可以组成$data。 (array_values 用于使用数字索引重新索引数组,因此它将在 JSON 输出中呈现为数组而不是对象。)

$data = json_encode(array_values($times));

在 JS 中:

Morris.Line({
  element: 'morris-area-chart',
  data: <?php echo $data ?>
  // note: no [] brackets around $data in this version

这是否有效取决于是否所有键都是字符串,因为 JSON 键是字符串,所以你会得到像

这样的输出
{ "y": "01", "1": 17.62, "2": 19.52 }

而不是

{ y: '01', 1: 17.62, 2: 19.52 }

我认为它应该可以正常工作。