MySQLi循环查询变量


MySQLi loop query to variables

大家晚上好。

我目前正在做一个小的个人项目。它的目的是从我的后端数据库中检索大量的值,并将它们存储为变量。然后使用这些变量来修改一些HTML5 Canvas对象的外观(在本例中,我使用arc)。

请注意,数据库中的值是Text,因此我的bind语句引用它。我正在调用的查询(AVG, MIN, MAX)与我所获得的值一起工作很好,因为字段存储数值数据(这仅仅是由于另一个处理添加或更新数据的脚本-已经运行MySQLi,并且使用Text是我的情况的最佳解决方案)。

现在,我用标准的MySQL查询实现了我想要的,但是它的代码很乱,而且随着数据库的增长,它的性能可能会变得很糟糕。出于这个原因,我想使用循环。我还觉得mysql的bind_param在安全性方面要好得多。页面不接受任何用户输入,它只是为了显示,所以注入是不太关心的,但在未来的某个时候,我将寻求扩展它,以允许用户控制显示的内容。

这是我的原始MySQL PHP代码示例;

$T0A = mysql_query('SELECT AVG(Temp0) FROM VTempStats'); // Average
$T0B = mysql_query('SELECT MIN(Temp0) FROM VTempStats'); // Bottom/MIN
$T0T = mysql_query('SELECT MAX(Temp0) FROM VTempStats'); // Top/MAX
$T1A = mysql_query('SELECT AVG(Temp1) FROM VTempStats'); // Average
$T1B = mysql_query('SELECT MIN(Temp1) FROM VTempStats'); // Bottom/MIN
$T1T = mysql_query('SELECT MAX(Temp1) FROM VTempStats'); // Top/MAX
$r_T0A = mysql_result($T0A, 0);
$r_T0T = mysql_result($T0T, 0);
$r_T0B = mysql_result($T0B, 0);
$r_T1A = mysql_result($T1A, 0);
$r_T1T = mysql_result($T1T, 0);
$r_T1B = mysql_result($T1B, 0);
if ($r_T0A == "" ) {$r_T0A = 0;}
if ($r_T1A == "" ) {$r_T1A = 0;}
if ($r_T0B == "" ) {$r_T0B = 0;}
if ($r_T1B == "" ) {$r_T1B = 0;}
if ($r_T0T == "" ) {$r_T0T = 0;}
if ($r_T1T == "" ) {$r_T1T = 0;}

这比原来的要短,因为有4x3组查询(Temp0,Temp1,Temp2,Temp3,以及min,max,avg)。请注意,最后6个if语句只是为了确保在我的画布脚本尝试处理它们之前,将null字段自动设置为0(见下文)。

要在弧上显示该值,我将在我的画布脚本中使用它(例如);

var endAngle = startAngle + (<?= $r_T0A ?> / 36+0.02);

它为我工作,显示的正是我所期望的。

现在,在试图清理我的代码和移动到一个循环和MySQLi,我遇到了问题。我对SQL和PHP都很陌生,所以我需要一些帮助。

这是我尝试过的;

$q_avg = "SELECT AVG(Temp?) FROM VTempStats";
    for ($i_avg = 0; $i_avg <= 3; ++$i_avg)
    {
        if ($s_avg = $mysqli->prepare($q_avg))
        {
            $s_avg->bind_param('s',$i_avg);
            $s_avg->execute();
            $s_avg->bind_result($avg);
            $s_avg->fetch();
            echo $avg;
        }
    }

注意: mysqli是MySQLi连接。我将代码缩减为只显示AVG查询循环,但MINMAX循环几乎相同。

显然,这将不起作用,因为它只为每组查询分配一个变量,而不是为每个循环分配4个变量。

正如你所想象的,我想做的是将所有12个值分配给各个变量,以便我可以在我的画布脚本中使用它们。我不完全确定我该怎么做。

我可以通过MySQLi回声个人值,或者我可以查询数据库更改或添加数据通过MySQLi,但试图使一个循环做什么我打算与MySQLi(甚至MySQL),这是我需要帮助的东西。

从我对代码的阅读来看,您有固定数量的列并知道它们的名称,并且您将AVG(), MIN(), MAX()聚合应用于同一聚合组上的同一表,没有应用WHERE子句。因此,它们都可以在一个查询中完成,您只需要从中获取一行。

SELECT
  AVG(Temp0) AS a0,
  MIN(Temp0) AS min0,
  MAX(Temp0) AS max0,
  AVG(Temp1) AS a1,
  MIN(Temp1) AS min1,
  MAX(Temp1) AS max1,
  AVG(Temp2) AS a2,
  MIN(Temp2) AS min2,
  MAX(Temp2) AS max2,
  AVG(Temp3) AS a3,
  MIN(Temp3) AS min3,
  MAX(Temp3) AS max3
FROM VTempStats

这可以在对$mysqli->query()的单个调用中完成,并且不需要绑定参数,因此您不需要prepare()的开销。需要调用fetch_assoc()来检索单行,其中列的别名如上面所做的a0, min0, max0, etc...

// Fetch one row
$values = $result_resource->fetch_assoc();
print_r($values);
printf("Avg 0: %s, Min 0: %s, Max 0: %s... etc....", $values['a0'], $values['min0'], $values['max0']);

可以使用extract()将它们拉入全局作用域,但我不建议这样做。将它们保存在$values数组中使它们的源代码更加明确。

正如你所想象的,我想做的是将所有12个值分配给各个变量,以便我可以在我的画布脚本中使用它们。我不太确定该怎么做

理解。以下是我要做的。

<?php // RAY_temp_scottprichard.php
error_reporting(E_ALL);
echo '<pre>';
// RANGE OF TEMPS
$temps = range(0,3);
// RANGE OF VALUES
$funcs = array
( 'A' => 'AVG'
, 'B' => 'MIN'
, 'T' => 'MAX'
)
;
// CONSTRUCT THE QUERY STRING
$query = 'SELECT ';
foreach ($temps as $t)
{
    foreach ($funcs as $key => $func)
    {
        $query .= PHP_EOL
        . $func
        . '(Temp'
        . $t
        . ') AS '
        . 'T'
        . $t
        . $key
        . ', '
        ;
    }
}
// DECLOP THE UNWANTED TRAILING COMMA
$query = rtrim($query, ', ');
// ADD THE TABLE NAME
$query .= ' FROM VTempStats';
// ADD ANY ORDER, LIMIT, WHERE CLAUSES HERE
$query .= ' WHERE 1=1';
// SHOW THE WORK PRODUCT
var_dump($query);

查看这里的输出查询字符串:http://www.laprbass.com/RAY_temp_scottpritchard.php

当你运行这个查询时,你将用*mysql_fetch_assoc()*或同等的方法获取一行,并且它将在该行中包含你想要的所有变量,并带有命名键。然后,可以使用类似这样的东西将变量名和值注入到脚本中。http://php.net/manual/en/function.extract.php

PHP extract()允许使用前缀,因此您应该能够避免对现有脚本进行太多更改。

HTH, ~雷