【问题标题】:Query is inputting the actual time instead查询正在输入实际时间
【发布时间】:2020-07-18 13:35:35
【问题描述】:

我想创建一个表单来禁止我的服务器中的玩家,这就是我的表单和查询的样子。

<!-- BAN FORM -->
<?php 
if(isset($_POST['ban'])){

    $time=time().'000';
    $durat=$_POST['duration']*86400000;
    $duration=$time+$durat;

    $banuid = "UPDATE userprofile SET bantime=:duration WHERE uid = '$_GET[uid]'";
    $query = $dbh1 -> prepare($banuid);
    $query-> bindParam(':duration',$duration, PDO::PARAM_STR);
    $query -> execute();

}
?>
<form method="POST">
<div class="col-md-12">

<label for="inputUsername" class="sr-only">Duration</label>
<div class="input-group mb-3">
    <div class="input-group-prepend">
        <span class="input-group-text" id="icon-inputUsername"><i class="flaticon-clock-2"></i> </span>
    </div>
    <input type="text" name="duration" size="18" placeholder="Type how many days">
</div>

<button name="ban" class="btn btn-lg btn-gradient-warning btn-block btn-rounded mb-4 mt-5" type="submit">BAN</button>

</div>
</form>

问题是当我输入时间(应该是天)时,它会在数据库中添加实际时间。

谁能给我一个提示?

谢谢

【问题讨论】:

  • 您在使用未经 url 参数处理的 uid 时有明显的 sql 注入
  • 要不要改成uid=:uid并绑定参数?
  • 是的,bindParam(...) uid

标签: php mysql time


【解决方案1】:

我可以看到您的 PHP 代码中存在一些问题。

$time=time().'000';  
// → '1595089303000' (string)
$durat=$_POST['duration']*86400000; 
// → $_POST['duration'] is a string, e.g. '3'
// → $durat is implicitly casted to integer, e.g. 259200000 (int)
$duration=$time+$durat;
// → string + number also does an implicit cast to integer, e.g.
// → $duration = '1595089303000' + 259200000 = 1595348503000 (int)


$banuid = "UPDATE userprofile SET bantime=:duration WHERE uid = '$_GET[uid]'";
$query = $dbh1 -> prepare($banuid);
$query-> bindParam(':duration',$duration, PDO::PARAM_STR);
// → I think this is the problem          ^^^^^^^^^^^^^^

// → SQL will look like that:
// UPDATE userprofile SET bantime='1595348503000' WHERE uid = '100'
//                                ^-------------^
// You see that the bantime is a string that holds a long number. 
// This should be either a number (without quotes) or a formatted datetime string.

$query -> execute();

您的 SQL 表中的“bantime”字段是什么数据类型?日期时间,整数,...?很可能它不是 varchar 并且无法转换 $duration 值。作为后备 MySQL 将使用默认值,可能是CURRENT_TIEMSTAMP(这意味着您有一个日期时间字段)

以下是更简洁代码的建议:

// 1. Sanitize all POST/GET values. I assume $uid is a numeric user ID:
$uid = (int) $_GET['uid'];

// 2. Keep the date calculation to numeric values:
$days = (int) $_POST['duration'] * 86400;
$ban_until = time() + $days;

// 3. After the calculation convert the numeric timestamp to the desired SQL format:
//    I assume your bantime field is a DATETIME field, i.e. '2020-07-18 18:45:00'
$mysql_date = date( 'Y-m-d H:i:s', $ban_until );

// 4. When preparing your SQL, always bind _ALL_ user-inputs!
$banuid = "UPDATE userprofile SET bantime=:duration WHERE uid=:uid";
$query = $dbh1->prepare( $banuid );
$query->bindParam(':duration', $mysql_date, PDO::PARAM_STR); 
$query->bindParam(':uid', $uid, PDO::PARAM_INT);
$query->execute();

// The resulting SQL would be:
// UPDATE userprofile SET bantime='2020-07-18 18:45:00' WHERE uid=100

【讨论】:

    猜你喜欢
    • 2012-07-01
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-03
    相关资源
    最近更新 更多