htmlspecialchars 不接受 'variable variables' 作为参数

htmlspecialchars won't accept 'variable variables' as an argument

我读完了一本书:“PHP 和 MySQL ® Web 开发第 4 版”,作者是 Luke Welling 和 Laura Thomson。在第 49 页,作者建议使用其他深奥的(至少对我而言)方法来处理表格。也就是说,如果 html 形式中的名称具有相同的值,这些值只是数字加一而不同,我们可以在 echo 语句中使用 'variable variables' 类型的变量来动态地从形式中提取值...:

这是我的 html:

<form action="processorder.php" method="post">
  <table style="border: 0px;">
    <tr style="background: #cccccc;">
      <td style="width: 150px; text-align: center;">Item</td>
      <td style="width: 15px; text-align: center;">Quantity</td>
    </tr>
    <tr>
      <td>Tires</td>
      <td><input type="text" name="name1" size="3" maxlength="3" /></td>
    </tr>
    <tr>
      <td>Oil</td>
      <td><input type="text" name="name2" size="3" maxlength="3" /></td> 
    </tr>
    <tr>
      <td>Spark Plugs</td>
      <td><input type="text" name="name3" size="3" maxlength="3" /></td>
    </tr>
    <tr>
      <td colspan="2" style="text-align: center;"><input type="submit" value="Submit Order" /></td>
    </tr>
  </table>
  <tr>
    <td>How did you find Bob's?</td>
    <td>
      <select name="find">
        <option value = "a">I'm a regular customer</option>
        <option value = "b">TV adversting</option>
        <option value = "c">Phone directory</option>
        <option value = "d">Word of mouth</option>
      </select>
    </td>
  </tr>
</form>

这是我的 .php 文件:

<!DOCTYPE html>
<html>
  <head>
    <title>Bob's Auto Parts - Order Results</title>
  </head>
  <body>
    <h1>Bob's Auto Parts</h1>
    <h2>Order Results</h2>
    <?php
      //create short variable names
      
      $tireqty  = $_POST['name1'];
      $oilqty   = $_POST['name2'];
      $sparkqty = $_POST['name3'];
      
      for ($i=1; $i <= 3; $i++){
        $temp = "name$i";
        echo htmlspecialchars($$temp).'<br />'; // or whatever processing we want to do
      }
      
      echo "<p>Order processed at ";
      echo date('H:i, jS F Y');// (string as an argument)
      echo "</p>";
      
      // or: 
      // echo "<p>Order processed at " . date('H:i, jS F Y') . "</p>";
      // (avoiding multiple echo commands)
      
      
      echo "<p>Your order is as follows: </p>";
      echo htmlspecialchars($tireqty)." tires<br />";
      echo htmlspecialchars($oilqty)." bottles of oil<br />";
      echo htmlspecialchars($sparkqty)." spark plugs<br />";
      
      $totalqty = 0;
      $totalqty = $tireqty + $oilqty + $sparkqty;
      echo "<p>Items ordered " . $totalqty . "<br />";
      $totalamount = 0.00;
      
      define('TIREPRICE', 100);
      define('OILPRICE', 10);
      define('SPARKPRICE', 4);
      $totalamount = $tireqty * TIREPRICE + $oilqty * OILPRICE + $sparkqty * SPARKPRICE;
      echo "Subtotal: $:" . number_format($totalamount, 2) . "<br />";
      
      $taxrate = 0.10;
      $totalamount = $totalamount * (1 + $taxrate);
      echo "Total including taxes is: $" . number_format($totalamount, 2) . "</p>";
      
      // echo 'isset($tireqty): '.isset($tireqty).'<br />';
      // echo 'isset($nothere): '.isset($nothere).'<br />';
      // echo 'empty($tireqty): '.empty($tireqty).'<br />';
      // echo 'empty($nothere): '.empty($nothere).'<br />';
      
      
      
      
    ?>
    
  </body>
</html>

这是我的问题所在:

  for ($i=1; $i <= 3; $i++){
    $temp = "name$i";
    echo htmlspecialchars($$temp).'<br />'; 
  }

脚本不会做出反应,也不会接受其他类型的简单变量参数。即使是编辑器 (np++) 也不接受第二个“$”符号。

该示例中的问题是 htmlspecialchars() 函数。因为参数 $$tempundefined 并且 $temp 变量只是一个名为 name 的字符串与整数值(如 1,2,3)连接。但真正的价值在全局 $_POST[$temp] 变量中。要获取 $_POST[$temp] 中的值,您需要使用正确的 post 参数名称,在您的示例中,它被命名为 name1name2name3

  // There are many other ways but Let me do this way.
  // Incoming Post Values that are named name1,name2 and name3

  $tireqty  = $_POST['name1'];
  $oilqty   = $_POST['name2'];
  $sparkqty = $_POST['name3'];

  for ($i=1; $i <= 3; $i++) {
      $temp = "name$i";
      $temp = !isset($_POST[$temp]) ? "" : $_POST[$temp];
      echo htmlspecialchars($temp).'<br />'; 
  }
  
  // if you want to stick with variable variable technique.

  $name1 = $_POST['name1'];
  $name2 = $_POST['name2'];
  $name3 = $_POST['name3'];

  for ($i=1; $i <= 3; $i++) {
      $temp = "name$i";
      echo htmlspecialchars($$temp).'<br />'; 
  }

这个其实和htmlspecialchars()功能没有关系。当你在循环中写这个时:

$temp = "name$i"

您正在创建一个值为 name1 的字符串。当您尝试将它与 'variable variable' 一起使用时,如下所示:

$$temp

代码正在查找名为 $name1 的变量,该变量不存在。

要修复原始代码,您真正需要做的就是从 $_POST 数组中生成您要使用的键名:

for ($i = 1; $i <= 3; $i++) {
    echo htmlspecialchars($_POST["name$i"]) . '<br />';
}

但是,无论如何,这是一个有点不雅的解决方案。


更好的解决方案

您可以从更改输入名称开始,这样它们都会作为自己的数字索引数组进入 $_POST 数组。

<tr>
    <td>Tyres</td>
    <td><input type="text" name="name[]" size="3" maxlength="3" /></td>
</tr>
<tr>
    <td>Oil</td>
    <td><input type="text" name="name[]" size="3" maxlength="3" /></td> 
</tr>
<tr>
    <td>Spark Plugs</td>
    <td><input type="text" name="name[]" size="3" maxlength="3" /></td>
</tr>

然后您可以遍历 $_POST['name'] 并轻松回显这些值:

foreach ($_POST['name'] as $val) {
    echo htmlspecialchars($val) . '<br>';
}

这些都是理想的解决方案吗?不,不是真的。您知道您需要一个用于轮胎、机油和火花塞的表单字段,因此尝试调用所有输入都称为 name 的模式首先是没有意义的。当表单字段都属于一个实体时,或者如果您不知道提交表单时会有多少行,您通常会这样做。

什么是 $_POST['name2']$_POST['name'][1]?谁知道。您必须通读代码并找到表单以仔细检查属于哪个字段。

代码应该是语义化的,任何阅读它的人(包括你自己,当你将来回顾自己的代码时)都应该易于理解。

我会正确重命名表单输入:

<tr>
    <td>Tyres</td>
    <td><input type="text" name="tyres" size="3" maxlength="3" /></td>
</tr>
<tr>
    <td>Oil</td>
    <td><input type="text" name="oil" size="3" maxlength="3" /></td> 
</tr>
<tr>
    <td>Spark Plugs</td>
    <td><input type="text" name="spark_plugs" size="3" maxlength="3" /></td>
</tr>

然后一切都变得更加简单易懂。在您的代码中,您可以使用三个值。你知道它们是什么,它们的名字是什么意思。

echo htmlspecialchars($_POST['tyres']) . '<br>';
echo htmlspecialchars($_POST['oil']) . '<br>';
echo htmlspecialchars($_POST['spark_plugs']) . '<br>';

如果您随后想使用奇特的循环和其他东西,我可以深入研究很多东西,但通常不希望将所有内容过度复杂化。你最终会产生更多的错误,使你的代码更难被每个人理解,并使调试你的代码的过程更耗时。