【问题标题】:PHP: How do you avoid the use of extract() in a specific casePHP:如何避免在特定情况下使用 extract()
【发布时间】:2015-08-26 00:31:05
【问题描述】:

我对 PHP 非常陌生,并且到处都在阅读不建议使用提取函数的信息。我正在从 mysql 表中获取数据以填充网站的一部分。因此我不知道该表可以有多少行。

所以我使用了 extract 函数,它为每一行提供了一个数组数组。为了创建一些有助于每个字段“回显”的变量,我正在使用以下代码:

$query = "SELECT * FROM example";
$result = mysqli_query($link,$query);
$num = mysqli_num_rows($result);
$gharray = mysqli_fetch_all($result,MYSQLI_ASSOC);
$arrayrows = array_keys($gharray);
foreach ($arrayrows as $arrayrow) {
   $i = $arrayrow;
};
foreach ($gharray[$i] as $ghimg) {
   extract ($gharray[$i], EXTR_PREFIX_ALL, "img"."$i");
};

它完成工作并创建变量,例如: $img1_title, $img1_description, $img2_title等(这会在评论中提到,所以这些变量在回溯时会有解释。

但我想知道这是否正确使用,或者是否有更简单、更清洁的解决方案来实现相同的结果。或者,如果有一定的行数限制(即六行),你会以不同的方式做吗?

我们会对发布到数据库的所有内容进行清理,因此不会有任何问题。 (此外,管理员是唯一可以在那里发布信息的人)。无论如何,我们将不胜感激。

【问题讨论】:

  • 你能解释一下你在用这个代码做什么:foreach ($arrayrows as $arrayrow) { $i = $arrayrow; };?您是否要查找 $arrayrow 中的最后一个值?
  • 不明白为什么你不只使用数组
  • 你为什么首先使用extract?为什么数组元素必须成为变量名?我很困惑为什么你需要这样做。也许您可以发布更多代码,以便我们更好地了解您的需求?
  • extract 有它的位置,我想(有理由的)担心是它会用任意的、隐式定义的变量污染当前范围——这使得人们很难对代码进行推理你写。请记住,代码是“一次编写,经常阅读”。从您提供的示例代码中很难看出您的意图是什么,但我建议嵌套循环可能是合适的,并且更具可读性。
  • 好的,感谢四位您对此的意见。 @Darragh 对于您的第一条评论:fetch_all 函数为我提供了一个数组,其中包含表中每一行的嵌套数组。第一个foreach 让我分别提取每个“行数组”并为每个字段分配一个自定义$i 变量。 @Dagon,@raduation 你的意思是像$array[]["fieldname"]?我必须将数组的每个字段放在几个地方,所以我发现只要我想放置任何东西,简单地放置echo $variablename 会更容易,因为它也可以提高可读性。 (对比$array[]["fieldname"]

标签: php mysql arrays extract


【解决方案1】:

您可以使用list (),但您需要一个枚举数组。检查 PHP 文档:

$row = [];
$row[0] = 123;
$row[1] = 'data';
 list($id, $data) = $row; 

http://php.net/manual/en/function.list.php

基本上list($id, $data) = $row; 会:

$id = $row[0];
$data = $row[1];

变量越多越短。

【讨论】:

  • 嘿@MinusFour 这似乎很棒,尽管我开始理解这里的人们只使用数组的意思。但是,我还没有完全理解如何从嵌套在数组中的数组分配列表的值,就像我的情况一样。
  • 您仍然需要迭代包含实际数据的数组的结果集。但是,您无需将所有内容都提取到单独的变量中,而是选择您需要的内容。
  • 谢谢我现在明白了!非常有用,至少对于演示案例。这是一个多一点的工作,但我完全是为了学习避免不良做法。我仍然不完全了解如何使其动态化,因为我不知道该表将有多少行,而且我还需要为每行取三列字段...
  • 我现在有这个:$result = mysqli_query($link,$query); $num = mysqli_num_rows($result); $hgarray = mysqli_fetch_all($result,MYSQLI_NUM); list($ghimg1,$ghimg2, $ghimg3, $ghimg4, $ghimg5, $ghimg6) = $hgarray; list ($ghimg1_id, $ghimg1_title, $ghimg1_image, $ghimg1_descrip) = $ghimg1; list ($ghimg2_id, $ghimg2_title, $ghimg2_image, $ghimg2_descrip) = $ghimg2;.... 等等。问题又是我不知道会有多少行,现在它只有两行,所以我得到$ghimg3, $ghimg4 和相关的未定义变量的错误,因为它们甚至还不存在。
  • 嗯,这对我来说没有多大意义。为什么要转储整个结果集?你最好迭代结果集。喜欢foreach($gharray as $row) { list($ghimg_id, $ghimg_time, $ghimg_image, $ghimg_descript) = $row; //Now you work with those variables inside this scope }
【解决方案2】:

计数变量:

要计算变量(这似乎是您第一个循环的目的?),您可以使用:

    $number_of_rows_in_your_array = count($arrayrows);

更清洁的解决方案:

您并没有非常具体地说明您希望如何填充该网站。假设您要填充具有相同行结构的简单表,那么您不需要 x 变量。相反,你可以用这样的东西替换你的两个循环:

    echo '
    <table>
      <tr>
        <td>
          Header row
        </td>
      </tr>';
      for($x=0;$x=count($arrayrows);$x++){
        echo '
        <tr>
          <td>
             '.$arrayrows[$x].'
          </td>
        </tr>';
      }
    echo '
    </table>';

在这里,我正在使用数组,并且每次迭代都显示 $ith 元素。因此,不需要 x 变量。

【讨论】:

  • 我试图将可操作的 php 与标记尽可能地分开,因此我会将发布的代码放在单独的文件中,并将其包含在需要回显变量的标记文件中.标记中没有表格。第一个foreach 循环的目的不是计数,而是能够分别调用每一行。我知道我可能可以使用echo $gharray[0]["title"] 回显,但与echo $img1_title 相比,它很难阅读
猜你喜欢
  • 2012-06-12
  • 1970-01-01
  • 1970-01-01
  • 2017-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-05
相关资源
最近更新 更多