【问题标题】:PHP How to select an array by name depending on other array value and assign contents to variables?PHP如何根据其他数组值按名称选择数组并将内容分配给变量?
【发布时间】:2020-04-21 18:08:18
【问题描述】:

免责声明:我对 PHP 很陌生,所以请耐心等待。我花了一整天的时间试图弄清楚这一点,但我觉得我不知道正确的方法或尝试错误的方法。


我想要达到的目标

我让用户从表单中的多选输入字段中选择最多三个项。我想将有关这些项目的所有信息打印到 pdf 中,这些信息保存在单独的数组中。输入字段包含大约 10 个不同的选项(比如说 A1 到 A10),我在提交表单后将它们提取到一个数组中:

$itemList = [
  [0] => A1,
  [1] => A2,   // optional
  [2] => A3    // optional
]

现在我为每个项目创建了一个单独的数组,其中包含附加信息(稍后可能来自数据库):

$infoA1 = [
  "info1" = "lorem",
  "info2" = "ipsum",
  "info3" = "dolor"
]

$infoA2 = [
  "info1" = "sit",
  "info2" = "amet",
  "info3" = "tatem"
]

$infoA3 ...

所有信息值都应分配给变量以放置在 pdf 中,因此我必须检查总共选择了多少项目,并且对于每个选定的项目,我需要调用如下函数:

function items1() {
  $pdf->SetXY(188.5,24);                 // *Note

  $pdf->Cell(17,4.7, $info1 ,0,2,'');    // $infoA1[0] = $info1
  $pdf->Cell(17,4.7, $info2 ,0,2,'');    // $infoA1[1] = $info1
  $pdf->Cell(17,4.7, $info3 ,0,2,'');    // $infoA1[2] = $info1
}

*注意:我不能对所有项目都使用一个函数,因为每个选定项目的信息变量必须转到 pdf 上不同的 X 和 Y 位置。

...

这是我的主要问题:

如何检查提交的 $itemList 数组中的哪些项目并获取具有相同名称的 $info array 以将相应的 info values 分配给填充 pdf 的占位符变量?

我的想法是我可以以某种方式比较名称,例如获取 info array,其中名称包含与提交的项目相同的值(例如“$infoA1”中的“A1”)。不过,到目前为止还没有运气。

再次,我怀疑我在这里使用了错误的方法,因此非常感谢任何见解。此外,据我所知,这里的人们喜欢只回答所提供的确切问题:如果这当然适合这种情况,我愿意重组我目前的方法。

【问题讨论】:

    标签: php arrays iteration


    【解决方案1】:

    您可以使用可变变量。 https://www.php.net/manual/en/language.variables.variable.php

    extract(${'info'.$itemList[0]});
    var_dump($info1);
    

    这样做是将字符串与变量连接起来以创建变量变量,然后提取将您的数组键转换为变量,以便您可以使用它们。

    【讨论】:

      【解决方案2】:

      你写道:

      注意:我不能对所有项目都使用一个函数,因为每个选定项目的信息变量必须转到 pdf 上不同的 X 和 Y 位置

      您实际上可以(并且可能应该)有一个这样的函数,它接受三个参数:一个数据数组、一个 x 坐标和一个 y 坐标。我选择将它们作为单个数组传递,但您可以更改它。

      function items($a) {
          $data = $a[0];
          $x = $a[1];
          $y = $a[2];
      
          $pdf->SetXY($x, $y);
      
          foreach ( $data as $v ) {
              $pdf->Cell(17,4.7, $v ,0,2,'');
          }
      }
      

      (在您的代码中,您似乎将所有内容都放在了同一位置:$pdf->Cell(17,4.7, $info1 ,0,2,'')。我一直这样,但这似乎是错误的。)

      那么您需要一种将$itemList 中的内容映射到$infoA1 变量的方法:

      $map = [
          'A1' => [ $infoA1, 188.5, 24 ]
          'A2' => [ $infoA2, 355, 30 ], // Just making it up
          'A3' => [ $infoA3, 500, 50 ], // Just making it up
      ];
      

      最后,遍历$itemList,在$map中查找对应的信息,并将其传递给items()函数:

      foreach ( $itemList as $v ) {
          if ( $map[ $v ] ) {
              items( $map[ $v ] );
          }
      }
      

      这可以通过多种方式进行简化和/或重写,但这完全取决于对您有意义的内容以及数据的结构。

      【讨论】:

      • 谢谢! Cell() 属性是高度和宽度,这就是为什么您可能认为它们在同一个位置,但它们彼此下方对齐,第一个从 X 和 Y 开始,所以这很好(使用 TCPDF)。
      • 太棒了!如果这充分回答了您的问题,请考虑marking it the accepted answer 和/或投票。谢谢!
      • 谢谢!最终解决方案是您和@Mik 的组合(请参阅我自己的答案)。请让我知道如何给你两个适当的荣誉,因为没有你的帮助,这将不复存在。
      • @VibeDesign This page 解释了如何决定将哪个答案标记为已接受。 (最终由您决定。)无论哪种情况,我们都鼓励您发送电子邮件至 upvote any answers and comments,这对您有帮助。
      【解决方案3】:

      *注意:我不能对所有项目都使用一个函数,因为每个选定项目的信息变量必须转到不同的 X 和 Y 位置 pdf。

      我猜,你可以将 X 和 Y 作为参数传递

      我建议将您的变量转换为多维数组:

      $itemList = [
        [0] => 'A1',
        [1] => 'A2',   // optional
        [2] => 'A3',    // optional
      ];
      
      $info = [
      'A1' => [
        'x' => 188.5, 
        'y' => 24,
        "info1" => "lorem",
        "info2" => "ipsum",
        "info3" => "dolor",
      ],
      
      'A2' = [
        'x' => 188.6, 
        'y' => 25,
        "info1" => "sit",
        "info2" => "amet",
        "info3" => "tatem",
      ],
      
      'A3' ...
      ];
      

      所以我们可以重写函数:

      function items($pdf, $info) {
        $pdf->SetXY($info['x'], $info['y']);
      
        $pdf->Cell(17,4.7, $info['info1'] ,0,2,'');
        $pdf->Cell(17,4.7, $info['info2'] ,0,2,'');
        $pdf->Cell(17,4.7, $info['info3'] ,0,2,'');
      }
      

      像下面这样使用它:

      foreach ($itemList as $item) {
        items($pdf, $info[$item]);
      }
      

      所以您无需检查$itemList

      【讨论】:

      • 谢谢!传递 X 和 Y 值是完全正确的,但我也可能需要调整每个 Cell() 具有单独高度和宽度的项目,这就是为什么我认为我仍然需要单独的功能。我还从表单中得到$itemlist 作为关联数组。我将如何制作这个多维并添加 X 和 Y 值?
      • 第二个想法:我可能只使用一个函数就可以了,但是$itemList 不能包含 X 和 Y,因为它们应该绑定到 1.、2.和 3. 的迭代函数,无论传递了哪个选定项(请记住,可供选择的项超过 3 个)。所以我必须在之后将 X 和 Y 分配给 $itemList 数组,但是如何?
      • 我试图通过采用硬编码数组$itemList 来实现您的解决方案,但它总是在函数中失败。这里可能存在某种范围问题吗?
      • 没错,它失败了,因为我忘记将$pdf 传递给函数。更新了...
      • 另外,我修改了整个代码。现在您可以直接从多选中获得$itemList,因此函数变得更短了:) 关于另一个变量:我认为您可以将它们全部存储在$info 的子数组中。
      【解决方案4】:

      多亏了@Mik 和@kmoser 的解决方案,我终于弄明白了,非常感谢你们两个!

      // multilevel $info array holding data
      
      $info = [
        'A1' => [
          "info1" => "lorem",
          "info2" => "ipsum",
          "info3" => "dolor",
        ],
        'A2' => [
          "info1" => "sit",
          "info2" => "amet",
          "info3" => "tatem",
        ],
        'A3' => [
          ...
      ];
      
      
      // array of selected items submitted by form
      
      $itemList = ["A1", "A2", "A3"];    // could also be ["A4", "A8", "A7"]
      
      
      // map items to $info and coordinates
      
      $map = [
        $itemList[0] => [ $info[$itemList[0]], 188.5, 24 ],
        $itemList[1] => [ $info[$itemList[1]], 188.5, 95.2 ],
        $itemList[2] => [ $info[$itemList[2]], 188.5, 167.7 ]
      ];
      
      
      // call function for each submitted item
      // also includes $pdf for use in function
      
      foreach ($itemList as $item) {
        items($map[$item], $pdf);
      }
      
      
      // function gets mapped array and places data to X any Y coords
      
      function items($item, $pdf) {
        $data = $item[0];
        $x = $item[1];
        $y = $item[2];
      
        $pdf->SetXY($x, $y);
      
        foreach ($data as $v) {
            $pdf->Cell(17,4.7, $v ,0,2,'');
        }
      }
      
      
      // this places the desired data to the pdf
      // "lorem, ipsum, dolor" to (188.5/24), "sit, amet, tatem" to (188.5/95.2), and so on...
      

      现在,这是完整的解决方案,但我不想为此付出代价,因为如果没有您的回答,这将不复存在。那么,在这里做什么才是公平的呢?

      另外,如果这里有什么需要改进的地方,请告诉我。

      【讨论】:

        猜你喜欢
        • 2021-11-02
        • 1970-01-01
        • 1970-01-01
        • 2019-10-24
        • 1970-01-01
        • 1970-01-01
        • 2023-03-04
        • 2017-05-15
        • 2021-05-23
        相关资源
        最近更新 更多