0

我制作了一个 mysql 表来存储问题及其 Drupal 6 属性,如前缀、后缀、选项、标题、值、类型……等。

不幸的是,存储的选项值是一个数组,我收到错误“警告:为 foreach() 提供的参数无效”

代码是:

$fruit = db_query("SELECT type,title, value, section, collapsible,collapsed, description, options, size, prefix, suffix, default_value FROM {table} ");
  $count = 1;
  while($slice = db_fetch_array($fruit)){
  $section = $slice['section'];
  $op = $slice['options'];
    $form[$count] = array(
    '#type' => $slice['type'],
    '#title' => $slice['title'],
    '#collapsible' => $slice['collapsible'],
    '#collapsed' => $slice['collapsed'], 
    '#description' => $slice['description'], 
    '#options' => $op, 
    '#size' => $slice['size'], 
    '#prefix' => $slice['prefix'], 
    '#suffix' => $slice['suffix'], 
      );
$count = $count+1;
      }

在一种特殊情况下,选项是

array(t('yes'), t('no'))

其中 type 是“radios”
,它是作为 varchar 存储的内容(blob 也不起作用)(添加逗号也无济于事。

4

2 回答 2

1

不要将数组序列化为字符串。这是人们在数据库中存储列表时常犯的错误之一(尽管公平地说,这比为前 n 项创建固定数量的列要好)。

我会制作一个单独的options表格,其中每行有两列:问题表中的外键(question_id, option)在哪里。question_id查询看起来像,

SELECT option FROM options WHERE question_id = <<$id>>;

(<> 不是实际的 SQL,只是 PHP 参数化查询语法的占位符。)

如果需要订购选项,请添加第三列rank

SELECT option FROM options WHERE question_id = <<$id>> SORT BY rank ASCENDING;

编辑:为什么不将数组序列化为字符串?

这不是我深入研究过的东西,但我可以想到性能、便利性和理论:

  1. 出于性能原因,数据库经过优化以存储固定宽度的字段。如果您开始将列表放入字段中,最终您会遇到包含太多项目的列表,并且需要调整字段大小。同时,数据库经过高度优化,可以存储任意多行的表,您永远不需要调整表的大小来容纳更多行。

  2. 为方便起见,对已序列化为单个字段的列表运行查询确实很烦人。大多数数据库对查询存储为字段的列表的支持很差。从数据库的角度来看,这只是一个字符串,甚至可能是一个不透明的二进制 blob。

  3. 从理论的角度来看,它违反了关系数据库是关系代数的具体化的虚构。但事实证明这会产生实际后果,因为查询优化器使用关系代数中的等价定理将您的查询重写为性能更高的形式。违反关系代数的假设往往会生成优化不佳的查询(尽管永远不会错误)。

于 2013-03-12T12:48:27.717 回答
0

您不能在 MySQL 中按原样存储数组。您可能希望将其保存为序列化字符串 ( serialize($options)),然后保存unserialize($slice['options'])在您的表单中。

于 2013-03-12T12:09:29.470 回答