2

大家晚上好。

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

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

现在,我用标准的 MySQL 查询实现了我想要的,但它的代码很混乱,而且随着数据库的增长,它的性能可能会变得很糟糕。出于这个原因,我想使用循环。我也觉得bind_paramMySQLi 的安全性要好得多。该页面不接受任何用户输入,它仅用于显示,因此注入问题不大,但在将来的某个时候,我将寻求扩展它以允许用户控制显示的内容。

这是我原始 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)。请注意,最后 6if条语句仅用于确保在我的画布脚本尝试使用它们之前将空字段自动设置为 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查询循环,但MINandMAX循环几乎相同。

显然,这是行不通的,因为它只为每组查询分配一个变量,而不是为每个循环分配 4 个变量。

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

我可以通过 MySQLi 回显单个值,或者我可以通过 MySQLi 查询数据库以更改或添加数据,但是尝试创建一个循环来执行我对 MySQLi(甚至 MySQL)的预期,这是我需要帮助的事情。

4

2 回答 2

1

根据我对您的代码的阅读,您有固定数量的列并且知道它们的名称,并且您正在将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数组中会使它们的来源更加明确。

于 2012-12-23T16:53:25.210 回答
1

你可以想象,我想做的是将所有 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,~雷

于 2012-12-23T16:58:54.817 回答