dongzhan5246 2015-11-04 21:34
浏览 24
已采纳

无法通过#,“,&$ $ _GET

I am providing a very simple test dataset and my code to try to resolve this issue. If the question has been asked before I have not been able to find it. I'm self-taught from books and the web so this is not slick programming. I hope I am providing enough information.

The dataset consists of one table ‘comments’ with fields id (autoincrement), name (text), comments (textarea), date, display (enum) The mysql connection collation and all text and text area fields are set to utf8_general_ci

The <head> includes 
<meta http-equiv="Content-Type" content="text/html" charset="UTF-8" /> 

All post and get statements are escaped as follows

$fieldname =  mysqli_real_escape_string($dbc, $_POST['fieldname']);

My code successfully enters the problem characters into the database and they are retrieved successfully if I just want to display them, however in the real world I need to vet user entries to ensure they are suitable for public viewing and I also need to be able to edit them. When I open my comments-edit page, anything after an & in a field disappears and if there is a # or " in any field nothing is retrieved at all.

First the comments-admin.php page:

   <?php
    $dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME)
    or die('Error connecting to MySQL server.');
    ?>
        <table width="100%"><tr><td>
        <b>ID:</b></td><td>
        <b>Name:</b></td><td align="left">
        <b>Comments:</b></td><td>
        <b>Date Posted:</b></td><td>
        <b>Display:</b></td></tr><tr><td>
    <?php
        $query = "SELECT * FROM comments ORDER BY date DESC";
        $result = mysqli_query($dbc,$query);
        while ($row=mysqli_fetch_array($result)){
        echo '<tr valign="top" ><td>';
        echo  $row['id'] . '</td><td>';
        echo  $row['name'] . '</td><td>'; 
        echo  $row['comments'] . '</td><td>'; 
        echo  $row['date'] . '</td><td>'; 
        echo  $row['display'] . '</td><td>'; 
        echo  '<td><a href="comments-edit.php?id=' . $row['id'] . 
              '&amp;name=' . $row['name'] . 
              '&amp;comments=' . $row['comments'] . 
              '&amp;date=' . $row['date'] . 
              '&amp;display=' . $row['display'] . 
              '">Edit</a></td></tr>';
          }
          ?>
          </table>

This results in a table which looks like this (without the decoration).

ID: Name:     Comments:                    Date Posted:  Display:
12  Fred    Just wanted to say "Thank You"  2015-11-04    No        Edit
11  Ricky   I live at #2, Anywhere Street.  2015-11-04    No        Edit
9   Ethel   Why can't I make this work!     2015-10-24   Yes        Edit
4   Lucy    Went to A&W today               2015-04-23   Yes        Edit

"Edit opens my comments-edit.php form. In this example the only one which will open correctly is #9. #'s 11 & 12 will not retrieve anything at all, and #4 will not have anything after the &.

The code for comments-edit follows:

<?php
$dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME)
  or die('Error connecting to MySQL server.');

 if (isset($_GET['id']) &&
   isset($_GET['name']) && 
   isset($_GET['comments']) && 
   isset($_GET['date'])) 
{

// Grab the data from the GET
    $id = ( $_GET['id']);
    $name =  mysqli_real_escape_string($dbc, $_GET['name']);
    $comments =  mysqli_real_escape_string($dbc, $_GET['comments']);
    $date =  ( $_GET['date']);
}
else if (isset($_POST['id']) && 
    isset($_POST['name']) && 
    isset($_POST['comments']) && 
    isset($_POST['date']) && 
    isset($_POST['display']))  
{
// Grab the data from the POST
    $id =  ( $_POST['id']);
    $name =  mysqli_real_escape_string($dbc, $_POST['name']);
    $comments =  mysqli_real_escape_string($dbc, $_POST['comments']);
    $date =  ( $_POST['date']);
    $display =  ( $_POST['display']);
    }

   <form class="gap" method="post" action="comments-update.php">
  <input type="hidden" name="ud_id" value="<?php echo "$id;" ?>" />
<p class="gap"><b>Select "Yes" before clicking "Edit Data" to confirm any changes</b></p>
<input type="radio" name="confirm" value="Yes" /> Yes 
<input type="radio" name="confirm" value="No" checked="checked" /> No 
<input type="submit" value="Edit Data" name="update" /><br />   

<label class="appsm">Comment Date:</label>
<input type="text" size="30" name="ud_date" value="<?php echo $date; ?>" 

<label class="appsm">ID:</label>
<input type="text" size="5" name="ud_id" value="<?php echo $id; ?>" />

<label class="appsm">Display:</label>
      <select id="ud_display" name="ud_display">
        <option value="yes" <?php if (!empty($display) && $display == 'yes') echo 'selected = "selected"'; ?>>Yes</option>
        <option value="no" <?php if (!empty($display) && $display == 'no') echo 'selected = "selected"'; ?>>No</option>
      </select><br />

<label class="appsm">Name:</label>
<input type="text" size="50" name="ud_name" value="<?php echo $name; ?>" />
<br />
<label class="appsm">comments:</label>
<textarea name="ud_comments" wrap="physical" class="left" cols="105" rows="2">
<?php echo stripslashes($comments); ?></textarea>

</form>

I'm sure I've missed something very simple and I've searched my books and the web but I have not found an answer to this specific issue. I would really like to be able to remove all the warnings not to use these characters from my real websites, especially since users rarely read the instructions.

  • 写回答

1条回答 默认 最新

  • dtbam62840 2015-11-04 22:27
    关注

    As mentioned in the comments above, you need to encode things that are passed in the URL.

    But my question is, why are you passing all that info to the second page when you can get it out of the database? Also changed your code to use a heredoc block instead of all those echo() statements. It's a handy way to make your code more readable. Finally, outputting data to HTML requires you to escape it with htmlspecialchars(). I used array_map() to quickly escape the entire database record.

    <?php
    $dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME) or die('Error connecting to MySQL server.');
    ?>
        <table width="100%"><tr><td>
        <b>ID:</b></td><td>
        <b>Name:</b></td><td align="left">
        <b>Comments:</b></td><td>
        <b>Date Posted:</b></td><td>
        <b>Display:</b></td></tr><tr><td>
    <?php
        $query = "SELECT * FROM comments ORDER BY date DESC";
        $result = mysqli_query($dbc,$query);
        while ($row=mysqli_fetch_array($result)){
            $row = array_map('htmlspecialchars', $row);
            echo <<< HTML
    <tr valign="top">
        <td>$row[id]</td>
        <td>$row[name]</td>
        <td>$row[comments]</td>
        <td>$row[date]</td>
        <td>$row[display]</td> 
        <td><a href="comments-edit.php?id=$row[id]">Edit</a></td>
    </tr>
    
    HTML;
          }
          ?>
          </table>
    

    Your second file. Note that $_POST and $_GET are both combined into the superglobal $_REQUEST, though you should really know how your own page is going to be sending data. Again HTML output is escaped.

    <?php
    $dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME) or die('Error connecting to MySQL server.');
    
    if (isset($_REQUEST['id'])) {
        $id = (int)$_REQUEST['id'];
        $query = "SELECT * FROM comments WHERE id=$id";
        $result = mysqli_query($dbc,$query);
        $row=mysqli_fetch_array($result);
    }
    if (!isset($_REQUEST['id']) || !$row) {
        // you should do something in this case
        return false;
    }
    $id = htmlspecialchars($row['id']);
    $name = htmlspecialchars($row['name']);
    $comments = htmlspecialchars($row['comments']);
    $date = htmlspecialchars($row['date']);
    $display = htmlspecialchars($row['display']);
    ?>
    
    <form class="gap" method="post" action="comments-update.php">
    <input type="hidden" name="ud_id" value="<?php echo $id ?>" />
    ...
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题
  • ¥15 matlab中使用gurobi时报错
  • ¥15 这个主板怎么能扩出一两个sata口
  • ¥15 不是,这到底错哪儿了😭
  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么