PHP + MySQL脚本无法正常工作

时间:2014-07-17 17:17:52

标签: php mysql sql

我制作了这个脚本给我带来了很多麻烦。我不太擅长MySQL,也许我正在尝试为我的SQL知识做过于先进的事情,但我真的非常希望能够做到这一点。

我的PHP脚本是:

<?PHP
$getusername=$_GET['user'];
$getpassword=$_GET['pass'];
$getworldname=$_GET['worldname'];
$getblock=$_GET['block'];
$getpos=$_GET['pos'];
$user_name = "asdasdasd";
$password = "asdasd";
$database = "asdasd";
$server = "localhost";

$db_handle = mysql_connect($server, $user_name, $password);
$db_found = mysql_select_db($database, $db_handle);


$SQL="SELECT * FROM accounts WHERE username='$getusername' and password='$getpassword'";
$result=mysql_query($SQL);


$count=mysql_num_rows($result);


if($count==1){
    $blockstring=$getpos.'/'.$getblock.'|';
    $SQL="SELECT LOCATE('$getpos', blocks) FROM worlds WHERE name='$getworldname'";
    $result=mysql_query($SQL);
    $count=mysql_num_rows($result);
    echo $count;
    //if there's already that block
    if ($result!=0){
        $posUnknown='|'.$getpos.'/';
        $posKnown='|'.$getpos.'/'.$getblock;
        $SQL="UPDATE worlds SET blocks=replace(blocks,concat('$posUnknown',substring_index(substring_index(blocks, '$posUnknown', 2), '|', 1),'|'),'$posKnown') WHERE name='$getworldname'";
        $result=mysql_query($SQL);
    }else{
        $SQL="UPDATE worlds SET blocks=CONCAT(blocks,'$blockstring') WHERE name='$getworldname'";
        $result=mysql_query($SQL);
    }
    print 'OK';
}else{
    print 'NO';
}
?>

我确定我犯了一些错误,也是查询中的大错,但遗憾的是我无法弄清楚我做错了什么。

块的内容示例可以是:

  

x10y20z30 / 0 | x999y1231z30 / 1 | x3330y4444z0 / 99999 |等

这个脚本的功能,以及我希望它做的是:

  • 检查用户名和密码,这很有效,
  • 检查&#34; blocks&#34;
  • 中是否已存在给定的块
  • 如果确实存在,则替换该值(/之后的那个) 已存在的新块
  • 如果它不存在,只需将其添加到&#34;块&#34;。

但它没有用,我知道为什么。我知道这是因为SQL,但我无法弄清楚如何使它工作。

1 个答案:

答案 0 :(得分:1)

正如评论中所指出的,您的代码安全性存在严重问题。我已经做了我能做的事情,而没有真正改变你的代码在做什么:

<?PHP
    $getusername=$_GET['user'];
    $getpassword=$_GET['pass'];
    $getworldname=$_GET['worldname'];
    $getblock=$_GET['block'];
    $getpos=$_GET['pos'];
    $user_name = "asdasdasd";
    $password = "asdasd";
    $database = "asdasd";
    $server = "localhost";

你应该使用mysqli,而不是mysql:

    $db = new mysqli($server, $user_name, $password, $database);

在使用real_escape_string:

的查询中使用之前,所有输入都需要进行转义
    $SQL="SELECT * FROM accounts WHERE username='" . $db->real_escape_string($getusername) . "' and password='" . $db->real_escape_string($getpassword) . "'";
    $result=$db->query($SQL);

    $count=$result->num_rows;

    if($count==1) {
        $blockstring=$getpos.'/'.$getblock.'|';
        $SQL="SELECT LOCATE('" . $db->real_escape_string($getpos) . "', blocks) FROM worlds WHERE name='" . $db->real_escape_string($getworldname) . "'";
        $result=$db->query($SQL);

        $count=$result->num_rows;
        echo $count;

        //if there's already that block
        if ($count!=0) {
            $posUnknown='|'.$getpos.'/';
            $posKnown='|'.$getpos.'/'.$getblock;

这可能是您遇到麻烦的地方,因为看起来您将所有这些信息存储在一行中:

            $SQL="UPDATE worlds SET blocks=replace(blocks,concat('" . $db->real_escape_string($posUnknown) ."',substring_index(substring_index(blocks, '" . $db->real_escape_string($posUnknown). "', 2), '|', 1),'|'),'" . $db->real_escape_string($posKnown) . "') WHERE name='" . $db->real_escape_string($getworldname). "'";
            $result=$db->query($SQL);
        } else {
            $SQL="UPDATE worlds SET blocks=CONCAT(blocks,'" . $db->real_escape_string($blockstring) ."') WHERE name='" . $db->real_escape_string($getworldname) . "'";
            $result=$db->query($SQL);
        }
        print 'OK';
    } else {
        print 'NO';
    }
?>

由于您的所有块信息都在一个列中被推到一起,因此您的数据库根本没有标准化,看起来像这样:

Worlds
name    blocks

你的数据库的结构应该更像这样:

Worlds
id | name
---------------
 1 | demoworld

Blocks
id | WorldID | x     | y    | z  | data
-----------------------------------------
 1 |       1 |    10 |   20 | 30 |     0
 2 |       1 |   999 | 1231 | 30 |     1
 3 |       1 | 33330 | 4444 |  0 | 99999

您可以重新创建查询数据时提供的数据布局,当有人尝试添加x20y30z40 / 12345之类的内容时,您可以解析它以获取x,y,z和数据部分。

相关问题