【问题标题】:updated ubuntu from version 14 to 16. was mysql and now in pdo将 ubuntu 从版本 14 更新到 16。是 mysql,现在在 pdo
【发布时间】:2017-12-16 02:05:45
【问题描述】:

代码是在 mysql 中完成的,现在我转换为 PDO。至少我是这么认为的。我不是一个好的编码器,只是在学习。但是这段代码在 mysql 中工作,因为我切换到 PDO 它没有做它的工作。它旨在显示黄金以及黄金被扫描的时间。它适用于一款名为 kingsofchaos 的游戏。一些代码没有显示,但有一个获取信息的greasemonkey(javascript) 代码,而php 为显示和数据库数据完成其余的工作。这是此代码的链接。 http://www.kingsofchaos.com/battlefield.php?start=0 现在 GM 获得了所需的信息,据我所知,如果显示黄金,然后它会更新数据库,Havent 还没有测试它。原因通常是???是这个 php 应该显示黄金的时间以及多久前它被另一个用户扫描。好的,我希望我为此留下了足够的信息,但如果不是让我知道,我会尽力提供。

<?php
require_once("ban.php");
if ($login==0) { die(); }

$list = $_POST['list'];
$list = str_replace("[/d]", "", $list);
$list = explode("[d]", $list);
array_shift($list);

$servername = $config['sqlserver'];
$dbname = $config['sqldb'];
$db = new PDO("mysql:host=$servername;dbname=$dbname",  $config['sqluser'], $config['sqlpass']);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

for ($i=0; $i<count($list); $i++) {

$start = strpos($list[$i],"u=")+2;
$end = strpos($list[$i],"*");
$user = trim(substr($list[$i],$start,$end-$start));
/* $user = mysql_real_escape_string(trim(substr($list[$i],$start,$end-$start))); */

$start = strpos($list[$i],"g=")+2;
$end = strpos($list[$i],"*o=0*");
$gold = trim(substr($list[$i],$start,$end-$start));
//print_r($gold);
/* $gold = mysql_real_escape_string(trim(substr($list[$i],$start,$end-$start))); */

$start = strpos($list[$i],"t=")+2;
$end = strpos($list[$i],"--");
$size = trim(substr($list[$i],$start,$end-$start));
/* $size = mysql_real_escape_string(trim(substr($list[$i],$start,$end-$start))); */

$start = strpos($list[$i],"s=")+2;
$sid = trim(substr($list[$i],$start,-1));

try{
    $growth = $db->prepare("INSERT INTO `growth` (id, name, size, date) VALUES ('$sid', '$user', '$size', '".time()."')");
    $growth->execute();
//From this part to //end doesnt work yet, From information ive gotten from you all, i have got all the other parts working far as i can tell..
    if ($gold == "???") {
        $stats = $db->prepare("SELECT gold, goldage FROM `stats` WHERE id='$sid' AND name='$user' ");
        $stats->execute();
        $stats = $stats->fetch(PDO::FETCH_ASSOC);
        //$stats = mysql_fetch_array($stats);           
        $gold2 = number_format($stats['gold']);
        if (!$gold2) { $gold2 = "???"; }
        if (!$stats['goldage']) { $gold2 = "???"; $goldage = "never updated"; } else { $goldage = duration(time()-$stats['goldage'],1)." ago"; } echo $user.$goldage.";".$gold2." Gold*";
//This is supposed to loop through 20 names on each page and show gold values and how long ago for each. 
//end
    } else {
        $check = $db->prepare("SELECT COUNT(*) FROM `stats` WHERE id='$sid' AND name='$user' LIMIT 1");
        $check->execute();
        //$check->fetchAll();
        $check = $check->fetch(PDO::FETCH_ASSOC);
        //$check = mysql_fetch_array($check);
        //$check = $check->rowCount();
        //$check = $check['COUNT(*)'];
        if ($check<1) {
            $query = $db->prepare("INSERT INTO `stats` (id, name, size, gold, goldage) VALUES ('$sid', '$user', '$size', '$gold', '".time()."')");
            $query->execute();
        } else {
            $query = $db->prepare("UPDATE `stats` SET size='$size', gold='$gold', goldage='".time()."' WHERE id='$sid' AND name='$user'");
            $query->execute();
        }
    }
}
catch(PDOException $e) {
    echo "Error: " . $e->getMessage();
}
}

function duration($seconds,$max_periods)
{
$periods = array("year" => 31536000, "month" => 2419200, "week" => 604800, "day" => 86400, "hour" => 3600, "minute" => 60, "second" => 1);
$i = 1;
foreach ( $periods as $period => $period_seconds )
{
    $period_duration = floor($seconds / $period_seconds);
    $seconds = $seconds % $period_seconds;
    if ( $period_duration == 0 )
    {
        continue;
    }
    $duration[] = "{$period_duration} {$period}" . ($period_duration > 1 ? 's' : '');
    $i++;
    if ( $i >  $max_periods )
    {
        break;
    }
}
return implode(' ', $duration);
}
$db = null;

?>

【问题讨论】:

  • 您应该阅读有关 PDO 的 php 手册(或有关它的教程)以很好地理解什么是准备好的语句
  • 还可以了解 DATETIME 列类型。从几秒钟到你真正需要的看起来需要很多计算
  • $growth-&gt;execute(); */这一行是否缺少某些东西
  • 我确实有一些代码被注释掉了,但是当我把它全部粘贴到这里时,我只是忘了删除该注释行。但是从哪里 If ($gold == ???) 。我不确定我是否有任何选择零件或插入零件正确。是的,有点想通sql注入的可能性。因此,如果可以引导我朝着正确的方向解决此 php 页面上的所有问题。非常感谢它对所有帮助的人表示感谢。如果是 mysql,我可以轻松停止 sql 注入,但是由于 vps 上的更新,我必须使用 PDO,而且我对 PDO 及其工作原理不太熟悉。

标签: javascript php pdo


【解决方案1】:

我不确定问题是什么,但我对您的代码有意见:

 $growth = $db->prepare("INSERT INTO `growth` (id, name, size, date) VALUES ('$sid', '$user', '$size', '".time()."')");
    $growth->execute(); 

在这里利用 pdo 的可能性:

 $growth = $db->prepare("INSERT INTO `growth` 
                       (id, name, size, date) 
                       VALUES (:sid, :user, :size, '".time()."')");
    $growth->bindValue(':sid', $sid);
    $growth->bindValue(':user', $user);
    $growth->bindValue(':size', $size);

    $growth->execute(); 

这也适用于其他查询。 这样 pdo 将确保您的输入正确转义。所以像“a'o”这样的用户名不会破坏查询,也不会造成伤害

查询是否应该在循环中:您只能准备一次(在开始循环之前),然后绑定正确的值并在循环内执行

附录用于 cmets:

$check = $db->prepare("SELECT COUNT(*) counted
                       FROM `stats` 
                       WHERE id=:sid AND name=:usr 
                      -- limit 1 will give only 1!
                       LIMIT 1");
$check->bindValue(':sid', $sid);
$check->bindValue(':usr', $user);

        $check->execute();
        while($row = $check->fetch(PDO::FETCH_ASSOC)) {
           if ($row['counted']<1) {
               // do the binding thing here again
               $query = $db->prepare("INSERT INTO `stats` (id, name, size, gold, goldage) VALUES ('$sid', '$user', '$size', '$gold', '".time()."')");
               $query->execute();
           } else {
               $query = $db->prepare("UPDATE `stats` SET size='$size', gold='$gold', goldage='".time()."' WHERE id='$sid' AND name='$user'");
               $query->execute();
           }
       }

失败:

  • 您将查询限制为仅 1 行。移除限制 1 以获得更多
  • 你覆盖了 $check。我在上面使用 $row
  • 您不能将 $check 与

【讨论】:

  • 好的,我添加了您对 $growth 部分的建议。但这现在正在起作用,但这部分及以后的部分不起作用。 $stats = $db->prepare("SELECT gold, goldage FROM stats WHERE id='$sid' AND name='$user'"); $stats->执行(); $stats = $stats->fetch(PDO::FETCH_ASSOC);这部分代码是为每个页面上显示的每个用户返回大量数据。每页显示 20 个。它只返回顶部的第一个用户,而不返回下面的其他 19 个用户。对不起,如果我在这里收集了很多单词并希望您能阅读它。这是我第一次使用网站
  • 您只获取一次结果。所以你得到第一行。循环执行。我会补充回答
  • 好的 $check 部分现在可以工作了,我仍然没有让上面的代码工作,但 $stats 和 $gold 语句不工作,但会尝试你为我做的一些事情.再次感谢所有对此有帮助的人。
  • 秘诀很简单:从原始查询中将 $var 替换为 :somelabel 并确保也删除了 ' '。然后添加 bindValue() 行,提到 :somelabel 和变量
猜你喜欢
  • 2023-04-01
  • 2022-08-22
  • 2018-02-27
  • 2022-11-24
  • 2023-02-21
  • 2023-02-09
  • 2018-11-29
  • 2012-03-10
  • 2021-12-12
相关资源
最近更新 更多